Rollup
rollup是一款小巧的javascript模块打包工具,更适合于库应用的构建工具;可以将小块代码编译成大块复杂的代码,基于ES6 modules,自动进行 Tree-shaking,它可以让你的 bundle 最小化,有效减少文件请求大小。
全局安装
npm install --global rollup
命令行
//该命令编译 main.js 生成 bundle.js, --format cjs 意味着打包为 node.js 环境代码
rollup --input main.js --output bundle.js --format cjs
-i, --input <filename> 要打包的文件(必须)
-o, --file <output> 输出的文件 (如果没有这个参数,则直接输出到控制台)
-f, --format <format> 输出的文件类型 (amd, cjs, esm, iife, umd)
-e, --external <ids> 将模块ID的逗号分隔列表排除
-g, --globals <pairs> 以`module ID:Global` 键值对的形式,用逗号分隔开
任何定义在这里模块ID定义添加到外部依赖
-n, --name <name> 生成UMD模块的名字
-h, --help 输出 help 信息
-m, --sourcemap 生成 sourcemap (`-m inline` for inline map)
--amd.id AMD模块的ID,默认是个匿名函数
--amd.define 使用Function来代替`define`
--no-strict 在生成的包中省略`"use strict";`
--no-conflict 对于UMD模块来说,给全局变量生成一个无冲突的方法
--intro 在打包好的文件的块的内部(wrapper内部)的最顶部插入一段内容
--outro 在打包好的文件的块的内部(wrapper内部)的最底部插入一段内容
--banner 在打包好的文件的块的外部(wrapper外部)的最顶部插入一段内容
--footer 在打包好的文件的块的外部(wrapper外部)的最底部插入一段内容
--interop 包含公共的模块(这个选项是默认添加的)
format
选项
rollup提供了五种选项:
amd
– 异步模块定义,用于像RequireJS这样的模块加载器cjs
– CommonJS,适用于 Node 和 Browserify/Webpackes
– 将软件包保存为ES模块文件iife
– 一个自动执行的功能,适合作为<script>
标签。(如果要为应用程序创建一个捆绑包,您可能想要使用它,因为它会使文件大小变小。)umd
– 通用模块定义,以amd
,cjs
和iife
为一体
使用配置文件
rollup.config.js
const rollup = require("rollup");
// rollup plugin to convert JSON files to ES6 modules
const json = require("rollup-plugin-json");
//Bundle third-party dependencies in node_modules
const resolve = require("rollup-plugin-node-resolve");
//Convert CommonJS modules to ES2015
const commonjs = require("rollup-plugin-commonjs");
const babel = require("rollup-plugin-babel");
const eslint = require("rollup-plugin-eslint").eslint;
const filesize = require("rollup-plugin-filesize");
export default {
input: 'src/main.js',
//打包时不进行导入的类库,这些类库采用在外部引用的方式
//名称为 package.json -> devDependencies中依赖类库的key值
external: ["jquery"],
output: {
file: 'bundle.js',
format: 'iife',
name:'',//当format为iife和umd时必须提供,生成包名称,代表你的iife/umd包
banner:'',
footer:'',
intro:'',
outro:'',
sourcemap:true,
//告诉rollup 全局变量jQuery即是jquery
globals: {
"jquery": "jQuery"
}
},
plugins:[
json(),
resolve(),
eslint(),
commonjs(),
filesize(),
babel({
exclude: "node_modules/**",
runtimeHelpers: true,
plugins: []
}),
]
};
执行 rollup -c
可以指定与默认 rollup.config.js
文件不同的配置文件:
rollup --config rollup.config.dev.js
rollup --config rollup.config.prod.js
使用rollup插件
rollup-plugin-alias
: 提供modules名称的 alias 和reslove 功能rollup-plugin-babel
: 提供babel能力rollup-plugin-buble
:编译ES6+语法为ES2015,无需配置,比babel更轻量;rollup-plugin-eslint
: 提供eslint能力rollup-plugin-node-resolve
: 解析 node_modules 中的模块rollup-plugin-commonjs
: 转换 CJS -> ESM, 通常配合上面一个插件使用,加载Node.js里面的CommonJS模块rollup-plugin-serve
: 类比webpack-dev-server
, 提供静态服务器能力rollup-plugin-filesize
: 显示 bundle 文件大小rollup-plugin-uglify
: 压缩 bundle 文件rollup-plugin-terser
:代码压缩,取代uglify,支持ES模块。rollup-plugin-replace
::替换代码中的变量为指定值。 类比 Webpack 的 DefinePlugin , 可在源码中通过 process.env.NODE_ENV 用于构建区分 Development 与 Production 环境.
使用 .browserslistrc
browserslist叫做目标环境配置表,除了写在package.json里,也可以单独写在工程目录下.browserslistrc文件里。我们用browserslist来指定代码最终要运行在哪些浏览器或node.js环境。Autoprefixer、postcss等就可以根据我们的browserslist,来自动判断是否要增加CSS前缀(例如’-webkit-‘)。我们的Babel也可以使用browserslist,如果你使用了@babel/preset-env这个预设,此时Babel就会读取browserslist的配置。
如果我们的@babel/preset-env不设置任何参数,Babel就会完全根据browserslist的配置来做语法转换。如果没有browserslist,那么Babel就会把所有ES6的语法转换成ES5版本。
chrome 58
ie 11
使用babel
Babel默认只转换JS语法,而不转换新的API,比如Iterator
、Generator
、Set
、Maps
、Proxy
、Reflect
、Symbol
、Promise
等全局对象,以及一些定义在全局对象上的方法(比如Object.assign
)都不会转码。
举例来说,ES2015在Array对象上新增了Array.from
方法。Babel 就不会转码这个方法。如果想让这个方法运行,必须使用babel-polyfill
。(内部集成了core-js
和regenerator
)
.babelrc
使用 transform-runtime
@babel/runtime
在 babel 7.4 之后大放异彩, 利用 corejs 3 也实现了各种内置对象的支持, 并且依靠 @babel/plugin-transform-runtime
的能力,沙箱垫片和代码复用, 避免帮助函数重复 inject 过多的问题, 该方式的优点是不会污染全局, 适合在类库开发中使用
要使用@babel/plugin-transform-runtime
插件,其实只有一个npm包是必须要装的,那就是它自己@babel/plugin-transform-runtime
。
对于@babel/runtime
及其进化版@babel/runtime-corejs2
、@babel/runtime-corejs3
,我们只需要根据自己的需要安装一个。
{
"presets": [
[
"@babel/env",
{
"targets": {
//"browsers": "last 2 versions",
"chrome": "58",
"ie": "10"
},
//设置"modules": false,否则 Babel 会在 Rollup 有机会做处理之前,将我们的模块转成 CommonJS,导致 Rollup 的一些处理失败
"modules": false
}
]
],
"plugins": [
//将regeneratorRuntime打包进代码中,如 async/await 等es6-8特性
//需要安装 @babel/runtime @babel/runtime-corejs2 @babel/runtime-corejs3
["@babel/plugin-transform-runtime",{
"corejs":2
}]
]
}
使用 polyfill
使用 babel-polyfill
后,可以使用内置对象如 Promise
、WeakMap
,静态方法如 Array.from
、Object.assign
,实例方法如 Array.prototypes.includes
以及 generator
函数
@babel/preset-env 拥有根据 useBuiltIns 参数的多种polyfill实现,优点是覆盖面比较全(entry), 缺点是会污染全局, 推荐在业务项目中使用
- entry 的覆盖面积全, 但是打包体积自然就大,
- useage 可以按需引入 polyfill, 打包体积就小, 但如果打包忽略node_modules 时如果第三方包未转译则会出现兼容问题
{
"presets": [
[
"@babel/env",
{
"modules": false,
"useBuiltIns": "usage"
}
]
]
}
.eslintrc.js
module.exports = {
extends: "standard",
env: {
"browser": true,
"es6": true
},
rules: {
"semi": ["error", "always"]
}
};
gulp
const gulp = require("gulp");
const concat = require("gulp-concat");
const sourcemaps = require("gulp-sourcemaps");
const plumber = require("gulp-plumber");
const rollup = require("rollup");
// rollup plugin to convert JSON files to ES6 modules
const json = require("rollup-plugin-json");z+
//Bundle third-party dependencies in node_modules
const resolve = require("rollup-plugin-node-resolve");
//Convert CommonJS modules to ES2015
const commonjs = require("rollup-plugin-commonjs");
const babel = require("rollup-plugin-babel");
const eslint = require("rollup-plugin-eslint").eslint;
const filesize = require("rollup-plugin-filesize");
gulp.task("js", async function () {
const bundle = await rollup.rollup({
input: "./src/js/index.js",
//告诉rollup不要将jquery打包,而作为外部依赖
external: [
"jquery",
"crypto-js/core"
],
/**
* rollup-plugin-alias: 提供modules名称的 alias 和reslove 功能
* rollup-plugin-babel: 提供babel能力
* rollup-plugin-eslint: 提供eslint能力
* rollup-plugin-node-resolve: 解析 node_modules 中的模块
* rollup-plugin-commonjs: 转换 CJS -> ESM, 通常配合上面一个插件使用
* rollup-plugin-serve: 类比 webpack-dev-server, 提供静态服务器能力
* rollup-plugin-filesize: 显示 bundle 文件大小
* rollup-plugin-uglify: 压缩 bundle 文件
* rollup-plugin-replace: 类比 Webpack 的 DefinePlugin , 可在源码中通过 process.env.NODE_ENV 用于构建区分 Development 与 Production 环境.
*/
plugins: [
//rollupTypescript()
json(),
resolve(),
eslint(),
commonjs(),
filesize(),
babel({
exclude: "node_modules/**",
runtimeHelpers: true,
plugins: []
}),
]
});
const banner = `/*!
* WSFileUpload 1.00.1
* Licensed under ISC
* Please visit https:// for details.
*/`;
await bundle.write({
file: "./dist/ws-fileupload.js",// 文件输出目录
globals: {//告诉rollup 全局变量jQuery即是jquery
"jquery": "jQuery",
"crypto-js/core": "CryptoJS"
},
/**
* amd – 异步模块定义,用于像RequireJS这样的模块加载器
* cjs – CommonJS,适用于 Node 和 Browserify/Webpack
* es – 将软件包保存为ES模块文件
* iife – 一个自动执行的功能,适合作为<script>标签。(如果要为应用程序创建一个捆绑包,您可能想要使用它,因为它会使文件大小变小。)
* umd – 通用模块定义,以amd,cjs 和 iife 为一体
*/
format: "iife", // 格式,amd(异步模块定义),cjs(commonjs),es(将软件包保存为es模块文件),iife(适合作为<script>标签),umd(以amd、cjs、iife为一体)
name: "WSFileUpload",//当format为iife和umd时必须提供,生成包名称,代表你的iife/umd包
sourcemap: true,
banner: banner,
footer: "/* follow me on github! */",
intro: "",
});
});