普贤教程 › 进阶教程
包管理与 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.strings | stdlib/(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 后路径失效 |