實(shí)用程序包utils - 基于Rollup打包輸出各模塊文件(二)
上一次,我們講到了如何去搭建一個(gè)前端工具庫(kù)的工程,那么今天我們來(lái)聊一聊如何去將其打包輸出。
需求
事情是這個(gè)樣子的。我有一個(gè)這樣的需求,或者是我發(fā)現(xiàn)有這么一個(gè)需求。就是有時(shí)候吧,我也不想搞的那么復(fù)雜,我就想寫一個(gè)簡(jiǎn)簡(jiǎn)單單的demo,引入一個(gè)JS腳本,CTRL + S一按,瀏覽器一打開,啪的一下,我就能看見(jiàn)效果,我就能爽起來(lái),我不想npm init、npm install這種去搞一個(gè)規(guī)范的工程,我就想回到遠(yuǎn)古時(shí)代,感受最純真的愛(ài)。再比如后端的同學(xué)或者測(cè)試的同學(xué),我不想知道npm是什么,我也不想去搞什么前端工程化,我就想像在學(xué)校老師教我的那樣,引入一個(gè)JS腳本,啪地一下能出效果,就像layui、jquery那樣,引入相關(guān)的腳本,it works。
好,今天圍繞著樓上這個(gè)問(wèn)題,我們?nèi)ニ伎忌弦淮喂こ袒粝聛?lái)的問(wèn)題。------ 怎么將開發(fā)的模塊打包輸出?

JS中的模塊規(guī)范
隨著時(shí)代的發(fā)展,社會(huì)的進(jìn)步。為了更好地解決代碼的沖突和依賴等問(wèn)題,JS的模塊也經(jīng)歷了很大的發(fā)展。比如寫服務(wù)端Node.js同學(xué)熟悉的CommonJS規(guī)范,以及專為瀏覽器設(shè)計(jì)的AMD(Asynchronous Module Definition)規(guī)范,還有它們的結(jié)合體UMD(Universal Module Definition)規(guī)范,還有2015年推出的ES Module規(guī)范。這里具體的示例我們放到后面再講。
Rollup介紹
Rollup是一個(gè)Javascript的模塊打包器,它可以做這樣一件事,將一大串代碼打包成一個(gè)模塊文件,這個(gè)模塊可以是我們上面提到的模塊規(guī)范,比如著名的Vue.js框架就是使用了rollup進(jìn)行打包相關(guān)的文件輸出。
如何在項(xiàng)目中運(yùn)用rollup
這里我主要是用了這5個(gè)主要的輔助包
執(zhí)行相關(guān)命令npm install package name即可,歐,不要忘了安裝rollup本包
@rollup/plugin-json
這個(gè)插件主要是將JSON文件轉(zhuǎn)換為ES Module
https://github.com/rollup/plugins/tree/master/packages/json
rollup-plugin-babel
我們知道babel是JS的一個(gè)語(yǔ)法編譯器,有了它,或者說(shuō)加上它的一些插件(比如說(shuō)墊片),你可以在一些低版本或者不支持ES高級(jí)語(yǔ)法的環(huán)境下使用它
https://github.com/rollup/plugins/tree/master/packages/babel
rollup-plugin-terser
可能我們生成的代碼體積很大,用這個(gè)插件可以有效地減小我們輸出包的體積
https://github.com/trysound/rollup-plugin-terser
@rollup/plugin-commonjs
這個(gè)插件就是將commonJS的語(yǔ)法轉(zhuǎn)化成ES Module的
https://github.com/rollup/plugins/blob/master/packages/commonjs
@rollup/plugin-node-resolve
這個(gè)是處理npm包的相關(guān)引入依賴的
https://github.com/rollup/plugins/tree/master/packages/node-resolve
下面是我的utils項(xiàng)目的一份配置文件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
樓上的配置項(xiàng)通俗易懂,字面意思就是它的意思,就不過(guò)多解釋了。這里我輸出的是一個(gè)數(shù)組,其實(shí)也可以是個(gè)對(duì)象,然后我們?cè)趏utput上面去配置輸出的格式,這個(gè)根據(jù)項(xiàng)目可以靈活配置的。主要是配置了打包輸出umd、amd、commonjs、esmodule以及IIFE(Immediately Invoked Function Expression)立即調(diào)用函數(shù)表達(dá)式

打包出來(lái)的文件怎么使用
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.bootcdn.net/ajax/libs/require.js/2.3.6/require.js"></script>
<script>
requirejs(["https://unpkg.com/@ataola/[email protected]/dist/ataola-utils.amd.js"], function(ataola) {
console.log(ataola)
console.log(ataola.getVersion())
});
</script>
</html>
https://zhengjiangtao.cn/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://unpkg.com/@ataola/[email protected]/dist/ataola-utils.umd.js"></script>
<script>
const ataola = this['ataola-utils'];
console.log(ataola);
console.log(ataola.getVersion());
</script>
</html>
https://zhengjiangtao.cn/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://unpkg.com/@ataola/[email protected]/dist/ataola-utils.min.js"></script>
<script>
// https://unpkg.com/@ataola/[email protected]/dist/ataola-utils.js
// https://cdn.jsdelivr.net/npm/@ataola/[email protected]/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://zhengjiangtao.cn/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://unpkg.com/@ataola/[email protected]/dist/ataola-utils.esm.js';
console.log(ataola);
</script>
</html>
https://zhengjiangtao.cn/show/zj/ataola-utils-amd.html
ComonJS

這里AMD相關(guān)的引入需要你先引入require.js的支持,如果是commonJS模塊的話,需要用seajs,我試了下不是很好使,我放棄了別打我,建議直接在node.js環(huán)境下引入,如樓上
參考文獻(xiàn)
Rollup官方文檔:https://rollupjs.org/guide/zh/
Rollup插件庫(kù):https://github.com/rollup/plugins
IIFE:https://developer.mozilla.org/zh-CN/docs/Glossary/IIFE
