前言
大略一年前写了个小小的js插件 remember-scroll,并且分享了一篇文章:用Class写一个记住用户来到地位的js插件,是一个纯js库,性能是在用户再次进入页面时能主动定位到上一次浏览的地位,应用webpack+babel打包,外面的webpack和babel的配置至今看来也算是很典型的。
前端打包工具有很多——webpack
,gulp
,rollup
等等,网上有很多文章剖析它们别离更适宜哪些场景,webpack
更适宜打包组件库、应用程序之类的利用,而rollup
更适宜打包纯js的类库。因而笔者始终有想法尝试将 remember-scroll 的打包工具由webpack
更换为rollup
,从理论利用的角度来比照一下两者的区别。
从零配置rollup
- 装置rollup和一些插件
npm i rollup rollup-plugin-uglify rollup-plugin-filesize @rollup/plugin-node-resolve @rollup/plugin-commonjs -D
rollup-plugin-uglify
用于压缩混同打包后的js。rollup-plugin-filesize
打包后在控制台显示文件大小。@rollup/plugin-node-resolve
让rollup
可能辨认node_modules的第三方模块。@rollup/plugin-commonjs
将 CommonJS 的模块转换为 ES2015 供rollup
解决。
- 增加babel
npm i @rollup/plugin-babel @babel/core @babel/plugin-transform-runtime @babel/preset-env core-js@2 -D
@rollup/plugin-babel
rollup 的babel插件。@babel/core
babel外围。@babel/plugin-transform-runtime
用于防止净化全局函数(不是必须要用到,但作为类库最好要加上)。@babel/preset-env
主动依据指标浏览器注入相干的polyfill。core-js
polyfill的类库,这里应用的是2.x版本(应用3会减少包的大小)。
根目录下的babel.config.js
如下:
const presets = [ [ '@babel/env', { useBuiltIns: 'usage', corejs: { version: 2 } }, ],]const plugins = [ '@babel/plugin-transform-runtime']module.exports = { presets, plugins }
- 根目录下新建
rollup.config.js
,全副配置如下:
import filesize from 'rollup-plugin-filesize'import babel from '@rollup/plugin-babel'import resolve from '@rollup/plugin-node-resolve'import { uglify } from 'rollup-plugin-uglify'import commonjs from '@rollup/plugin-commonjs'const isProd = process.env.NODE_ENV === 'production'export default { input: 'src/index.js', output: { file: isProd ? 'dist/remember-scroll.min.js' : 'dist/remember-scroll.js', format: 'umd', exports: 'default', name: 'RememberScroll', }, plugins: [ resolve(), commonjs(), filesize(), babel({ babelHelpers: 'runtime', exclude: ['node_modules/**'] }), (isProd && uglify()) ]}
package.json
打包命令如下:
"build": "rollup -c --environment NODE_ENV:production && rollup -c", "dev": "rollup -c --watch",
总之,所有配置都是与之前webpack
版本的一样,都应用了babel。npm run build
就能够将资源打包到dist了,接下来咱们比照一下webpack
和rollup
两个工具打进去的体积有啥区别。
webpack和rollup打包体积比照
笔者顺便建了一个同时有rollup和webpack打包进去的资源的分支,大家能够间接看下github上feature/webpack_rollup
分支的remember-scroll/dist,比照后果如下:
- | webpack | rollup |
---|---|---|
开发模式大小 | 52.8KB | 19.46KB |
生产打包大小 | 10.3KB | 7.66KB |
生产包gzip后大小 | 4.1KB | 3.4KB |
可见,rollup
打包进去的体积都比webpack
略小一些,通过查看打包进去的代码,webpack打包进去的文件外面有很多__webpack_require__
工具函数的定义,可读性也很差,而rollup打包进去的js会简略一点。
我的项目的master分支曾经改为应用rollup进行构建,feature/webpack分支保留了之前webpack的配置,感兴趣的同学能够去github上具体理解下。
不得不说,从打包体积上来看,应用rollup
构建无疑是更适宜的。
package.json的main指向问题
笔者之前遇到过一个问题是package.json
的main
到底应该是指向构建后的开发版本还是生产版本呢?
对于package.json中main字段的指向问题这篇文章给了答案:main应该指向开发版本。
这里会有一个疑难:援用开发版本的包体积很大,岂不是让我的利用打包上线版本很大?
为了验证下面 package.json 的main
指向开发或生产版本有什么不同,笔者这里间接实战做个比照。
应用VueCli v4.5.9 新建一个vue我的项目,而后在App.vue
引入不同工具打包而成的remember-scroll
,再npm run build
打包该vue我的项目,比照打包进去chunk-vendors.[hash].js
的体积。
引入的npm包默认会打包进chunk-vendors
,app.js
的增量体积都是一样的就不作比照了。
| - | vue打包| 引webpack开发版(52.8KB) | 引webpack生产版(10.3KB) | 引rollup开发版(19.46KB,举荐) | 引rollup生产版(7.66KB)|
Size | 89.42KB | 134.97 | 99.34 | 97.29KB | 96.96KB |
Gzip | 32.04KB | 40.47 | 34.60 | 34.52KB | 34.51KB |
能够看到,应用rollup
打包的,无论main指向开发版还是生产版,gzip后简直统一,但webpack
打包进去的,main指向开发版时体积会相差十分大。
所以应用webpack
打包的插件,个别都是会依据NODE_ENV
来加载对应的包,NODE_ENV === 'production'
时指向压缩后的生产版本。比方像上面这样,在根目录新建一个index.js
,package.json
的main
指向该文件,而后在js中写上:
if (process.env.NODE_ENV === 'production') { module.exports = require('./dist/remember-scroll.min.js')} else { module.exports = require('./dist/remember-scroll.js')}
假使各位当前要写一个用webpack打包的插件,要特地留神这一点。
而如果用rollup打包的,其实就不必在意这个细节啦,在这个环节rollup
又比webpack
更香一点哈哈哈。
总结
通过实战,性能不变且浏览器兼容性统一的状况下,对remember-scroll这个js库来说,应用rollup
打包的确比webpack
会更适合一些。所以如果咱们当前要做技术选型,对于纯js的类库,抉择应用rollup
会更适合一点。
当然,rollup
和webpack
都是作为构建工具,它们都有着各自的劣势和各自的应用场景,利用好它们的长处就能够了。