最近研究了一下 John Coene 的 packer 包,发现 htmlwidgets 在 js 侧的开发自由度很大,只要最终能生成一个打包文件就行。packer 的工具链是 javascript + npm/yarn 管理 + webpack 打包, 我尝试按照它的思路换成了 typescript + pnpm 管理 + esbuild 打包,实验了一个 htmlwidgets 包 xkcd。
总结下来,几个工具使用的感想如下
typescript: 比较 javascript 确实能提早发现代码的不少逻辑错误,编辑器的推断功能也更完善。但因为我要包装的 js 库 chart.xkjs 本身不是用 typescript 写的,也没有提供类型声明,导致要额外花不少功夫自己写各种类型。如果换成另一个自带类型的包,typescript 的开发体验应该能提升很多。不过 htmlwidgets 里会涉及大量 R 和 javascript 的数据结构转换,有时候写类型也能起到文档的作用,这点见仁见智
pnpm:pnpm 的包管理功能和 npm 或 yarn 没有本质区别,但可以节省很多磁盘空间。它会像 renv 一样在用户目录下创建一个中央的存储库,而每个项目下的 node_modules 都是指向中央库的 symlink。此外体感安装速度也快了很多,推荐使用
esbuild: 根据 官网 打包速度比 wepack 快了百倍,在我的小项目下 webpack 每次打包大概 1 ~ 2秒左右,而 esbuild 基本上是秒刷新。同时 esbuild 比 webpack 的配置简单不少,特别是没有各种奇怪的参数命名, 原生支持 typescript 也不用定义各种 loader。我的核心配置只有以下几行
esbuild
{
entryPoints: [path.join(__dirname, "srcts/index.ts")],
bundle: true,
outfile: path.join(__dirname, "inst/htmlwidgets/xkcd.js"),
platform: "node",
format: "cjs",
external: ["Shiny", "HTMLWidgets"],
watch:true
}
此外 esbuild 的打包体积更小一些 非常推荐