You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
借助@babel/plugin-transform-runtime处理polyfill,该插件与usage一样也是扫描代码得出哪些api需要进行polypill,只不过引用的方式改成了import _promise from 'core-js/xxx/xxx.js',这种方式就是无污染的polypill
目录
背景
公司鉴于经常开发
npm
包,于是需要统一一下npm
包的开发规范,总结一个可以通用的npm
包模版开发
npm
通用模版,最关的就是构建工具的选择,该构建工具需要包含如下功能babel
转化typescript
鉴于上述功能,最终选择了rollup来作为我们构建npm包的工具,理由如下
rollup
相对于webpack
更轻量rollup
相对于webpack
更适合构建npm
包的场景rollup
目录社区也是越来越活跃,满足上述的功能rollup
相对于webpack
学习成本更低使用
npm
包打包构建默认选择项目内安装方式,便于rollup
版本的升级rollup插件
常用插件
rollup
默认只能识别es module,原因是tree-shaking
的条件就是需要es module才能进行,而es module能够进行tree-shaking
的原因是,es module是静态模块导入,我们在引入一个模块的时候就已经确定了该模块导出的内容,所以我们在借助rollup来进行npm
包开发的时候,可能会引入一写第三方npm
包,而目前很多第三方npm
包都使用的是commonjs模块规范导出的模块,所以在开发的时候需要借助rollup
的插件来帮助我们完成npm包的开发我们先定义下我们常用的
npm
包开发,需要做哪些事情typescrip
t开发,所以我们需要能够将ts转化成js的插件babel-loader
那里再来处理我们的npm包npm
包typescript
开发,所以我们需要能够将ts转化成js的插件babel-loader
那里再来处理我们的npm
包npm
包基于typescript开发
基于babel做语法转换与polyfill
注意babel与getBabelOutputPlugin方法的区别
二者之前有细微的差异,前者可以包含includes、excludes参数,后者不能使用includes、excludes参数
借助
@babel/plugin-transform-runtime
插件解决polyfill而不是@babel/preset-env
解决ployfill的原因是前者是无污染的polyfill后者是有污染的polyfill目前前端处理js polyfill的方式主要有这两种
借助
polypill.io
来添加垫片借助
babel
来处理ployfill,而babel
实际上借助的core-js
来实现具体的ployfill功能core-js
目前分为2个主要版本2.x与3.x,二者的区别主要是代码目录的划分与模块命名不一致babe
处理polyfill有三种方式直接在项目入口引用
core-js
借助
@babel/preset-env
处理polyfill借助
@babel/plugin-transform-runtime
处理polyfill,该插件与usage一样也是扫描代码得出哪些api需要进行polypill,只不过引用的方式改成了import _promise from 'core-js/xxx/xxx.js',这种方式就是无污染的polypill处理第三方npm包
注意transformMixedEsModules这个参数,允许导入的模块内commonjs与esmodule混用
处理css文件
有些
npm
包内有css文件,所以需要借助css插件进行处理处理amd规范的模块
改包可以将amd规范的模块转化成es module
该包只能识别
exports.foo = foo
这种语法,不支持module.exports.foo = foo
这种语法生成符合es module与 commons 规范的包
注意file的取值,分别是
dist/index.cjs.js
,dist/index.esm.js
目前主流的构建工具都支持识别
package.json
内的module
字段,而我们将module
字段指向es module规范的文件,这样做的目的是,通过构建工具的tree-shaking
功能将没有使用到的代码去掉,减少包的体积大小插件开发
开发
rollup
插件因该遵循如下规范rollup-plugin-
为前缀package.json
内的keyword字段应该包含rollup-plugin-
开发一个简单的替换内容的插件
最佳实践
单文件输出es module与commonjs规范文件
如果需要对
npm
包的代码进行polyfill,需要借助@babel/plugin-transform-runtime
插件多文件输出es module or commonjs规范文件
单文件输出不能做到按需加载,因为代码都已经合并到一个模块了,如果我们要做代码的按需加载需要满足下面两个条件
npm
包的模块是多模块导出的,而不是聚合的一个模块,比如npm
包,实现按需导入,有两种引入方式代码目录结构
rollup配置文件
多文件输出的时候,如果ts有输出.d.ts文件,那么
declarationDir
参数需要设置为dir对应的目录输出结果如下图所示
注意这时候输出的文件是按照源文件的目录结构输出的,如果代码内引入了npm包,且
preserveModules:true
则会在dist目录生成对应的node_modules目录,具体解决方法可以参考FAQ,如果preserveModules:false
则不会生成多余的node_modules
,但是不会按照原目录结构生成文件多文件多目录输出
比如组件库,可能输出dist目录与es目录
代码目录如下图所示
rollup配置
tsconfig.dist.json与tsconfig.es.json的区别就是
outDir
与declarationDir
参数值不同,分别是./dist
与./es
输出结果入下图所示
这样构建出来的组件库就可以实现按需导入,同时支持满足
tree-shaking
的条件FAQ
preserveModules:true
的场景,如果有引入npm包,且没有通过external
参数排除,则生成的目录内会包含node_modules目录,当包真正构建的时候被报错,解决方法如下所示Why does thepreserveModules
option generatenode_modules
folder总结
在通过
rollup
构建npm
包的过程中,碰到了很多的坑,比如碰到了npm
模块内有amd的模块,碰到了npm
包内有css文件,碰到了多文件输出有node_modules
的问题,碰到了babel
插件没有生效的问题等等,最后总结了一些最佳实践,以备后续使用The text was updated successfully, but these errors were encountered: