认识rollup
我们来看一下官方对rollup的定义:
- rollup是一个javascript的模块化打包工具,可以帮助我们编译小的代码到一个大的、复杂的代码中,比如一个库或者一个应用程序
我们会发现rollup的定义、定位和webpack非常的相似:
- rollup也是一个模块化的打包工具,但是rollup主要是针对 ES Module 进行打包的
- 另外webpack通常可以通过各种loader处理各种各样的文件,以及它们的依赖关系
- rollup更多时候是专注于处理javascript代码的(当然也可以处理css、font、vue等文件)
- 另外rollup的配置和理念相对于webpack来说,更加的简洁和容易理解
- 在早期webpack不支持tree shaking时,rollup具备更强的优势
目前webpack和rollup分别应用在什么场景呢?
- 通常在实际开发过程中,我们都会使用webpack(比如vue、react、angular项目都是基于webpack的)
- 在对库文件进行打包时,我们通常会使用rollup(比如vue、react、dayjs源码本身都是基于rollup的)
rollup基本使用
安装:npm isntall rollup
命令行使用
命令行使用语法和webpack差不多,都是通过 npx 执行 node_module 文件夹下的 .bin 文件夹下的脚本
rollup支持cjs和第三方包
对于一些使用commonjs做为模块化方式的文件,我们可以使用 @rollup/plugin-commonjs 这个包来处理
import commonjs from "@rollup/plugin-commonjs";
export default {
input: "./src/main.js",
output: {
format: "umd",
name: "jujuulUtils",
file: "dist/jujuul.umd.js",
},
plugins: [commonjs()],
};
具体的使用为引入 commonjs,然后在 plugins 中调用即可。
而对于引入的第三方包,比如 lodash 这种第三方库,如果只是在 js 文件中引入并使用,那么通过 rollup 打包后是无法将第三方包引入的,因此会报错,解决方法是,在配置文件中将第三方包通过external做额外处理,并且在 html 文件中单独引入。
import commonjs from "@rollup/plugin-commonjs";
import resolve from "@rollup/plugin-node-resolve";
export default {
input: "./src/main.js",
output: {
format: "umd",
name: "jujuulUtils",
file: "dist/jujuul.umd.js",
globals: {
lodash: "_",
},
},
external: ["lodash"],
plugins: [commonjs(), resolve()],
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="node_modules/lodash/lodash.min.js"></script>
<script src="./dist/jujuul.umd.js"></script>
<script>
console.log(jujuulUtils.sum(20, 30))
</script>
</body>
</html>
一些基本功能的使用
像是比较常见的配置,ES6语法转换、代码压缩等,配置方式和webpack没什么太大区别
- 首先是安装
npm install @rollup/plugin-babel rollup-plugin-terser
- 然后就是引入,并且在plugins属性中使用 ```javascript import commonjs from “@rollup/plugin-commonjs”; import babel from “@rollup/plugin-babel”; import { terser } from “rollup-plugin-terser”;
export default { input: “./src/main.js”, output: { format: “umd”, name: “jujuulUtils”, file: “dist/jujuul.umd.js”, globals: { lodash: “_”, }, }, external: [“lodash”], plugins: [ commonjs(), babel({ babelHelpers: “bundled”, }), terser(), ], };
3. 像是 babel 转换这种也可以本地建立文件,和webpack用法一样
```javascript
// babel.config.js
module.exports = {
presets: ["@babel/preset-env"],
};
rollup对css和vue文件处理
rollup处理css和vue文件和webpack原理基本上一致,有些许不同。webpack处理css文件和vue文件通过loader,而rollup则是通过plugins。
相同点在于都是安装插件,loader插件或者plugins插件,然后调用插件即可。
rollup处理过程
- 安装插件
npm install rollup-plugin-postcss postcss rollup-plugin-vue -D
- 使用插件 ```javascript import commonjs from “@rollup/plugin-commonjs”; import babel from “@rollup/plugin-babel”; import { terser } from “rollup-plugin-terser”; import resolve from “@rollup/plugin-node-resolve”;
// 使用 postcss 和 vue 插件 import postcss from “rollup-plugin-postcss”; import vue from “rollup-plugin-vue”;
export default { input: “./src/main.js”, output: { format: “umd”, name: “jujuulUtils”, file: “dist/jujuul.umd.js”, globals: { lodash: “_”, }, }, external: [“lodash”], plugins: [ commonjs(), resolve(), babel({ babelHelpers: “bundled”, }), // 使用 postcss 和 vue 插件 postcss(), vue(), terser(), ], };
3. 处理vue文件的额外操作
如上的代码处理vue文件后,会因为没有环境变量导致报错,这是因为 rollup 打包代码会将 vue 源码一起打包,而 vue 源码中需要提供环境变量,所以这里还要用到额外的插件
- 安装 rollup-plugin-replace 插件
`npm i rollup-plugin-replace -D`
- 使用 replace 提供环境变量
```javascript
import replace from "rollup-plugin-replace";
// ...
plugins: [
commonjs(),
resolve(),
// 使用 replace 提供环境变量
replace({
"process.env.NODE_ENV": JSON.stringify("production"),
}),
babel({
babelHelpers: "bundled",
}),
postcss(),
vue(),
terser(),
],
开启本地服务和环境区分
开启本地服务
在开发中,为了方便调试,我们需要开启本地服务,步骤是:
- 安装插件
npm install rollup-plugin-serve -D
- 使用插件 ```javascript import serve from “rollup-plugin-serve”;
// … plugins: [ commonjs(), resolve(), replace({ “process.env.NODE_ENV”: JSON.stringify(“production”), }), babel({ babelHelpers: “bundled”, }), postcss(), vue(), terser(), // 使用插件 serve({ open: true, // 是否打开浏览器 port: 8080, // 监听哪一个端口 contentBase: “.”, // 服务哪一个文件夹 }), ],
<a name="JHBQD"></a>
## 热更新
热更新的原理就是在监听到文件变化后,重新打包文件
1. 安装插件
`npm install rollup-plugin-livereload -D`
2. 使用插件
```javascript
import livereload from "rollup-plugin-livereload";
// ...
plugins: [
commonjs(),
resolve(),
replace({
"process.env.NODE_ENV": JSON.stringify("production"),
}),
babel({
babelHelpers: "bundled",
}),
postcss(),
vue(),
terser(),
serve({
open: true, // 是否打开浏览器
port: 8080, // 监听哪一个端口
contentBase: ".", // 服务哪一个文件夹
}),
// 使用插件
livereload(),
],
修改 package.json 配置
"scripts": { "build": "rollup -c", "serve": "rollup -c -w" },
package.json 中新建一个 serve 指令,用来监听
额外事项
默认监听的是 input 的值,可以指定 watch 对象,来指定具体监听的文件
环境区分
在 package.json 的启动脚本中传入环境变量,就可以区分不同的环境,再根据环境的不同调用不同的插件,实现开发环境和生产环境的分离。
区分环境
"scripts": { "build": "rollup -c --environment NODE_ENV:production", "serve": "rollup -c --environment NODE_ENV:development -w" },
区分环境并使用 ```javascript const isProduction = process.env.NODE_ENV === “production”; const plugins = [ commonjs(), resolve(), replace({ “process.env.NODE_ENV”: JSON.stringify(process.env.NODE_ENV), }), babel({ babelHelpers: “bundled”, }), postcss(), vue(), ];
// 判断环境,根据环境的不同使用不同的 rules if (isProduction) { plugins.push(terser()); } else { const devPlugins = [ serve({ // open: true, // 是否打开浏览器 port: 8080, // 监听哪一个端口 contentBase: “.”, // 服务哪一个文件夹 }), livereload(), ]; // 合并 rule 规则 plugins.push(…devPlugins); } ```