使用rollup编写现代化模块
bosens-China opened this issue · 0 comments
之所有选用 rollup 是因为它可以减少打包体积和提高构建速度,下面介绍不会详细讲解配置,你可以自行查阅官方文档
ES6 已经出现很久了,但是为了兼容以前的浏览器,我们还是需要使用各种构建工具,例如 webpack,在使用的时候很方便,可以通过 babel 转换 es6 的语法,比如下面导入一个模块
import moduleName from 'module';
不过编写一个现代化模块呢,预定目标应该有三点
- 支持 typescript,将 ES6 代码转化为 ES5 环境使用
- 支持构建工具和
script type="module"
的导入 - 支持 umd 格式引用
就以下面这段代码为演示,实现上述的目标
export default (arr = []) => {
return Array.from(arr).length;
};
准备
npm init -y
npm i rollup -D
cd.>rollup.config.js
md src
cd.>src/index.js
这样就创建好我们想要的基本结构了,将上面例子复制到 index.js
文件下。
rollup
可以通过命令行也可以通过脚本来调用,这里在package.json
的scripts
字段,通过脚本调用
"scripts": {
"build": "rollup -c"
}
-c
是指配置文件,默认就是rollup.config.js
所以不需要额外配置了
编写第一个例子
rollup.config.js
export default {
input: "./src/index.js",
output: [
{
file: "dist/index.esm.browser.js",
format: "es",
sourcemap: true
}
]
};
上面配置信息input
指的是入口文件,output
是出口文件,file
是输出的文件路径,sourcemap
是是否输出 map 文件,他可以方便调试错误,在开发模块中应该是必须的,format
是指输出的格式
- amd
异步模块定义,用于像 RequireJS 这样的模块加载器 - cjs
CommonJS,适用于 Node 和 Browserify/Webpack - es
将软件包保存为 ES 模块文件 - iife
一个自动执行的功能,适合作为<\script>标签。(如果要为应用程序创建一个捆绑包,您可能想要使用它,因为它会使文件大小变小。) - umd
通用模块定义,以 amd,cjs 和 iife 为一体
执行npm run build
dist/index.esm.browser.js
var index = (arr = []) => {
return Array.from(arr).length;
};
export default index;
//# sourceMappingURL=index.esm.browser.js.map
可以看到生成的信息十分简洁,上面说到要同时支持umd
格式和 import
导入,import
可以通过es
的形式来供构建工具和script type="module"
使用,下面就来定义一下 umd 格式
export default {
input: "./src/index.js",
output: [
{
file: "dist/index.esm.browser.js",
format: "es",
sourcemap: true
},
{
file: "dist/index.js",
format: "umd",
sourcemap: true,
name: "index"
}
]
};
注意使用umd
或者iife
必须指定 name 字段,他决定了暴露在全局作用下的变量名,再次执行可以看到index.js
的信息了。
babel
上面完成了需求的第一步,不过对于 es6 的代码,并没有转化为 es5 的形式,只是将语法转换了,Array.from
依旧存在,下面使用babel
来完成需求
npm i @babel/core @babel/preset-env core-js rollup-plugin-babel rollup-plugin-node-resolve rollup-plugin-commonjs -D
babel.config.js
module.exports = {
presets: [
[
"@babel/preset-env",
{
useBuiltIns: "usage",
corejs: 3,
modules: false
}
]
]
};
上面代码的useBuiltIns
的usage
是 babel7 的实验性特性,他支持按需加载
rollup.config.js
import babel from "rollup-plugin-babel";
import resolve from "rollup-plugin-node-resolve";
import commonjs from "rollup-plugin-commonjs";
export default {
input: "./src/index.js",
output: [
{
file: "dist/index.esm.browser.js",
format: "es",
sourcemap: true
},
{
file: "dist/index.js",
format: "umd",
sourcemap: true,
name: "index"
}
],
plugins: [
commonjs(),
resolve(),
babel({
exclude: [/\/core-js\//],
runtimeHelpers: true,
sourceMap: true,
extensions: [".js", ".jsx", ".es6", ".es", ".mjs", ".ts"]
})
]
};
再次执行可以看到Arrar.from
已经被babel
转换为 ES5 的环境了
typescript
这个我们用babel
提供给我们的@babel/preset-typescript
即可完成,不过为了支持typescript
一些其他扩展语法,我们还需要安装一些插件
npm i @babel/preset-typescript @babel/plugin-transform-typescript @babel/plugin-syntax-dynamic-import @babel/plugin-proposal-class-properties -D
babel.config.js
module.exports = {
presets: [
[
"@babel/preset-env",
{
useBuiltIns: "usage",
corejs: 3,
modules: false
}
],
["@babel/preset-typescript"]
],
plugins: [
"@babel/plugin-transform-typescript",
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-proposal-class-properties"
]
};
修改一下 src/index.js
为 index.ts
,rollup.config.js
下input
字段
export default (arr: Array<any> = []): number => {
return Array.from(arr).length;
};
再次执行npm run build
,成功输出
优化
- 输出代码没有被压缩
- 每次输出的时候文件夹没有被删除
上面两个问题,可以通过插件来解决
npm i rollup-plugin-terser rollup-plugin-clear -D
rollup.config.js
import babel from "rollup-plugin-babel";
import clear from "rollup-plugin-clear";
import resolve from "rollup-plugin-node-resolve";
import commonjs from "rollup-plugin-commonjs";
import { terser } from "rollup-plugin-terser";
export default {
input: "./src/index.ts",
output: [
{
file: "dist/index.esm.browser.js",
format: "es",
sourcemap: true
},
{
file: "dist/index.js",
format: "umd",
sourcemap: true,
name: "index"
}
],
plugins: [
clear({
targets: ["dist"]
}),
resolve(),
commonjs(),
terser(),
babel({
exclude: [/\/core-js\//],
runtimeHelpers: true,
sourceMap: true,
extensions: [".js", ".jsx", ".es6", ".es", ".mjs", ".ts"]
})
]
};
这样基本的模块的基本功能就编写完成了