使用Rollup构建你的JS代码
lihongxun945 opened this issue · 0 comments
很多人知道 vue
等框架的JS代码是用 rollup
编译的,那么 rollup
是什么呢,它和 webpack
有什么异同?如果你也有这个疑惑,那么这篇文章正好可以解答。
Rollup 是什么
Rollup 本身(不包含任何插件的情况下)只是一个模块语法的转换工具,他可以把 ES6 的模块语法编译成不同的语法:
cjs
在node中使用的CMD语法iife
直接在浏览器中运行amd
requirejs 的语法umd
兼容amd
和cmd
举个例子,我们有用 ES6 模块语法编写的代码如下:
foo.js
export default 'Hello world!'
main.js
import foo from './foo.js'
export default function () {
console.log(foo)
}
显然ES6的模块语法无法在node中运行,我们使用rollup用这个命令进行打包:
rollup src/main.js -f cjs
打包出的结果如下:
'use strict';
var foo = 'Hello world!';
function main () {
console.log(foo);
}
module.exports = main;
可以看到rollup做了两件事:
- 把
ES6
模块语法编译成了node
的语法 - 把两个文件的代码打包成了一份。
这就是Rollup本身做的所有事情,是不是很简单明了?
那么会有童鞋要问了,这也太简单了吧?如果我们需要编译 es6/7
中的其他语法呢?
如何处理 ES6/7
等新的JS语法
Rollup本身做的非常精简,任何除了上面讲到的功能外的其他功能,都需要插件来实现,比如我们要把 ES6
中的箭头函数编译一下,就需要安装额外的插件。
把前面的代码稍微改一下,假设我们有如下代码:
foo.js
export default () => {
return 'Hello world!'
}
main.js
import foo from './foo.js'
export default function () {
console.log(foo())
}
那么我们打包成 cjs
之后变成了这样:
'use strict';
var foo = () => {
return 'Hello world!'
};
function main () {
console.log(foo);
}
module.exports = main;
可以看到正如我们前面所说的,箭头函数根本不会被编译,因为 rollup
默认只会编译模块语法,其他语法他是不管的。为了编译 箭头函数等其他 es6/7
的语法,我们需要一个插件 rollup-plugin-babel
我们在 rollup.config.js
中进行如下配置(这里省略了.babelrc
的配置):
// rollup.config.js
import babel from 'rollup-plugin-babel'
export default {
input: 'src/main.js',
output: {
file: 'bundle.js',
format: 'cjs'
},
plugins: [
babel()
]
}
那么打包出来的代码就变成这样了:
'use strict';
var foo = (function () {
return 'Hello world!';
});
function main () {
console.log(foo);
}
module.exports = main;
可以看到其中的箭头函数已经被转成了function
。
Tree shaking
我们在webpack源码解析 中提到过,webpack本身其实进行 tree-shaking 优化,他只负责把无用的exports删除,最终是由 uglify
完成的摇树优化。
我们都知道Webpack 的treeshaking其实是从 rollup 中 借鉴
来的,而rollup原生就实现了 tree shaking。如果我们把上面的代码稍微做一点修改,改成这样:
foo.js
export const foo = () => {
return 'Hello world!'
}
export const bar = () => {
return 'Hello world!'
}
main.js
import {foo} from './foo.js'
export default function () {
console.log(foo())
}
可以看到其中的 bar
函数被直接删除了。
如何在我的项目中使用Rollup
Rollup 官方提供了两个示例项目 https://github.com/rollup/rollup-starter-app 和 https://github.com/rollup/rollup-starter-lib。一个项目是开发JS框架,一个是我们正常的项目。
rollup-starter-lib
重点是展示如何把你的代码打包成不同的版本,以适应不同的环境。这个项目中打包成了三种模块语法: es
, cjs
和 umd
rollup-starter-app
重点是展示如何打包你的项目以在浏览器中运行。这个项目会把代码打包成 iife
模式,也就是把你的代码打包成一个自执行函数。另外还使用了 uglify
压缩代码,以及可以生成sourcemap
和 webpack 的区别
在Rollup官方提供的例子中我们就可以看出,Rollup(包括他的插件)做的仅仅是JS的编译打包工作,这和webpack是有本质区别的。webpack是一个通用的前端资源打包工具,它不仅处理JS,也可以通过loader来处理 CSS、图片、字体等各种前端资源,还提供了 hot reload
等方便前端项目开发的功能。如果不是开发一个JS框架,webpack显然会是一个更好的选择。
如果说相同点,Rollup和Webpack的核心都是处理JS,他们都会解析JS的语法树,然后分析模块依赖。如果对webpack的工作原理不了解,也可以参见我之前写的系列博客 webpack源码解析