px普贤教程PuXian
普贤教程 › 进阶教程

包管理与 registry

pxpkg 是 PuXian 的包管理器。它管两件事:把 registry 里的包拉进项目,以及把依赖锁成可复现的版本。

四条命令走完

sh
pxpkg init --name myapp     # 生成 px.toml
pxpkg add mysql@0.2.0       # 加依赖
pxpkg install               # 落地到 .px_modules/
pxpkg list                  # 看装了哪些
命令作用
pxpkg init初始化项目,写 px.toml
pxpkg add spec添加依赖:名字@^1.2.0、本地路径、或 http(s) URL
pxpkg install安装依赖并写 px.pkg.lock;--locked 只校验不改写
pxpkg list列出依赖与安装状态
pxpkg remove移除依赖
pxpkg sync从远程同步整个 registry 到本地缓存

目录结构与解析顺序

名字形态从哪里找
import std.stringsstdlib/(PX_STDLIB 可覆盖)
import "lib/x.px"相对当前文件的路径
import mysql项目 .px_modules/ → PX_REGISTRY 指向的目录

registry 的目录约定是 <名称>/<版本>/<名称>.px,例如:

text
registry/mysql/0.2.0/mysql.px
registry/mysql/0.2.0/proto.px
registry/mysql/0.2.0/stmt.px

一个完整例子

sh
mkdir -p ~/pxapp && cd ~/pxapp
pxpkg init --name reporter
pxpkg add mysql@0.2.0
pxpkg install
pxpkg list
px
# main.px
import mysql

def main():
    var c = mysql_connect("127.0.0.1", 3306, "app", "***", "appdb")
    if c.is_err():
        print("连接失败:" + c.err())
        return
    var conn = c.ok()
    var q = mysql_query(conn, "SELECT 1 AS n")
    if q.is_err():
        print("查询失败:" + q.err())
    else:
        print(str(q.ok()["rows"][0][0]))
    mysql_close(conn)

依赖写进哪里

px.toml 记声明,px.pkg.lock 记精确版本。两个文件都要进版本库——只提交 toml 会让不同机器装出不同版本,出问题时无法复现。

sh
pxpkg install --locked    # CI 里用这个:lock 不匹配就失败

离线与内网

registry 是目录结构,不是必须联网。把整份 registry 拷到内网机器:

sh
export PX_REGISTRY=/opt/puxian-registry
pxpkg install

或者用 pxpkg sync --registry <目录> 从发布源同步一份。

写自己的包

一个包就是一个目录,里面放 .px 文件,导入方按裸名引用。包内相对导入要用同目录文件名(如 import "proto.px"),因为安装后包内文件会一起被复制到 .px_modules/。

包目录必须自包含不要跨目录 import 上级目录的库。部署到 Ma 的 px_routes 时,编译沙箱只打包「脚本所在目录」,跨目录的目标不在里面,编译会跳过、运行期报未定义变量。这条在 0.22.4 之后会在编译期直接拦住并说明原因。

依赖排错

现象原因
「找不到模块 'mysql'」没 pxpkg install,或 PX_REGISTRY 没指对
装了但版本不对px.toml 用了范围依赖而 lock 没提交
包内引用报未定义包里有跨目录 import,装到 .px_modules 后路径失效