勉强凑个 5 个。
Tip 1. 如何选择打包格式?
我们支持三种打包格式,
- cjs
- esm
- umd
具体含义可以查文档。然后 esm 里还有个 mjs 的变种,感兴趣的可以具体查文档。
那么怎么选呢?
浏览器包
如果是给浏览器用,那么选 cjs
和 esm
。
项目打包时(通常用 webpack)用 esm
,cjs
有两种用途,1 是给 SSR(服务端渲染)用,2 是当你的库作为依赖进行测试时,测试库(比如 jest)通常不会处理 esm 格式,只能用 cjs 格式。如果不考虑 cjs
的两种用途,也可以只选 esm
。
umd
通常不用打,除非你知道为啥要打。
node 包
如果是给 node 用,那么只选 cjs
就够了。
然后记得 target
配 node
,兼容到 node 6。不配的话,语法层会兼容到 IE10,会引入不必要的语法转化代码。
Tip 2. 如何选择打包方式?
我们支持两种打包方式,
- rollup
- babel
所有格式都支持 rollup 打包方式,然后 cjs
和 mjs
还支持 babel 打包方式。
配置示例,
cjs: 'rollup',
esm: 'babel',
怎么选?
**无特殊需要,推荐用 rollup
。**这是组件打包的主流方案,编译后是一个文件,应用到项目后打包会更快;由于 rollup
的 tree-shaking 比 webpack 更激进,理论上应用到项目之后产物会更小。
如果只要 cjs
和 esm
格式,那么 babel
打包方式是万能方案,只做语法转化。
我想到一些必须用 babel 的场景,欢迎补充,
node
包,需要读一些奇怪的文件,比如 template 文件等- 类
antd
的场景,输出后还要按需载入样式啥的
Tip 3. 遇到 Error: 'default' is not exported by
错误怎么办?
问题
这是新手用户经常遇到的问题,如果你的打包格式不是 umd,那么解决起来很简单,只要调整 package.json
里的依赖配置即可。(umd 格式处理起来复杂些,这里不展开)
比如,你的代码里依赖了 foo
:
import foo from 'foo';
然后报错了,
Error: 'default' is not exported by foo
底层原因是因为依赖 foo
没有 export default,但是我们打 esm
或 cjs
时是不需要把依赖也打进去的,怎么会要分析到依赖 foo
里的代码呢?
解决
这种情况下可以检查下 package.json
,你会发现 foo
并不存在于 dependencies
或 peerDependencies
里,而是在 devDependencies
里或没有写依赖。
{
"devDependencies": {
"foo": "1"
}
}
解决办法就是把他写到 dependencies
或 peerDependencies
里,比如:
{
"dependencies": {
"foo": "1"
}
}
因为我们有个关于 externals 的约定,打包 esm
或 cjs
时,dependencies 和 peerDependencies 里的依赖会被处理为 externals,不打包到产物里。
Tip 4. 你的组件依赖了 antd?
问题
如果你的组件里依赖了 antd
,
import { Button } from 'antd';
那么,打包后还是,
import { Button } from 'antd';
或者 cjs 格式的,
const { Button } = require('antd');
然后你的组件在发布之后,被用户使用时是存在于 node_modules
下的,而 node_modules
下目前不走 babel 编译。所以,虽然用户项目里配了 babel-plugin-import
按需打 antd
,但影响不到到你的组件代码,然后用户项目就不知不觉地全量引了 antd 了。
方案
- 安装依赖
babel-plugin-import
- 通过
extraBabelPlugins
配置 antd 的按需加载,libraryDirectory
为es
,如下:
extraBabelPlugins: [
['babel-plugin-import', {
libraryName: 'antd',
libraryDirectory: 'es',
style: true,
}]
],
然后对于 antd 的引用就会变成,
import Button from 'antd/es/button';
import('antd/es/button/style');
从而不会全量引入 antd。
doc dev 时的 antd 样式问题
如果 doc dev 时 antd 没有样式,有两种解决方案,
- 如上配置(推荐)
- 通过
doc.htmlContext.head.links
引入 antd 样式(不推荐)
doc: {
htmlContext: {
head: {
links: [
{
rel: 'stylesheet',
href: 'https://cdn.bootcss.com/antd/3.12.3/antd.css',
},
],
},
},
}
Tip 5. 组件怎么打补丁?
**组件不用打补丁!**补丁只在项目里决定是否启用,以及启用哪些。为啥?因为如何每个组件都自己打补丁,那么就会有无数个重复的补丁。
如果要做地严谨一些,可以和 react 一样,告诉用户使用你的组件之前需要引入哪些补丁。