本文档地址javascript
本文引用参考文档地址html
Rollup 是一个 JavaScript 模块打包器,能够将小块代码编译成大块复杂的代码,例如 library 或应用程序。java
Rollup 对代码模块使用新的标准化格式,这些标准都包含在 JavaScript 的 ES6 版本中,而不是之前的特殊解决方案,如 CommonJS 和 AMD。ES6 模块可使你自由、无缝地使用你最喜好的 library 中那些最有用独立函数,而你的项目没必要携带其余未使用的代码。ES6 模块最终仍是要由浏览器原生实现,但当前 Rollup 可使你提早体验。node
Rollup
着眼于将来,采用原生的ES
标准的模块机制进行构建,将来ES
规范确定会由浏览器实现,也是JavaScript语言明确的发展方向。机制更加优于CommonJS
webpack
CommonJS
是在ES
规范以前被提出的一种暂时性性解决方案,是一种特殊的传统格式,git
相比较ES
模块容许进行静态分析,从而实现像 tree-shaking 的优化,并提供诸如循环引用和动态绑定等高级功能github
Tree-shaking
, 也被称为 "live code inclusion," 它是清除实际上并无在给定项目中使用的代码的过程,可是它能够更加高效。web
打包工具 | 体积 | 注入代码 | code spliting | dynamic import | Tree-shaking |
---|---|---|---|---|---|
webpack | large | more | ✅ | ✅ | ❌ |
rollup | small | less | ❌ | ❌ | ✅ |
webpack 是一款强大的 bundle
构建工具,经过 loader
机制能够处理各类类型的文件,良好的 code splitting
和dynamic import
支持使得webpack
成为了应用程序,单页应用的全能型的的打包工具。npm
可是由于其打包体积相对较大,注入代码更多,没有良好的Tree-shaking
因此在Library
的打包工做中,不如rollup
打包的精简。json
rollup
定位是一款轻量级的构建工具,其配置也相对很简单,可是因为不支持CommonJs
,在配置rollup-plugin-commonjs
将CommmonJS
转化成ES
模块方式的时候,须要配置babel
转译
因为babel 7+
升级改动比较大,命名空间改动,市面上的教程大部分说的不够清楚,并且基本上停留在babel 6
的配置,致使一直抛(plugin commonjs) SyntaxError: Unexpected token
在后文中会着力介绍这个部分,分析babel 7+
配置以及各个presets
和plugins
的做用。
npm install --save-dev rollup
复制代码
在项目根目录建立rollup.config.js
文件。
rollup
配置比较的简洁,通常包括input
,output
,plugins
,external
这是一段简单的配置文件
export default {
input: 'src/index.js',
output: {
name: 'amapUpper',
file: 'dist/amapUpper.js',
format: 'umd' //兼容模式
},
external: ['@amap/amap-jsapi-loader'],// 配置引入的包是否要打包,在这里配置的会忽略掉,不打包到咱们的程序里面
plugins: []
};
复制代码
当你的配置文件须要配置多个打包策略的时候,你还能够这样配置
export default [{
input: 'main-a.js',
output: {
file: 'dist/bundle-a.js',
format: 'cjs'
}
}, {
input: 'main-b.js',
output: [
{
file: 'dist/bundle-b1.js',
format: 'cjs'
},
{
file: 'dist/bundle-b2.js',
format: 'es'
}
]
}]
复制代码
你还可使用多个配置文件,使用--config
来使用配置文件
# pass a custom config file location to Rollup
rollup --config my.config.js
复制代码
::: danger 使用了umd
模式必须指定 Name for UMD export
:::
配置gollup 的plugin 相似babel 所有移植到了@rollup
下,在官方提供的 一站式配置商店,能够下载所需的插件, 做用在于可维护学习被误导成本下降,更有利于长期维护。
rollup plugin
是一个遵循rollup
插件规范的object
,通常经过一个工厂函数返回一个对象实现
一段简单的示例:
export default function myExample () {
return {
name: 'my-example', // this name will show up in warnings and errors
resolveId ( source ) {
if (source === 'virtual-module') {
return source; // this signals that rollup should not ask other plugins or check the file system to find this id
}
return null; // other ids should be handled as usually
},
load ( id ) {
if (id === 'virtual-module') {
return 'export default "This is virtual!"'; // the source code for "virtual-module"
}
return null; // other ids should be handled as usually
}
};
}
复制代码
而后在配置文件中引用该插件,在plugins中,传入执行返回的对象
import myExample from 'myExample'
plugins: [ myExample() ]
复制代码
A Rollup plugin is an object with one or more of the properties
, build hooks
, and output generation hooks
熟悉webpack loader
机制的都应该知道loader
其实是从右到左,自下而上执行的,在页头的 rollup打包js的注意点 里面提到的错误记录/错误2里面,类比webpack loader
机制, 实际上是一个错误的类比,实际上rollup
的plugin
机制是从左往右,自上而下而下的执行顺序。
一个测试例子
// rollup.config.js
function myExample1() {
return {
name: 'my-example1', // this name will show up in warnings and errors
resolveId(source) {
console.log('111 resolve_______________-------------------------------------------');
return null; // other ids should be handled as usually
},
load(id) {
console.log('111 load_______________-------------------------------------------');
return null; // other ids should be handled as usually
}
};
}
function myExample2() {
return {
name: 'my-example1', // this name will show up in warnings and errors
resolveId(source) {
console.log('222 resolve_______________-------------------------------------------');
return null; // other ids should be handled as usually
},
load(id) {
console.log('222 load_______________-------------------------------------------');
return null; // other ids should be handled as usually
}
};
}
export default {
input: 'src/index.js',
output: {
name: 'test',
file: 'dist/test.js',
format: 'umd'
},
plugins: [
myExample1(),
myExample2()
]
};
复制代码
能够看到load
,resolve
钩子函数都是从左往右,自上而下而下的执行顺序。
下面介绍正常打包中须要用到的插件,和通常配置。
@rollup/plugin-json
原rollup-plugin-json
@rollup/plugin-commonjs
原rollup-plugin-commonjs
@rollup/plugin-node-resolve
原rollup-plugin-node-resolve
rollup-plugin-terser
首先,须要做为开发依赖安装这些插件
npm i @rollup/plugin-json -D
npm i @rollup/plugin-commonjs -D
npm i @rollup/plugin-node-resolve -D
npm i rollup-plugin-terser -D
复制代码
而后须要引用配置文件
import json from '@rollup/plugin-json';
import commonjs from '@rollup/plugin-commonjs';
import nodeResolve from '@rollup/plugin-node-resolve';
import babel from 'rollup-plugin-babel';
import { terser } from 'rollup-plugin-terser';
export default {
...
plugins: [
json(),
terser(),
nodeResolve(),
commonjs(),
babel({
exclude: '*', // 排除node_modules 下的文件
runtimeHelpers: true // 防止生成多个 打包helper 函数
}),
]
};
复制代码
在跟着 rollup 搭建打包 JS 一文配置的过程当中,用到的插件不是官方一站式插件提供的长期维护版本,遇到了 rollup-plugin-commonjs
插件打包报错的问题
针对使用了放弃维护的rollup-plugin-commonjs
插件的打包抛出的这个SyntaxError
,能够有两种解决方案。推荐方案二。
查找了不少资料都显示,应该是babel
配置问题,主要分为:
babel
配置问题babel
转译执行顺序问题综合这些资料,这个报错应该是因为该commonjs 插件库 被移动到 @rollup/plugin-commonjs
下维护,致使非长期维护版本缺乏某些转译后的辅助函数,属性,致使抛出异常。
因此须要babel
辅助编译以后才能正确执行commonjs
插件。
babel 配置的一些问题
因为babel 7+
版本中,将babel 的各个库所有移植到了@babel/***
下统一官方维护,而市面上大部分的babel
教程实际上没有对这点进行详细说明,并且教程里安装babel
组件的时候并无指定版本,实际上致使可能安装了7+ 版本的babel
核心库,而安装了放弃维护的babel-plugins-***
下的插件预设之类的。就会致使一系列的问题。
这里要注意一下这个@
这个符号,这个是只有babel7
才特有的,babel6
都木有,市面上大量代码都是基于6的因此要特别注意,安装的时候要使用 npm install i -S @babel\cli
而不能是npm install i -S babel-cli
了 这是 babel 7
的一大调整,原来的 babel-xx
包统一迁移到babel
域 下 - 域由 @
符号来标识
参阅文章开头提到的 babel 7 的使用的我的理解
配置
因为这里使用@rollup/plugin-babel
,执行babel
转译 因此不须要安装@babel/cli
命令行工具。
首先咱们须要安装:
@babel/core
@babel/preset-env
@babel/runtime
@babel/plugin-transform-runtime
npm i -D @babel/core
npm i -D @babel/preset-env
npm i -D @babel/runtime
npm i -D @babel/plugin-transform-runtime
复制代码
而后在项目根目录下建立.babelrc
的配置文件
{
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"targets": {
"browsers": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
}
]
],
"plugins": ["@babel/plugin-transform-runtime"]
}
复制代码
而后若是你用的是rollup-plugin-commonjs
很是期维护版本的插件的话,因为和babel
有依赖关系,你须要:
在commonjs
插件以前引入babel
插件,并配置须要匹配编译的文件,目录。和编译配置
// rollup.config.js
export default {
input: 'src/index.js',
output: {
name: 'amapUpper',
file: 'dist/amapUpper.js',
format: 'umd'
},
plugins: [
babel({
exclude: '/node_modules/**', // 排除node_modules 下的文件
runtimeHelpers: true // 与plugin-transform-runtime 插件对应配置,生成统一化helper。
}),
commonjs()
]
};
复制代码
使用rollup
新的官方提供的移动后的一站式插件库里面的插件
使用了新的插件库以后,babel
仍是须要配置的,只是解决了commonjs
插件依赖babel
的问题。
而babel 其实是解决各类浏览器,引擎之间的差别,而存在的。因此为了更好的支持,须要配备良好的babel配置。
欢迎各位看官大佬们点赞,纠错。