rollup 快速起步 | 青训营笔记

81 阅读4分钟

这是我参与「第四届青训营」笔记创作活动的第3天

写在前面

Vue CLI 提供了开箱即用的现成 Vue 开发工具包,虽然官方教程中提示了不推荐新手直接使用 vue-cli 。但是比起花好些天去熟悉 Node.js 构建工具,在繁琐的配置中纠结,直接 vue create 一个现成项目去熟悉 Vue 显然是能更快带来正向反馈的选择。在熟练掌握应用的撰写之后,现在是时候回过头去还这份债了。

安装与初始化

npm i rollup -g // 全局安装
npm i rollup -D // 或者选择安装为开发依赖

npm init // 生成 package.json

接下来创建我们需要打包的入口文件,并创建配置文件,在配置文件中配置出入口路径。

需要认识到,rollup 是一个 JavaScript 模块打包器,意味着最终需要打包成一个 .js 文件并在页面中引用,入口和出口都是 JavaScript 代码文件。而使用 vue-cli 时不创建 index.html 也能运行项目,是因为工具负责完成了生成模板主页文件并引用打包完成的 .js 文件这一过程,在打包后的 /dist 文件夹下能够找到输出的 index.html

// index.html
<!doctype html>
<html lang="en">
    ...
    <body>
        <script src="bundle.js"></script>
    </body>
</html>

// src/main.js
...any script you like
// rollup.config.js
export default {
  input: 'src/main.js', // 入口文件路径,通常会和其他模块一起放在 ./src 下管理
  output: {
    file: 'bundle.js',  // 出口文件路径
    format: 'esm',      // 生成包的格式
  }
}

然后配置指令方便调用

// package.json
...
"scripts": {
    "dev": "rollup -wc rollup.config.js" // -w: watch, 文件更新后自动重新编译
}                                        // -c: config, 指定配置文件

现在就可以完成最简单的模块打包了,这也是 rollup 本体所具有的功能。而其他的功能,如对 .vue 文件的解析,热更新等等都是通过插件的方式实现。

插件的使用

热重载

热更新是通过 rollup-plugin-livereload rollup-plugin-serve 两个插件来实现的。serve 插件会开启一个本地服务器返回静态资源,livereload插件负责检测文件更新并与页面通信来实现页面热重载。

npm i rollup-plugin-livereload -D
npm i rollup-plugin-serve -D

// rollup.config.js
import livereload from 'rollup-plugin-livereload'
import serve from 'rollup-plugin-serve'

export default {
    ...
    plugins: [
        livereload(),
        serve({
            open: true,
            contentBase: '',          // 提供网站资源的文件夹
            host: 'localhost',
            port: 8888,
            openPage: '/index.html',
        }),
    ]
}

更详细的配置信息可以在 npm 搜索对应的插件名来查看。

Vue

要使用 Vue 进行应用开发,需要在 main.js 文件中创建应用并挂载到页面中去。当然,页面中需要新增一个 div#app 元素。

// main.js
import { createApp } from 'vue'
import App from './index.vue'

createApp(App).mount('#app')

然后创建 index.vue 文件即可。但是 rollup 本身不能处理 node_modules ,此时需要安装并引入 @rollup/plugin-node-resolve 来处理引入的包(注意导入方式的不一致),并使用 rollup-plugin-vue 来处理 SFC 文件的解析。

import { nodeResolve } from '@rollup/plugin-node-resolve'
import vuePlugin from 'rollup-plugin-vue'

export default {
    ...
    plugins: [
        nodeResolve(),
        vuePlugin(),
    ]
}

另外,由于 Vue 的构建工具版本 vue(.runtime).esm-bundler.js 留下了对 process.env.NODE_ENV 判断来区分线上和开发环境的语句。而 process.envnode 环境才有的变量,在网页端并不存在,因而需要对这个变量进行替换才能正常运行。

image.png

使用到的插件为 @rollup/plugin-replace

import replace from '@rollup/plugin-replace'

const env = process.env.NODE_ENV

... plugins: [
        replace({
            preventAssignment: true,
            'process.env.NODE_ENV': JSON.stringify(env),
        }),
    ]

除此以外还有一个问题,NODE_ENV 并不是 node 的原生变量,而是开发者自定义的,就需要在 package.json 配置指令时,添加对应的环境变量。

// package.json
...
"scripts": {
    "dev": "set NODE_ENV=development rollup -wc rollup.config.js"
    "build": "set NODE_ENV=production rollup -c rollup.config.js"
}

但是,不同的环境使用环境变量的方式不尽相同,这时候就需要使用 cross-env 跨平台运行设置和使用环境变量,而不需要我们去为不同的平台和 shell 考虑。

npm install cross-env -D // 需要在 package.json 中使用,与项目绑定,因而需要安装为开发依赖

// package.json
...
"scripts": {
    "dev": "cross-env NODE_ENV=development rollup -wc rollup.config.js"
    "build": "cross-env NODE_ENV=production rollup -c rollup.config.js"
}

结语

至此才完成了一个可供线上线下环境使用的简单配置,另外,实际工作还需要根据环境变量的不同,在配置文件中使用不同的打包设置。以及根据项目的需要,去添加其他插件来补充功能,例如分包和引入 CSS 文件等。