RollUp
它仅仅是一款ESM打包器。Tree-shaking这个概念最早就是从rollup中提出的。可以通过以下几个命令行,快速进行基础打包。
yarn rollup src/index.js --format iife --file dist/bundle.js
yarn rollup src/index.js --format iife
yarn rollup src/index.js
// 已配置文件方式运行
yarn rollup --config rollup.config.js
配置文件
我们可以在根目录下创建rollup.condig.js的方式,进行配置。我们可以使用ESM语法,它默认导出一个对象:
export default {
input: "src/index.js",
output: {
file: "dist/bundle1.js",
format: "iife"
}
}
对于不同的环境我们可以使用不同的配置文件。
使用插件
在配置文件中,通过plugins属性进行配置。在这个rollup-plugin-json示例中,好像发现了ESM所谓的依赖预声明的好处,同时也加深了对Tree-shaking的理解。还发现了Json文件可以直接以ESM语法导入所需的Json属性。
还有一个rollup-plugin-cleaner插件,能帮助清除上一次打包结果:
import cleaner from 'rollup-plugin-cleaner'
export default {
plugins: [
cleaner({
targets: [
'./dist'
]
})
};
加载NPM模块
通过插件rollup-plugin-node-resolve完成NPM模块的加载
import json from "rollup-plugin-json";
import resolve from "rollup-plugin-node-resolve";
export default {
input: "src/index.js",
output: {
file: "dist/bundle.js",
format: "iife"
},
plugins: [
json(),
resolve()
]
}
代码拆分
示例中是使用动态导入的方式实现代码拆分。对于通过import动态导入的模块,Rollup会自动拆分成不同的bundle。同时还需在config文件中进行配置:
export default {
input: 'src/index.js',
output: {
dir: 'dist', // 需要改为dir,因为此时会打包输出多个文件,file只会输出一个文件
format: 'amd' // rollup支持amd规范,不支持cmd规范
}
}
现在的rollup已支持file属性进行动态导入,他们都会被打包到同一文件,而不会报错。但这样并不是我们想要的代码拆分,因为还是合并到了一起。
多入口打包
我们可以通过配置input属性的值,进行多入口打包,可以配置为路径为元素的数组,也可以像webpack那样的配置对象:
input: ['src/index.js', 'src/album.js']
// webpack那样对象式配置
input: {
foo: 'src/index.js',
bar: 'src/album.js'
},
选用原则
Rollup总结下来有这些优势:
- 输出结果更加扁平,没有那么多的辅助代码,显得更加简洁,执行效率也更高。
- 自动移除未引用代码,默认开启了Tree-Shaking。
- 打包结果的可读性也很好,基本和原生代码一致。
由于小巧灵活,有些功能肯定也会不完善,它有这么些缺点:
- 加载非ESM的第三方模块比较复杂,需要额外配置插件。
- 模块最终被打包到一个函数中,无法实现HMR这种功能。但我觉得应该可以实现,HMR不过是当模块代码有编辑更新时,再重新运行一遍。
- 浏览器环境中,代码拆分是依赖AMD模块规范。
如果我们是开发一个正常的项目,需要引入很多第三方模块,也需要HMR改善开发体验,应用大了也需要分包、压缩代码,而这些是Rollup欠缺的。
但如果是开发JS框架或类库,那他的优点很必要,缺点也可以忽略。比如开发类库,我们是很少去使用第三方模块的。像React和Vue都是使用Rollup。
我们应该要明白的是,让更专业的工具去做专业的事情。Webpack大而全,Rollup小而美。但是目前Webpack在越来越多的场景已经可以替代Rollup了,比如扁平化输出,也可以使用对应插件去实现。
Parcel
这是一款零配置的前端应用打包器。首先进行安装:
yarn add parcel-bundler --dev
parcel和Webpack一样,支持任意文件为打包入口,但是它官方建议以html文件为入口。
使用以下命令进行打包:
yarn parcel src/index.html // 需传入入口路径
通过结果发现,不仅完成了打包,还开启了一个类似devServer的服务。
它居然也支持HMR功能,使用方式和Webpack的一样:
if (module.hot) {
module.hot.accept(() => {
console.log('hmr')
})
}
但是有一点不同的是,它只接受一个回调函数,仅当当前模块以及所依赖模块更新时,才会触发这个热更新函数。
它另一个优点是可以自动安装依赖,而不用终止掉当前服务去安装。我们可以直接在文件中编写需要的第三方依赖,保存后,parcel就开始自动安装依赖。
它也支持自动导入,它可以自动拆分我们的代码。
打包生产代码
同样是一行命令:
yarn parcel build src/index.js
同体量的文件Parcel会比Webpack打包速度快很多,因为在Parcel内部是使用多进程同时去工作,充分发挥了多核CPU的性能。webpack也可以通过happypack插件去实现这一点。
它是2017年发布,出现原因也是因为Webpack使用过于繁琐,而Parcel完全零配置,构建速度快