作者:曾启澔
前言:
为什么要模块化
一般情况下,单一的中小型项目没有将自己模块化打包的必要。然而在实际工作或者开源项目开发的场合下,往往会有需要将当前项目或者其中一部分功能性代码在其他项目中使用的场景。若仅仅简单的对代码的复制黏贴,会对代码的管理以及后续开发改进产生极大的不便,代码每有改动就需要在各个项目中保持同步更新,非常不便。此时对代码进行模块化打包是一个非常值得考虑的手段,模块化后的代码能非常便利的在其他项目中进行使用,并解决了代码内容变动产生的差异化问题。
模块化的好处
· 项目组建分割化开发,降低复杂度
· 开发通用Library、可于多个不同项目中应用同一处理模块
· 能够轻松植入到第三方代码中
关于Rollup:
Rollup.js是什么
Rollup是一个目前较为流行的JavaScript模块打包器。常见的JavaScript的开源程序及Library的模块化打包都是用到了Rollup。
Rollup.js的特点
· 兼容性高:可以自由打包成目前常规的模块类型(如CommonJS和ES6),兼容各个浏览器标准
· 统一处理:可对全体代码(包括引用模块)的语法格式统一,纠错,进行统一处理
· 压缩:对代码进行压缩处理,产出更小容量的代码文件插件:庞大的插件库,并支持自定义插件开发
· 庞大的插件库
· 打包速度快、配置简单
开始Rollup
Rollup.js的安装
安装Rollup前,首先需要安装Node.js。具体方法请参考官方文档。
1. 全局安装:
npm install rollup -g
安装完后可以通过以下命令确认是否安装成功,若显示版本号说明可以正常使用Rollup了。
rollup -version
2. 项目中安装(推荐):
一般来说,为了保证在任何环境下都能正常进行模块化打包,采取在项目中安装依赖的做法更为常用。于项目根目录执行以下代码,将rollup于当前项目中。此举保证了rollup的版本统一、确保正常的打包。
npm install rollup –save-dev
Rollup.js基本命令
rollup ./index.js -o dist/index_es.js -f es
在项目中安装的场合为
./node_modules/.bin/rollup ./index.js -o dist/index_es.js -f es
该命令的意思为将文件index.js打包为ES6模块后保存到dist/index_es.js。
*更多命令行参数请参考官方文档:命令行参数
Rollup.js配置文件
虽然通过命令行,我们可以使用rollup所有的功能。但是因为自定义打包需要对多种插件、环境进行配置,全部采用命令并不是一种聪明的手段。这里建议使用Rollup配置文件,方便设置的管理和统一。方法很简单,在项目根目录中建立一个名为rollup.config.js的配置文件。
// rollup.config.js
export default [ {
input: 'src/***/[target.js] ', // 需要模块化打包的目标文件
output: [ {
file: ***/[output].js', // 输出路径及输出文件名
format: 'es' // 输出类型(amd, cjs, es, iife, umd)
}],
external: […], // 外链列表(可选)
plugins: […] // 插件列表(可选)
}];
建立了文件后,通过命令行选择配置文件进行打包
rollup -c -o bundle-2.js
*想了解更多配置文件内容,请参考官方文档:配置文件
Rollup.js打包示例
1. 创建一个需要模块化的入口文件index.js:
// index.js
import { Now } from './lib'
Now()
2. 创建引用的依赖文件lib.js:
// lib.js
export const Now = () => {
console.log('Now:', new Date())
}
3. 使用命令行进行打包
rollup ./index.js -o dist/index_es.js -f es
4. 输出dist/index_es.js内容如下
const Now = () => {
console.log('Now:', new Date());
};
Now();
5. Rollup配置文件rollup.config.js
// rollup.config.js
export default [
{
input: './index.js',
output: [
{
file: 'dist/index_cjs.js',
format: 'cjs'
},
{
file: 'dist/index_es.js',
format: 'es'
}
]
}
]
6. 执行命令行 rollup -c
7. 分别生产cjs形式的模块文件./dist/index_cjs.js和es形式文件./dist/index_es.js。
模块化后可在其他项目中的html head中导入
进阶-Rollup的插件:
Rollup的一大优势就是拥有强大的插件库可供选择。用户可以根据自身需要,安装对应插件实现代码纠错、规范化、压缩、uglify以及对vue、react等主流框架代码进行编译和打包。
这里介绍一些常用插件:
· rollup-plugin-clear:用于在打包前对输出目录进清扫,删除不需要的文件或者清空目录
· rollup-plugin-alias:modules名称的 alias 和reslove 功能
· rollup-plugin-babel:babel语法编译
· rollup-plugin-eslint:eslint代码语法规范及纠错
· rollup-plugin-terser:代码压缩用插件
· rollup-plugin-node-resolve:解析 node_modules 中的模块
· rollup-plugin-commonjs:转换 cjs
· rollup-plugin-replace:用于环境变量参数的替换
通过npm install以上模块后,可以通过重新配置rollup.config.js文件,实现插件功能。(其中babel插件还需要安装babel依赖并在config中配置babel插件)
const path = require('path');
import replace from 'rollup-plugin-replace';
import alias from 'rollup-plugin-alias';
import nodeResolve from 'rollup-plugin-node-resolve';
import flow from 'rollup-plugin-flow-no-whitespace';
import babel from 'rollup-plugin-babel';
import commonjs from 'rollup-plugin-commonjs';
import globals from 'rollup-plugin-node-globals';
import builtins from 'rollup-plugin-node-builtins';
import clear from 'rollup-plugin-clear';
import { terser } from 'rollup-plugin-terser';
export default [
{
input: './index.js',
output: [
{
file: 'dist/index_cjs.js',
format: 'cjs'
},
{
file: 'dist/index_es.js',
format: 'es'
}
],
external: [ 'fs' ],
plugins: [
replace({
ENV: JSON.stringify(process.env.NODE_ENV || 'production')
}),
alias({
resolve: ['.js'],
'~': path.resolve(__dirname, 'src/scripts/')
}),
clear({
targets: ['dist']
}),
nodeResolve(),
babel({
babelrc: false,
comments: false,
sourceMap: false,
presets: [
['@babel/preset-env']
],
plugins: [
['@babel/plugin-syntax-dynamic-import'],
['@babel/plugin-proposal-class-properties'],
['@babel/plugin-proposal-export-namespace-from'],
['@babel/plugin-proposal-throw-expressions']
],
exclude: 'node_modules/**',
runtimeHelpers: true
}),
commonjs(),
globals(),
builtins(),
flow(),
terser({
toplevel: true,
compress: {
passes: 2
},
mangle: true,
output: {
ascii_only: true,
beautify: false,
preamble: '/* minified */'
}
})
]
},
];
以上配置文件配置了babel、alias、clear、nodeResolve、commonjs、globals、flow、terser等插件,运行结果如下:
/* minified */
console.log("Now:",new Date);
小结
Rollup可以使你的程序打包后以模块形式加载于其他项目中
Rollup可以打包输出各种主流类型模块格式,兼容性稿
Rollup可以通过安装插件,对vue、react等主流框架编写的程序进行打包
Rollup可以通过安装插件实现代码规范化、差错、压缩、uglify。可操作性强