认识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 这个包来处理

  1. import commonjs from "@rollup/plugin-commonjs";
  2. export default {
  3. input: "./src/main.js",
  4. output: {
  5. format: "umd",
  6. name: "jujuulUtils",
  7. file: "dist/jujuul.umd.js",
  8. },
  9. plugins: [commonjs()],
  10. };

具体的使用为引入 commonjs,然后在 plugins 中调用即可。

而对于引入的第三方包,比如 lodash 这种第三方库,如果只是在 js 文件中引入并使用,那么通过 rollup 打包后是无法将第三方包引入的,因此会报错,解决方法是,在配置文件中将第三方包通过external做额外处理,并且在 html 文件中单独引入。

  1. import commonjs from "@rollup/plugin-commonjs";
  2. import resolve from "@rollup/plugin-node-resolve";
  3. export default {
  4. input: "./src/main.js",
  5. output: {
  6. format: "umd",
  7. name: "jujuulUtils",
  8. file: "dist/jujuul.umd.js",
  9. globals: {
  10. lodash: "_",
  11. },
  12. },
  13. external: ["lodash"],
  14. plugins: [commonjs(), resolve()],
  15. };
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <script src="node_modules/lodash/lodash.min.js"></script>
  11. <script src="./dist/jujuul.umd.js"></script>
  12. <script>
  13. console.log(jujuulUtils.sum(20, 30))
  14. </script>
  15. </body>
  16. </html>

一些基本功能的使用

像是比较常见的配置,ES6语法转换、代码压缩等,配置方式和webpack没什么太大区别

  1. 首先是安装

npm install @rollup/plugin-babel rollup-plugin-terser

  1. 然后就是引入,并且在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处理过程

  1. 安装插件

npm install rollup-plugin-postcss postcss rollup-plugin-vue -D

  1. 使用插件 ```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(),
],

开启本地服务和环境区分

开启本地服务

在开发中,为了方便调试,我们需要开启本地服务,步骤是:

  1. 安装插件

npm install rollup-plugin-serve -D

  1. 使用插件 ```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(),
],
  1. 修改 package.json 配置

    "scripts": {
    "build": "rollup -c",
    "serve": "rollup -c -w"
    },
    

    package.json 中新建一个 serve 指令,用来监听

  2. 额外事项

默认监听的是 input 的值,可以指定 watch 对象,来指定具体监听的文件

环境区分

在 package.json 的启动脚本中传入环境变量,就可以区分不同的环境,再根据环境的不同调用不同的插件,实现开发环境和生产环境的分离。

  1. 区分环境

    "scripts": {
    "build": "rollup -c --environment NODE_ENV:production",
    "serve": "rollup -c --environment NODE_ENV:development -w"
    },
    
  2. 区分环境并使用 ```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); } ```