JS模块汇总工具 rollup【实践】

博客内容仅是个人实践理解,仅供参考,如有错误,敬请指正,更多内容和详情请访问官方文档

实践理解

一:对rollup的认识?

1.rollup将多个小的模块汇总合并成一个或多个大的模块。
2.rollup可多种模块化形式输入,汇总后也可以多种模块化形式输出
3.rollup支持插件功能让rollup更加灵活和强大

二:与webpack的用途适用比较

1.webpack更加适用于打包应用
2.rollup更加适用于打包类库

实践过程

一:初始化项目及其目录结构:rollup-test

在这里插入图片描述

二:安装rollup

全局安装

npm i -g rollup

本地安装(团队协作时)

三:汇总前各模块

汇总前目录结构

在这里插入图片描述

es6模块化规范下的三个文件(默认支持ES6模块化规范,而不是commonJS)

src/js/es6/entry.js
import module1 from "./module1"
import module2 from "./module2"
let moduleName = 'entry'
function fn(){
    
    
    console.log(moduleName)
    console.log(module1.moduleName)
    console.log(module2.moduleName)
}
export default {
    
    
    moduleName,
    fn
}
src/js/es6/module1.js
let moduleName = 'module1'
let moduleShake = 'moduleShake_param'// 定义却不被使用,tree-shake
console.log('module1')
export default {
    
    
    moduleName
}
src/js/es6/module2.js
let moduleName = 'module2'
console.log('module2')
export default {
    
    
    moduleName
}

四:命令行方式汇总模块

1.汇总命令(为方便运行,配置在package.json文件中)

  "scripts": {
    
    
    "dev:es6ToIife": "rollup src/js/es6/entry.js --file dist/fromES6/bundle.iife.js --format iife",
    "dev:es6ToCjs": "rollup src/js/es6/entry.js --file dist/fromES6/bundle.cjs.js --format cjs",
    "dev:es6ToUmd": "rollup src/js/es6/entry.js --file dist/fromES6/bundle.umd.js --format umd --name \"myBundle\"",
    "dev:es6ToEs6": "rollup src/js/es6/entry.js --file dist/fromES6/bundle.esm.js --format es",
    "dev:cjsToCjs": "rollup src/js/cjs/entry.js --file dist/fromCJS/bundle.cjs.js --format cjs"
  },

2.汇总结果

在这里插入图片描述

  • dist/fromES6/bundle.iife.js
(function () {
    
    
    'use strict';

    let moduleName = 'module1';
    console.log('module1');
    var module1 = {
    
    
        moduleName
    };

    let moduleName$1 = 'module2';
    console.log('module2');
    var module2 = {
    
    
        moduleName: moduleName$1
    };

    let moduleName$2 = 'entry';
    function fn(){
    
    
        console.log(moduleName$2);
        console.log(module1.moduleName);
        console.log(module2.moduleName);
    }
    var entry = {
    
    
        moduleName: moduleName$2,
        fn
    };

    return entry;

}());

  • dist/fromES6/bundle.esm.js
let moduleName = 'module1';
console.log('module1');
var module1 = {
    
    
    moduleName
};

let moduleName$1 = 'module2';
console.log('module2');
var module2 = {
    
    
    moduleName: moduleName$1
};

let moduleName$2 = 'entry';
function fn(){
    
    
    console.log(moduleName$2);
    console.log(module1.moduleName);
    console.log(module2.moduleName);
}
var entry = {
    
    
    moduleName: moduleName$2,
    fn
};

export default entry;
  • dist/fromCJS/bundle.cjs.js【汇总失败,module1、module2并没有被解析汇总】
'use strict';

let module1 = require('./module1');
let module2 = require('./module2');
let moduleName = 'entry';
function fn(){
    
    
    console.log(moduleName);
    console.log(module1.moduleName);
    console.log(module2.moduleName);
}
var entry = {
    
    
    moduleName,
    fn
};

module.exports = entry;

3.汇总结果分析

  • es6模块以各种模块化规范(iife、commonJS、umd、es6)汇总输出成功,而commonJS模块化规范汇总输出失败(默认支持ES6模块化规范而不是CommonJS)。
  • 模块内无用代码会被tree-shake
  • 不同模块的同名变量会被自动加以区分,如moduleName$1、moduleName$2
  • ES6代码的import和export语法会被识别转换到ES5语法,但其它ES6语法如let等并不会转换(说明需要借助babel插件)。

五:配置文件方式汇总模块

1.创建配置文件(scripts/rollup.config.js)并配置scripts(package.json文件中)

  "scripts": {
    
    
    "dev": "rollup -c scripts/rollup.config.js",
    ...
   }

2.入口与输出

单入口单输出配置
// 单输入单输出
export default {
    
    
    input: 'src/js/es6/entry.js',
    output: {
    
    
    	file: 'dist/fromEs6/bundle.cjs.js',
        format: 'cjs',
        name:'vue',// 输出的模块名,默认为入口名
        
}
};
单入口多输出配置
// 单输入多输出
export default {
    
    
    input: 'src/js/es6/entry.js',
    output: [{
    
    
        file: 'dist/fromEs6/bundle.iife.js',
        format: 'iife'
    }, {
    
    
        file: 'dist/fromEs6/bundle.cjs.js',
        format: 'cjs'
    },
        {
    
    
            file: 'dist/fromEs6/bundle.umd.js',
            format: 'umd',
            name: 'myBundle'
        }, {
    
    
            file: 'dist/fromEs6/bundle.esm.js',
            format: 'es'
        },]
}
多入口多输出配置
// 多输入多输出
export default [{
    
    
    input: 'src/js/es6/entry.js',
    output: [{
    
    
        file: 'dist/fromES6/bundle.iife.js',
        format: 'iife'
    }, {
    
    
        file: 'dist/fromES6/bundle.cjs.js',
        format: 'cjs'
    },
        {
    
    
            file: 'dist/fromES6/bundle.umd.js',
            format: 'umd',
            name: 'myBundle'
        }, {
    
    
            file: 'dist/fromES6/bundle.esm.js',
            format: 'es'
        },]
},{
    
    
    input: 'src/js/cjs/entry.js',
    output: [{
    
    
        file: 'dist/fromCJS/bundle.iife.js',
        format: 'iife'
    }, {
    
    
        file: 'dist/fromCJS/bundle.cjs.js',
        format: 'cjs'
    },
        {
    
    
            file: 'dist/fromCJS/bundle.umd.js',
            format: 'umd',
            name: 'myBundle'
        }, {
    
    
            file: 'dist/fromCJS/bundle.esm.js',
            format: 'es'
        },]
}]

2.配置文件中读取运行命令参数

  • 运行的命令
  "scripts": {
    
    
    "dev": "rollup -c scripts/rollup.config.js",
    "dev:lineParamTest": "rollup -c scripts/rollup.config.js --input entry.js",
    ...
   }
  • 获取参数(如获取命令 rollup -c scripts/rollup.config.js --input entry.js 中的input配置)
// 读取命令行参数作用在配置文件
export default commandLineArgs => {
    
    
    const inputBase = commandLineArgs.input || 'main.js';// 不传人默认为main.js

    delete commandLineArgs.input;
    return {
    
    
        input: 'src/js/es6/' + inputBase,
        output: {
    
    
            file: 'dist/fromEs6/bundle.cjs.js',
            format: 'cjs'
        }
    }
}

六:rollup插件

配置解析json(rollup默认只支持解析汇总js模块)

需求:entryWithJson.js读取package.josn文件内容
import module1 from "./module1"
import module2 from "./module2"
import {
    
     version } from '../../../package.json'// 不需要的内容会被tree-shake
let moduleName = 'entry'
function fn(){
    
    
    console.log(moduleName)
    console.log(module1.moduleName)
    console.log(module2.moduleName)
    console.log(version)
}
export default {
    
    
    moduleName,
    fn
}
安装插件
npm i @rollup/plugin-json -D
配置文件引入解析json插件
import json from '@rollup/plugin-json'
export default {
    
    
    input: 'src/js/es6/entryWithJson.js',
    output: {
    
    
        file: 'dist/fromEs6/bundle.cjs.js',
        format: 'cjs'
    },
    plugins: [ json() ]
};
汇总结果(成功并且tree-shake,如下 var version = “1.0.0”;)
'use strict';

let moduleName = 'module1';
console.log('module1');
var module1 = {
    
    
    moduleName
};

let moduleName$1 = 'module2';
console.log('module2');
var module2 = {
    
    
    moduleName: moduleName$1
};

var version = "1.0.0";

let moduleName$2 = 'entry';
function fn(){
    
    
    console.log(moduleName$2);
    console.log(module1.moduleName);
    console.log(module2.moduleName);
    console.log(version);
}
var entryWithJson = {
    
    
    moduleName: moduleName$2,
    fn
};

module.exports = entryWithJson;

汇总后压缩

安装插件
npm i rollup-plugin-terser -D
配置引入压缩插件
import json from '@rollup/plugin-json'// 解析json插件
import {
    
    terser} from 'rollup-plugin-terser'// 压缩插件
export default {
    
    
    // input: 'src/js/es6/entryWithJson.js',
    output: {
    
    
        file: 'dist/fromEs6/bundle.min.cjs.js',
        format: 'cjs',
        name:"vue",
        plugins: [terser()]// 压缩插件
    },
    plugins: [ json() ]
};
汇总结果
"use strict";console.log("module1");var o="module1";console.log("module2");var l="module2";var e={
    
    moduleName:"entry",fn:function(){
    
    console.log("entry"),console.log(o),console.log(l),console.log("1.0.0")}};module.exports=e;

汇总时代码分割(分离动态/懒加载模块)

需求:entryWithCodeSplit.js中动态加载的module1模块打包时分离
export default function () {
    
    
    import('./module1.js').then(({
    
     default: foo }) => console.log(foo));
}
配置代码
import json from '@rollup/plugin-json'// 解析json插件
import {
    
    terser} from 'rollup-plugin-terser'// 压缩插件
export default {
    
    
    // input: 'src/js/es6/entryWithJson.js',
    input: 'src/js/es6/entryWithCodeSplit.js',
    output: {
    
    
        // file: 'dist/fromEs6/bundle.min.cjs.js',
        entryFileNames: 'bundle.min.cjs.js',
        dir:"dist/fromEs6/codeSplit/",// 不给定dir将会输出在控制台
        format: 'cjs',
        name:"vue",
        plugins: [terser()]// 压缩插件
    },
    plugins: [ json() ]
};
汇总结果

在这里插入图片描述

更多插件以及插件开发参考官方文档

猜你喜欢

转载自blog.csdn.net/jw2268136570/article/details/105384886