前言
web工程化工具技术是前端比较重要的一部分,对于初级往高级走,无论是项目架构还是项目开发web工程化是无法避开的一个重要环境,因此我们一起来探索web工程化工具技术,本篇文章内容参考网络,如有错误欢迎在评论区告诉我。
rollup
与Webpack偏向于应用打包的定位不同,rollup.js更专注于Javascript类库打包。所以我们可以简单的理解 webpack用于打包应用,rollup用于打包类库如vue、react还有我的easyfront.js(我的easyfront.js用的是webpack打包,当时没有了解过rollup)。
为什么webpack打包应用rollup打包类库
rollup对于代码的Tree-shaking和ES6模块有着算法优势上的支持,打包一个简单的bundle包(就是一个 JavaScript 文件),并是基于ES6模块开发的,生成的文件更小。
webpack对于代码分割和静态资源导入有比较好的支持,并且支持热模块替换(HMR),而rollup并不支持,所以webpack更适合打包应用。
随着webpack的升级,从2.0开始就已经支持Tree-shaking,并在使用babel-loader的情况下还可以支持es6 module的打包,rollup渐渐失去优势,但是因为rollup的API较为简单,还是挺适合打包类库的。
rollup的简单使用
全局安装rollup
npm install --global rollup
构建一个目录,学习vue项目打包的结构自定义项目结构,比如dist是打包后的文件,public放置引用或测试的html文件或静态文件,src则放置脚本文件以及组成各个脚本的包(bundle)。
├─dist
│ index.js
│
├─public
└─src
│ index.js
│
└─components
test.js
src/index.js
import test from "./components/test"
test()
console.log('使用rollup')
src/components/test.js
export default function() {
console.log("test模块")
}
使用命令
使用命令把src下的入口文件index.js把项目打包成一个文件。
rollup src/index.js -f umd -o dist/index.js
打包后的文件代码,dist/index.js
(function (factory) {
typeof define === 'function' && define.amd ? define(factory) :
factory();
})((function () { 'use strict';
function test(){
console.log("test模块");
}
test();
console.log('使用rollup');
}));
使用配置文件
在项目根目录创建rollup.config.js
文件。
export default {
input: ["./src/index.js"],
output: {
file: "./dist/index.js",
format: "umd",
name: "experience",
},
}
打包的时候执行下列命令就开始进行打包。
rollup -c
插件
实际开发中,我们大多会通过npm下载远程的库,方便我们开发。
为了方便,我将原本的
rollup -c -w
添加到了package.json
的scripts
中:"serve": "rollup -c -w"
。
安装插件
rollup/plugin-node-resolve插件
使用节点解析算法定位模块,可以告诉 Rollup 如何查找外部模块。
rollup-plugin-commonjs插件
由于node_modules文件夹中的大多数包可能是旧版CommonJS而不是JavaScript模块所以还需要rollup-plugin-commonjs
将 CommonJS 模块转换为 ES6,以便它们可以包含在汇总捆绑包。
Babel插件
为了实现浏览器兼容,还可能需要引入Babel
。Babel
是一个工具链,主要用于在当前和较旧的浏览器或环境中将 ECMAScript 2015+
代码转换为向后兼容的 JavaScript
版本。
@rollup/plugin-json插件
为了能够引入json文件,可能还需要引入@rollup/plugin-json
。
npm install @rollup/plugin-node-resolve
npm install rollup-plugin-commonjs
npm install rollup-plugin-babel
npm install @rollup/plugin-json
npm install @babel/core
npm install @babel/preset-env
npm install @babel/preset-env
修改配置文件
修改rollup.config.js
文件。
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import babel from 'rollup-plugin-babel';
import json from '@rollup/plugin-json';
export default {
input: ["./src/index.js"],
output: {
file: "./dist/index.js",
format: "umd",
name: "experience",
},
plugins: [
resolve(),
commonjs(),
babel(),
json()
],
external: ["moment"]
}
在根目录新建.babelrc
文件配置babel。
{
"presets": [
[
"@babel/preset-env",
{
"modules": false,
// "useBuiltIns": "usage"
}
]
]
}
编写测试代码
此处随意测试引入一个Moment.js库,使用es6语法。
import test from "./components/test"
import moment from 'moment'
import testJson from './json/test.json'
console.log(moment().format())
test()
console.log(()=>{
return '1212'
})
console.log(testJson)
console.log('使用rollup')
执行命令发现可以正常打包。
npm run serve
打包后的代码
注意,为了展示我们所编写的代码是被打包成什么样子,此处我加了外部引入标识moment.js是由外部引入,因此不会打包进此文件。可以看到箭头函数被转换为了function,说明babel插件正常工作。
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('moment')) :
typeof define === 'function' && define.amd ? define(['moment'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.moment));
})(this, (function (moment) { 'use strict';
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
function test () {
console.log("test模块");
}
var name = "xiaoxi";
var testJson = {
name: name
};
console.log(moment__default["default"]().format());
test();
console.log(function () {
return '1212';
});
console.log(testJson);
console.log('使用rollup');
}));
tree-shaking
原理
tree shaking 是一种采用删除不需要的额外代码的方式优化代码体积的技术。
利用ES6模块特性
- 只能作为模块顶层的语句出现
- import的模块名只能是字符串常量
- 引入的模块不能再进行修改
代码删除
- uglify:判断程序流,判断变量是否被使用和引用,进而删除代码
实现原理可以简单的概况
ES6 Module引入进行静态分析,故而编译的时候正确判断到底加载了那些模块
静态分析程序流,判断那些模块和变量未被使用或者引用,进而删除对应代码。