什么是 ROLLUP?
rollup自称自己是下一代的 JavaScript 模块打包工具。
至于后面会有什么高级的打包工具我们先不管,在这个大前端时代,当你使用 ES2015 模块来编写你的者库时,rollup通过 Tree-shaking 技术,抽取式打包代码我们的js文件到一个单独的文件确实当下比较好的选择了。我也尝试过使用webpack来打包,但是要求严格(挑剔)的大家肯定会对下面的打包代码不满意:
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
webpack打包会对我们的代码添加一些它自己的代码,不像平时看到的jQuery和Vue源码那样干净、简洁,所以为了追随大佬的步伐(为了装逼),我选择rollup:
废话有点多,下面开始打包构建(装逼)
1、全局安装rollup,创建自己的项目目录(基本操作,坐下坐下)
npm install -g rollup
mkdir my-rollup-project
cd my-rollup-project
npm create -y
2、编写我们的js文件,这里我尽量使用es6的一些新属性,以便看到打包效果
/* /src/index.js */
import {inBrowser,classListSupport} from './config';
import "core-js/modules/es.promise";
const foo = x => x + 2;
console.log(inBrowser);
console.log(classListSupport);
foo(2);
class Super {
constructor(){
this.author = 'Yang lin';
this.version = '1.0.0';
}
sayAuhtor(){
console.log(this.author);
}
delay(times){
return new Promise(resolve => {
const timer = setTimeout(() => {
resolve();
},times);
});
}
update(version){
this.version = version;
}
}
export default Super;
config.js我就不展示出来了,只是为了使用这种模块引入功能
3、打开rollup文档,开始我们的打包之旅,这里我们使用配置文件来进行打包,毕竟命令容易出错,还不好维护。在build目录下创建我们的打包配置
/* /build/build.js */
import buble from 'rollup-plugin-buble';//在rollup.js打包的过程中进行代码编译,将ES6+代码编译成ES2015标准
import flow from 'rollup-plugin-flow-no-whitespace';//去除flow静态类型检查代码
import commonjs from 'rollup-plugin-commonjs';//这两个插件可以让你加载Node.js里面的CommonJS模块
import node from 'rollup-plugin-node-resolve';//这两个插件可以让你加载Node.js里面的CommonJS模块
import babel from 'rollup-plugin-babel';//打包的时候使用Babel
import {uglify} from 'rollup-plugin-uglify';//压缩、美化js文件
const path = require('path');
const resolve = _path => path.resolve(__dirname,'../',_path);
const version = process.env.VERSION || require('../package.json').version;
const banner =
`/* !
* library v${version}
* https://github.com/ (github address)
*
* (c) ${new Date().getFullYear()} Zoro
*/
`;
const outputs = [{
file: resolve('dist/bundle.js'),
format: 'umd',
env: 'development'
},{
file: resolve('dist/bundle.min.js'),
format: 'umd',
env: 'production'
},{
file: resolve('dist/bundle.common.js'),
format: 'cjs'
},{
file: resolve('dist/bundle.esm.js'),
format: 'es'
}];
function buildRollupConfig(output){
let config = {
input: resolve('src/index.js'),
plugins: [
flow(),
node(),
commonjs(),
buble(),
babel({
extensions: [".js"],
runtimeHelpers: true,
exclude: ["node_modules/**"]
})
],
output: {
file: output.file,
format: output.format,
banner,
name: 'library'
}
};
if(output.env && output.env.includes('prod')){
config.plugins.push(uglify());
}
return config;
}
export default outputs.map(buildRollupConfig);
这里我也尝试过使用rollup.rollup的api来进行打包,像vueRoute一样,但是总是失败,code总是返回undefiend。大家可以试试
const { code, map } = await bundle.generate(outputOptions);
4、接下来就是安装依赖和配置命令了
npm i -D rollup-plugin-babel rollup-plugin-buble rollup-plugin-commonjs rollup-plugin-flow-no-whitespace rollup-plugin-node-resolve rollup-plugin-uglify uglify-js
{
"name": "my-rollup-project",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rollup -c build/build.js",
"dev": "rollup -w -c build/build.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"rollup-plugin-babel": "^4.3.2",
"rollup-plugin-buble": "^0.19.6",
"rollup-plugin-commonjs": "^9.3.4",
"rollup-plugin-flow-no-whitespace": "^1.0.0",
"rollup-plugin-node-resolve": "^4.1.0",
"rollup-plugin-uglify": "^6.0.2",
"uglify-js": "^3.5.3"
}
}
然后运行一下,what?
好吧,我装,我装
npm i -D @babel/core
在运行一下,哈哈,成功了
/* !
* library v1.0.0
* https://github.com/ (github address)
*
* (c) 2019 Zoro
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.library = factory());
}(this, function () { 'use strict';
var inBrowser = typeof window !== 'undefined';
var tempDiv = document.createElement('div');
var classListSupport = 'classList' in tempDiv;
tempDiv = null;
/* /src/index.js */
console.log(inBrowser);
console.log(classListSupport);
var Super = function Super() {
this.author = 'Yang lin';
this.version = '1.0.0';
};
Super.prototype.sayAuhtor = function sayAuhtor() {
console.log(this.author);
};
Super.prototype.delay = function delay(times) {
return new Promise(function (resolve) {
var timer = setTimeout(function () {
resolve();
}, times);
});
};
Super.prototype.update = function update(version) {
this.version = version;
};
return Super;
}));
完美,有没有,但是,为什么我们的promise没有被转换,这里就要添加.babelrc配置文件,然后安装babel预设依赖
npm i -D @babel/preset-env @babel/polyfill
添加.babelrc文件,并配置(参考文档:babel-preset-env):
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"browsers": "last 10 versions, > 1%, ie >= 9, Android >= 4.4, iOS >= 8",
"node": "current"
},
"modules": false,
"useBuiltIns": "entry"
}
]
],
"ignore": [ "node_modules" ]
}
然后在入口文件中引入promise的pollfill,运行
这里引入后打包文件就变得很大了,所以大家自行舍取;
最后项目代码参考github地址
参考文章: