Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

开发 NPM 包时可能不需要将代码打包进一个文件里 #123

Open
lmk123 opened this issue Dec 10, 2022 · 0 comments
Open

开发 NPM 包时可能不需要将代码打包进一个文件里 #123

lmk123 opened this issue Dec 10, 2022 · 0 comments

Comments

@lmk123
Copy link
Owner

lmk123 commented Dec 10, 2022

我目前正在写很多个 NPM 包。我使用 es module 写了源码,然后用 Rollup 将它们打包在一个文件里,并同时提供 CommonJS 和 es module 的格式。

但最近我开始意识到,我似乎不需要这样做。

我发现,将所有代码打包在同一个文件里的话,很难“优化”。

举个例子,浏览器扩展程序的代码有两种运行环境:内容脚本只能使用一部分 Chrome API,而扩展程序内的其它页面(背景页、弹出页页等)可以使用所有 Chrome API,这种情况下,我需要单独给内容脚本加一个 entry:

// index.js 导出全部
import { runInBackground, runInContent } from 'my-module'

// content-only.js 仅导出只能在内容脚本环境运行的代码
import { runInContent } from 'my-module/content-only'

这样用 Rollup 打包的话就有一个问题,那就是 runInContent 的代码同时出现在了 index.js 和 content-only.js 的 bundle 里。这可能没什么大不了的,但我觉得最理想的方式应该是由 index.js 引入 content-only.js:

// content-only.js
export function runInContent() {}

// index.js
export { runInContent } from './content-only'
export function runInBackground () {}

如果要用 Rollup 做到这一点,那就需要改一些配置,但是我又想到——如果不把代码打包成一个文件的话,不就天然支持这种形式吗?

这么一想,我发现这样做有很多好处:

  • 我不用配置 Rollup 了
  • Webpack 的 sideEffects: true 能起作用了
关于 Webpack 的 sideEffects

Webpack 的 sideEffects 的原理似乎是拆分 import,举个例子:

// 当我们引用了模块里的某个方法时
import { runInBackground } from 'my-module'

// Webpack 会分析 runInBackground 的来源,最终只引入定义了这个函数的文件,比如
import { runInBackground } from 'my-module/lib/background.js'

这样的话就不用导入整个 'my-module',只会导入 'my-module/lib/background.js'。但是如果我们将 my-module 整个打包成一个文件,那么这个优化就不起作用了,因为 my-module 并没有被拆分成多个文件,runInBackground 就在 bundle 里。

找到了一篇比较好的解释 https://stackoverflow.com/a/69866774

坏处就是用户在消费我的 NPM 包的时候需要做一些配置,但我觉得这样利大于弊:

  • 用户自行通过 Babel 处理我的 NPM 包,就能根据自己项目的浏览器 / Node.js 支持范围来对代码进行转译,我也不用管兼容性的问题了,可以直接用最新的语法进行开发
  • 这可能会导致我的 NPM 包在不使用 Babel 的项目里无法使用(例如不支持 ESM 的 Node.js 版本,或者没有使用 Webpack 打包的前端项目),不过这个问题也好解决
    • 如果要兼容不支持 ESM 的 Node.js,那我自己用 Babel 将 ESM 转为 CommonJS,然后通过 package.json 里的 exports 配置就好了
    • 如果要兼容前端项目,那我也可以单独打一个 UMD 包

我担心将 NPM 包打包成一个文件可能有一些好处,但我谷歌了一下 do we need bundle npm package code,推荐的结果都觉得 NPM 包(再次强调,特指 NPM 包)不需要打包成同一个文件:

我准备试试。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant