上一次,我们讲到了如何去搭建一个前端工具库的工程,那么今天我们来聊一聊如何去将其打包输出。
需求 事情是这个样子的。我有一个这样的需求,或者是我发现有这么一个需求。就是有时候吧,我也不想搞的那么复杂,我就想写一个简简单单的demo,引入一个JS脚本,CTRL + S一按,浏览器一打开,啪的一下,我就能看见效果,我就能爽起来,我不想npm init
、npm install
这种去搞一个规范的工程,我就想回到远古时代,感受最纯真的爱。再比如后端的同学或者测试的同学,我不想知道npm是什么,我也不想去搞什么前端工程化,我就想像在学校老师教我的那样,引入一个JS脚本,啪地一下能出效果,就像layui、jquery那样,引入相关的脚本,it works。
好,今天围绕着楼上这个问题,我们去思考上一次工程化留下来的问题。------ 怎么将开发的模块打包输出?
JS中的模块规范 随着时代的发展,社会的进步。为了更好地解决代码的冲突和依赖等问题,JS的模块也经历了很大的发展。比如写服务端Node.js同学熟悉的CommonJS规范,以及专为浏览器设计的AMD(Asynchronous Module Definition)规范,还有它们的结合体UMD(Universal Module Definition)规范,还有2015年推出的ES Module规范。这里具体的示例我们放到后面再讲。
Rollup介绍 Rollup是一个Javascript的模块打包器,它可以做这样一件事,将一大串代码打包成一个模块文件,这个模块可以是我们上面提到的模块规范,比如著名的Vue.js框架就是使用了rollup进行打包相关的文件输出。
如何在项目中运用rollup 这里我主要是用了这5个主要的辅助包
执行相关命令npm install package name
即可,欧,不要忘了安装rollup
本包
@rollup/plugin-json 这个插件主要是将JSON文件转换为ES Module
https://github.com/rollup/plugins/tree/master/packages/json
rollup-plugin-babel 我们知道babel是JS的一个语法编译器,有了它,或者说加上它的一些插件(比如说垫片),你可以在一些低版本或者不支持ES高级语法的环境下使用它
https://github.com/rollup/plugins/tree/master/packages/babel
rollup-plugin-terser 可能我们生成的代码体积很大,用这个插件可以有效地减小我们输出包的体积
https://github.com/trysound/rollup-plugin-terser
@rollup/plugin-commonjs 这个插件就是将commonJS的语法转化成ES Module的
https://github.com/rollup/plugins/blob/master/packages/commonjs
@rollup/plugin-node-resolve 这个是处理npm包的相关引入依赖的
https://github.com/rollup/plugins/tree/master/packages/node-resolve
下面是我的utils项目的一份配置文件rollup.config.js
import json from '@rollup/plugin-json' ;import babel from 'rollup-plugin-babel' ;import { terser } from 'rollup-plugin-terser' ;import commonjs from '@rollup/plugin-commonjs' ;import resolve from '@rollup/plugin-node-resolve' ;import pkg from './package.json' ;const banner = '/*!\n' + ` * ataola-utils.js v${pkg.version} \n` + ` * (c) 2021-${new Date ().getFullYear()} ataola(Jiangtao Zheng)\n` + ' * Released under the MIT License.\n' + ' */' ;export default [ // browser-friendly UMD build { input : 'index.js' , output : { name : 'ataola-utils' , file : pkg.browser, format : 'umd' , sourcemap : true , banner, }, plugins : [ json({ compact : true , }), resolve(), commonjs(), babel({ exclude : 'node_modules/**' , runtimeHelpers : true , presets : ['@babel/preset-env' ], plugins : [ [ '@babel/plugin-transform-runtime' , { useESModules : true /**, corejs: 3 */ }, ], ], }), ], }, { input : 'index.js' , output : [ { file : pkg.main, format : 'cjs' , banner, sourcemap : true }, { file : pkg.module, format : 'esm' , banner, sourcemap : true }, { name : 'ataola-utils' , file : 'dist/ataola-utils.amd.js' , format : 'amd' , extend : true , sourcemap : true , banner, }, { name : 'ataola-utils' , file : 'dist/ataola-utils.js' , format : 'iife' , extend : true , sourcemap : true , banner, }, { name : 'ataola-utils' , file : 'dist/ataola-utils.min.js' , format : 'iife' , extend : true , banner, sourcemap : true , plugins : [terser()], }, ], plugins : [ json({ compact : true , }), resolve(), commonjs(), babel({ // https://github.com/rollup/rollup-plugin-babel#configuring-babel exclude : 'node_modules/**' , runtimeHelpers : true , presets : ['@babel/preset-env' ], plugins : [ [ '@babel/plugin-transform-runtime' , { useESModules : true /**, corejs: 3 */ }, ], ], }), ], }, ];
https://github.com/ataola/utils/blob/main/rollup.config.js
楼上的配置项通俗易懂,字面意思就是它的意思,就不过多解释了。这里我输出的是一个数组,其实也可以是个对象,然后我们在output上面去配置输出的格式,这个根据项目可以灵活配置的。主要是配置了打包输出umd、amd、commonjs、esmodule以及IIFE(Immediately Invoked Function Expression)立即调用函数表达式
打包出来的文件怎么使用 AMD <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > ataola utils</title > </head > <body > </body > <script src ="https://cdn./ajax/libs/require.js/2.3.6/require.js" > </script > <script > requirejs(["https:///@ataola/utils@0.1.10/dist/ataola-utils.amd.js" ], function (ataola ) { console .log(ataola) console .log(ataola.getVersion()) });</script > </html >
https:///show/zj/ataola-utils-amd.html
UMD <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > ataola utils</title > </head > <body > </body > <script src ="https:///@ataola/utils@0.1.10/dist/ataola-utils.umd.js" > </script > <script > const ataola = this ['ataola-utils' ]; console .log(ataola); console .log(ataola.getVersion());</script > </html >
https:///show/zj/ataola-utils-umd.html
IIFE <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > ataola utils</title > </head > <body > </body > <script src ="https:///@ataola/utils@0.1.10/dist/ataola-utils.min.js" > </script > <script > // https:///@ataola/utils@0.1.10/dist/ataola-utils.js // https://cdn./npm/@ataola/utils@0.1.10/dist/ataola-utils.js // use this['ataola-utils'] || window['ataola-utils'] const ataola = this ['ataola-utils' ]; console .log(ataola); console .log(ataola.getVersion());</script > </html >
https:///show/zj/ataola-utils.html
ES Module <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > utils unpkg</title > </head > <body > </body > <script type ="module" > import * as ataola from 'https:///@ataola/utils@0.1.10/dist/ataola-utils.esm.js' ;console .log(ataola);</script > </html >
https:///show/zj/ataola-utils-amd.html
ComonJS
这里AMD相关的引入需要你先引入require.js的支持,如果是commonJS模块的话,需要用seajs,我试了下不是很好使,我放弃了别打我,建议直接在node.js环境下引入,如楼上
参考文献 Rollup官方文档:https:///guide/zh/
Rollup插件库:https://github.com/rollup/plugins
IIFE:https://developer.mozilla.org/zh-CN/docs/Glossary/IIFE