Rollup 与其他工具集成
npm packages
在某些时候,你的项目很可能依赖于从npm安装到你的node_modules
文件夹中的软件包。 与Webpack和Browserify这样的其他捆绑包不同,Rollup不知道如何打破常规去处理这些依赖。 - 我们需要添加一些配置。
让我们添加一个简单的依赖 the-answer,它输出对生活、宇宙及其它一切的答案
npm install the-answer # or `npm i the-answer`
如果修改我们的 src/main.js
入口文件...
// src/main.js
import answer from 'the-answer';
export default function () {
console.log('the answer is ' + answer);
}
...然后执行 Rollup...
npm run build
...我们将会看到下面这些警告:
(!) Unresolved dependencies
https://github.com/rollup/rollup/wiki/Troubleshooting#treating-module-as-external-dependency
the-answer (imported by main.js)
打包后的bundle.js
仍然会在 Node.js 中工作,因为import
声明转变成了 CommonJS中的 require
语句,但是the-answer
不包含在包中。因此,我们需要一个插件。
rollup-plugin-node-resolve
这个 rollup-plugin-node-resolve 插件可以告诉 Rollup 如何查找外部模块。 安装它...
npm install --save-dev rollup-plugin-node-resolve
...将它加入到你的配置文件中:
// rollup.config.js
import resolve from 'rollup-plugin-node-resolve';
export default {
input: 'src/main.js',
output: {
file: 'bundle.js',
format: 'cjs'
},
plugins: [ resolve() ]
};
这次,当你运行 npm run build
, 再没有警告输出 - 打包文件 bundle 包含了引用的模块。
rollup-plugin-commonjs
一些库导出成你可以正常导入的ES6模块 -the-answer
就是一个这样的模块。 但是目前,npm中的大多数包都是以CommonJS模块的形式出现的。 在它们更改之前,我们需要将CommonJS模块转换为 ES2015 供 Rollup 处理。
这个 rollup-plugin-commonjs 插件就是用来将 CommonJS 转换成 ES2015 模块的。
请注意,rollup-plugin-commonjs
应该用在其他插件转换你的模块之前 - 这是为了防止其他插件的改变破坏CommonJS的检测。
Peer dependencies
假设你正在构建一个具有对等依赖关系(peer dependency)的库,例如React或Lodash。 如果你如上所述设置外部引用(externals),你的 Rollup 将把 所有 imports 的模块打包在一起:
import answer from 'the-answer';
import _ from 'lodash';
你可以微调哪些导入是想要打包的,哪些是外部的引用(externals)。 对于这个例子,我们认为lodash
是外部的引用(externals),而不是the-answer
。
这是配置文件:
// rollup.config.js
import resolve from 'rollup-plugin-node-resolve';
export default {
input: 'src/main.js',
output: {
file: 'bundle.js',
format: 'cjs'
},
plugins: [resolve({
// 将自定义选项传递给解析插件
customResolveOptions: {
moduleDirectory: 'node_modules'
}
})],
// 指出应将哪些模块视为外部模块
external: ['lodash']
};
这样,“lodash”现在将被视为外部的(externals),不会与你的库打包在一起。
external
接受一个模块名称的数组或一个接受模块名称的函数,如果它被视为外部引用(externals)则返回true。 例如:
export default {
// ...
external: id => /lodash/.test(id)
}
如果你使用 [babel-plugin-lodash](https://github.com/lodash/babel-plugin-lodash)来最优选择lodash模块,在这种情况下,Babel将转换你的导入语句,如下所示
import _merge from 'lodash/merge';
“external”的数组形式不会处理通配符,所以这个导入只会以函数的形式被视作外部依赖/引用(externals)。
Babel
许多开发人员在他们的项目中使用[Babel](https://babeljs.io/),以便他们可以使用未被浏览器和Node.js支持的将来版本的 JavaScript 特性。
使用 Babel 和 Rollup 的最简单方法是使用 [rollup-plugin-babel](https://github.com/rollup/rollup-plugin-babel)。 安装它:
npm i -D rollup-plugin-babel
添加到Rollup配置文件 rollup.config.js
:
// rollup.config.js
import resolve from 'rollup-plugin-node-resolve';
import babel from 'rollup-plugin-babel';
export default {
input: 'src/main.js',
output: {
file: 'bundle.js',
format: 'cjs'
},
plugins: [
resolve(),
babel({
exclude: 'node_modules/**' // 只编译我们的源代码
})
]
};
在Babel实际编译代码之前,需要进行配置。 创建一个新文件src/.babelrc
:
{
"presets": [
["latest", {
"es2015": {
"modules": false
}
}]
],
"plugins": ["external-helpers"]
}
这个设置有一些不寻常的地方。首先,我们设置"modules": false
,否则 Babel 会在 Rollup 有机会做处理之前,将我们的模块转成 CommonJS,导致 Rollup 的一些处理失败。
其次,我们使用external-helpers
插件,它允许 Rollup 在包的顶部只引用一次 “helpers”,而不是每个使用它们的模块中都引用一遍(这是默认行为)。
第三,我们将.babelrc
文件放在src
中,而不是根目录下。 这允许我们对于不同的任务有不同的.babelrc
配置,比如像测试,如果我们以后需要的话 - 通常为单独的任务单独配置会更好。
现在,在我们运行 rollup 之前,我们需要安装latest
preset 和external-helpers
插件
npm i -D babel-preset-latest babel-plugin-external-helpers
运行 Rollup 现在将创建一个 bundle 包... 实际上我们并没有使用任何ES2015特性。 我们来改变一下。 编辑src / main.js
:
// src/main.js
import answer from 'the-answer';
export default () => {
console.log(`the answer is ${answer}`);
}
运行 Rollup npm run build
,检查打包后的bundle:
'use strict';
var index = 42;
var main = (function () {
console.log('the answer is ' + index);
});
module.exports = main;
Gulp
Rollup 返回 gulp 能明白的 promises,所以集成是很容易的。
语法与配置文件非常相似,但属性分为两个不同的操作,对应于JavaScript API:
const gulp = require('gulp');
const rollup = require('rollup');
const rollupTypescript = require('rollup-plugin-typescript');
gulp.task('build', async function () {
const bundle = await rollup.rollup({
input: './src/main.ts',
plugins: [
rollupTypescript()
]
});
await bundle.write({
file: './dist/library.js',
format: 'umd',
name: 'library',
sourcemap: true
});
});