🥇 Rollup 与 Webpack
Rollup官方解析:Rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,例如 library 或应用程序
webpack官方解析:webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
🥇 应用场景对比
使用Rollup的开源项目:
- vue
- vuex
- vue-router 使用webpack的项目:
- ElementUI
- mint-ui
- vue-cli
从上面使用场景可以大概分析出,Rollup 偏向应用于js库,webpack 偏向应用于前端工程,UI 库;
如果你的应用场景中只是 js 代码,希望做 ES 转换,模块解析,可以使用 Rollup。
如果你的场景中涉及到 css、html,涉及到复杂的代码拆分合并,建议使用 webpack。
🥇 安装和使用
初始化项目包:npm init
安装 rollup:npm i rollup -D
创建 rollup 配置文件:rollup.config.js
export default {
input: "", // 入口
output: {}, // 出口
plugins: [], // 各种插件使用的配置
external: [], // 外部依赖的配置
global: {}, // 全局变量的配置
};
🥇 入口的配置
Rollup 的入口配置的 key 同 webpack 的不同,Rollup 的入口是 input,而 webpack 是 entry。
🥈 单个入口配置
单个入口的配置只需要为 input 指定一个入口文件即可
export default {
input: "src/main.js", //
output: {
file:'dist/main.js' // 一个入口指定一个出口
},
};
🥈 多个入口配置
多个入口配置需要将导出的配置设置为数组,数组的项为一个对象,每一个对象都可以单独配置,例子如下:
export default [
{
input: "src/main1.js", // 入口 1
output: {
file: "dist/main-one.js", // 出口 1
},
},
{
input: "src/main2.js", // 入口 2
output: {
file: "dist/main-two.js", // 出口 2
},
},
];
🥇 出口的配置
出口的配置字段为 output,output 可以是一个对象也可以是一个数组,分别对应一个出口和多个出口。 出口配置的各字段解释:
- file:出口的地址以及打包的名字
- format:打包的格式,格式分为五种分别为:amd / es / cjs / iife / umd
- name:当 format 为 iife 和 umd 时必须提供,将作为全局变量挂在window(浏览器环境)下
- sourcemap:生成 main.map.js 文件,方便调试
- banner:为打包好的文件添加注释,注释的位置在整个文件的首行
- footer:为打包好的文件添加注释,注释的位置在整个文件的尾行
- intro:为打包好的文件添加注释,注释的位置在打包数据内容的头部
- outro:为打包好的文件添加注释,注释的位置在打包数据内容的末尾
注:banner、footer、intro、outro 可以不用配置在出口中,具体在后文中讲解。
🥈 单个出口配置
单个出口的配置需要将 output 指定为一个对象,对象的每一个 key 都是出口的配置。
export default {
input: "src/main.js",
output: {
file: "dist/main.js",
format: "es",
name: "A",
sourcemap: true,
banner: "// 文件的首行",
footer: "// 文件的尾行",
intro: "// 内容的头部",
outro: "// 内容的末尾",
},
};
🥈 多个出口配置
多出口配置需要将 output 配置设置为数组,数组的项为一个对象,每一个对象都可以单独配置,例子如下:
export default {
input: "src/main.js",
output: [
{
file: "dist/main1.js",
// ...
},
{
file: "dist/main2.js",
// ...
},
],
};
🥇 external 的配置
有些场景下,虽然我们使用了 resolve 插件,但可能我们仍然想要某些库保持外部引用状态,这时我们就需要使用 external 属性,来告诉 rollup.js 哪些是外部的类库。
import resolve from "@rollup/plugin-node-resolve";
export default {
input: "src/main.js",
output: {
file: "dist/main.js",
format: "es",
},
plugins: [resolve()],
external: ["the-answer"],
};
下图中我们通过 resolve 插件引入了一个外部库 the-answer 如果我们不通过 external 告诉 rollup 我们引入的库需要保持外部引入的话,rollup 会读取库的代码打包到我们的文件中,这样会造成文件过大。如果我们通过 external 告诉 rollup 的话,rollup 会将我们引入的库保持外部引入的状态打包。
🥇 global 属性
export default {
input: "src/main.js",
output: {
file: "dist/main.js",
format: "es",
},
global:{
"$":"jquery" // 告诉 rollup 全局指令 $ 就是 jquery
}
};
🥇 插件详解
请尽量使用官方插件:github.com/rollup/plug…
🥈 支持导入远程库
🥉 @rollup/plugin-node-resolve
安装:npm i -D @rollup/plugin-node-resolve
配置 rollup.config.js:
import resolve from "@rollup/plugin-node-resolve";
export default {
input: "src/main.js",
output: {
file: "dist/main.js",
format: "es",
},
plugins: [resolve()],
};
resolve 插件的作用
正常我们打包的对象是本地的 js 代码和库,但实际开发中,不太可能所有的库都位于本地,我们大多会通过 npm 下载远程的库。
与 webpack 和 browserify 这样的其他捆绑包不同,rollup 不知道如何打破常规去处理这些依赖。因此我们需要添加一些配置。
首先在我们的项目中添加一个依赖 jquery,然后修改 src/main.js 文件
import answer from "the-answer";
export default function () {
console.log("answer " + answer);
}
执行 npm run build 后会报如下错误
打包后的 main.js 仍然会在 Node.js 中工作,但是 jquery 不包含在包中。为了解决这个问题,将我们编写的源码与依赖的第三方库进行合并,rollup.js 为我们提供了 resolve 插件。
首先,安装 resolve 插件:npm i -D @rollup/plugin-node-resolve
修改配置文件 rollup.config.js:
import resolve from "@rollup/plugin-node-resolve";
export default {
input: "src/main.js",
output: {
file: "dist/main.js",
format: "es",
},
plugins: [resolve()],
};
再次打包就不会报错了
🥈 支持非es模块化
🥉 @rollup/plugin-commonjs
安装:npm i -D @rollup/plugin-commonjs
配置 rollup.config.js:
import commonjs from "@rollup/plugin-commonjs";
export default {
input: "src/main.js",
output: {
file: "dist/main.js",
format: "es",
},
plugins: [commonjs()],
};
commonjs 插件的作用
rollup.js 编译源码中的模块引用默认只支持 ES6+ 的模块方式 import/export。然而大量的 npm 模块是基于 CommonJS 模块方式,这就导致了大量 npm 模块不能直接编译使用。
因此使得 rollup.js 编译支持 npm 模块和 CommonJS 模块方式的插件就应运而生:@rollup/plugin-commonjs。
🥈 js兼容
🥉 @rollup/plugin-babel
安装:npm i -D @rollup/plugin-babel @babel/core @babel/preset-env
安装 @rollup/plugin-babel 后,在安装 @babel/core,因为 @babel/core 是 babel 的核心,都安装好以后创建一个 .babelrc 文件,用于配置 babel,我们看.babelrc配置了preset env,所以要安装这个插件,都安装成功后,babel 插件才可以正常工作。
// .babelrc
{
"presets": [
[
"@babel/preset-env",
{
"modules": false, // 将此设置为 false 将保留 ES 模块。 仅当您打算将本机 ES 模块发送到浏览器时才使用此选项。
"useBuiltIns": "usage", // @babel/preset-env 编译新的 API 使用 core-js 这个库需要安装 corejs 库, 默认使用 core-js2 版本的库
"corejs": 3 // 告诉 @babel/preset-env 使用 corejs3 版本
}
]
]
}
配置 rollup.config.js:
import babel from "@rollup/plugin-babel";
export default {
input: "src/main.js",
output: {
file: "dist/main.js",
format: "es",
},
plugins: [
babel({
exclude: "node_modules/**", // 排除 node_modules 文件夹下的文件
}),
],
};
babel 插件的作用
Babel:www.babeljs.cn/docs/
Babel 是一个工具链,主要用于将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。
🥉 rollup-plugin-buble
安装:npm i -D rollup-plugin-buble
配置 rollup.config.js:
import buble from "rollup-plugin-buble";
export default {
input: "src/main.js",
output: {
file: "dist/main.js",
format: "es",
},
plugins: [buble()],
};
🥈 支持导入json
🥉 @rollup/plugin-json
安装:npm i -D @rollup/plugin-json
配置 rollup.config.js:
import json from "@rollup/plugin-json";
export default {
input: "src/main.js",
output: {
file: "dist/main.js",
format: "es",
},
plugins: [json()],
};
json 插件的作用
没有 json 插件的支持我们在导入 json 文件时会报错,所以需要安 json 插件来支持 json 文件的导入
[!] Error: Unexpected token (Note that you need @rollup/plugin-json to import JSON files)
// [!] Error: Unexpected token (注意你需要 @rollup/plugin-json 来导入JSON文件)
🥈 支持别名
🥉 rollup-plugin-alias
安装:npm i -D rollup-plugin-alias
配置 rollup.config.js:
import alias from "rollup-plugin-alias";
const path = require("path");
const pathResolve = (p) => path.resolve(__dirname, p);
export default {
input: "src/main.js",
output: {
file: "dist/main.js",
format: "es",
},
plugins: [
alias({
resolve: [".jsx", ".js"], // 可选,默认情况下这只会查找 .js 文件或文件夹
entries: {
"@": pathResolve("src"),
_: __dirname,
},
}),
],
};
alias 插件的作用
alias 插件提供了为模块起别名的功能,用过 webpack 的应该对这个功能非常熟悉
🥈 代码压缩
🥉 rollup-plugin-terser
安装:npm i -D rollup-plugin-terser
配置 rollup.config.js:
import { terser } from "rollup-plugin-terser";
export default {
input: "src/main.js",
output: {
file: "dist/main.js",
format: "es",
},
plugins: [terser()],
};
🥈 代码检查
🥉 rollup-plugin-eslint
安装:npm i -D rollup-plugin-eslint
另外,需要创建 .eslintrc 文件配置 eslint 规则
// .eslintrc
module.exports = {
root: true,
parserOptions: {
"ecmaVersion": 6, // 支持es6
"sourceType": "module" // 使用 es6 模块化
},
env: { // 设置环境
"browser": true, // 支持浏览器环境: 能够使用window上的全局变量
"node": true // 支持服务器环境: 能够使用node上global的全局变量
},
extends: : "eslint:recommended", // 使用 eslint 推荐的默认规则 https://cn.eslint.org/docs/rules/
globals: { // 声明使用的全局变量, 这样即使没有定义也不会报错了
"$": "readonly" // $ 只读变量
},
rules: { // eslint检查的规则 0 忽略 1 警告 2 错误
"no-console": 0, // 不检查 console
"eqeqeq": 2, // 用 == 而不用 === 就报错
"no-alert": 2 // 不能使用 alert
},
}
配置 rollup.config.js:
import eslint from "rollup-plugin-eslint";
export default {
input: "src/main.js",
output: {
file: "dist/main.js",
format: "es",
},
plugins: [
eslint({
include:['src/**/*.js'] // 需要检查的部分
})
],
};
🥈 热更新
🥉 rollup-watch
安装:npm i -D rollup-watch
配置 package.js:
"scripts": {
"dev": "rollup -c -w",
},
🥈 开启本地服务器
🥉 rollup-plugin-serve
安装:npm i -D rollup-plugin-serve
配置 rollup.config.js:
import serve from "rollup-plugin-serve";
export default {
input: "src/main.js",
output: {
file: "dist/main.js",
format: "es",
},
plugins: [
serve({
open: true, // 是否打开浏览器
contentBase: "./", // 入口 html 文件位置
historyApiFallback: true, // 设置为 true 返回 index.html 而不是 404
host: "localhost", //
port: 3000 // 端口号
})
],
};
🥈 实时刷新页面
🥉 rollup-plugin-livereload
安装:npm i -D rollup-plugin-livereload
实时刷新页面,配合 rollup-plugin-serve 使用
配置 rollup.config.js:
import serve from "rollup-plugin-serve";
import livereload from "rollup-plugin-livereload";
export default {
input: "src/main.js",
output: {
file: "dist/main.js",
format: "es",
},
plugins: [
serve({
open: true, // 是否打开浏览器
contentBase: "./", // 入口 html 文件位置
historyApiFallback: true, // 设置为 true 返回 index.html 而不是 404
host: "localhost", //
port: 3000 // 端口号
}),
livereload()
],
};
🥈 删除调试器语句和函数
🥉 @rollup/plugin-strip
安装:npm install @rollup/plugin-strip --save-dev
实时刷新页面,配合 rollup-plugin-serve 使用
配置 rollup.config.js:
import strip from "@rollup/plugin-strip";
export default {
input: "src/main.js",
output: {
file: "dist/main.js",
format: "es",
},
plugins: [
strip({
exlude: "node_modules/**",
}),
],
};