探索web工程化工具技术 - rollup

大熙哥
大熙哥 2022年02月24日 阅读:465

前言

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.jsonscripts中:"serve": "rollup -c -w"

安装插件

rollup/plugin-node-resolve插件

使用节点解析算法定位模块,可以告诉 Rollup 如何查找外部模块。

rollup-plugin-commonjs插件

由于node_modules文件夹中的大多数包可能是旧版CommonJS而不是JavaScript模块所以还需要rollup-plugin-commonjs将 CommonJS 模块转换为 ES6,以便它们可以包含在汇总捆绑包。

Babel插件

为了实现浏览器兼容,还可能需要引入BabelBabel 是一个工具链,主要用于在当前和较旧的浏览器或环境中将 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

终端信息.png

打包后的代码

注意,为了展示我们所编写的代码是被打包成什么样子,此处我加了外部引入标识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模块特性

  1. 只能作为模块顶层的语句出现
  2. import的模块名只能是字符串常量
  3. 引入的模块不能再进行修改

代码删除

  1. uglify:判断程序流,判断变量是否被使用和引用,进而删除代码

实现原理可以简单的概况

ES6 Module引入进行静态分析,故而编译的时候正确判断到底加载了那些模块
静态分析程序流,判断那些模块和变量未被使用或者引用,进而删除对应代码。

分类:
标签:
目录
目录