實用程式包utils - 基於Rollup打包輸出各模組檔案(二)

ataola發表於2021-06-07

上一次,我們講到了如何去搭建一個前端工具庫的工程,那麼今天我們來聊一聊如何去將其打包輸出。

需求

事情是這個樣子的。我有一個這樣的需求,或者是我發現有這麼一個需求。就是有時候吧,我也不想搞的那麼複雜,我就想寫一個簡簡單單的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.bootcdn.net/ajax/libs/require.js/2.3.6/require.js"></script>
<script>
requirejs(["https://unpkg.com/@ataola/utils@0.1.10/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/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://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/utils@0.1.10/dist/ataola-utils.min.js"></script>
<script>
  // https://unpkg.com/@ataola/utils@0.1.10/dist/ataola-utils.js
  // https://cdn.jsdelivr.net/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://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/utils@0.1.10/dist/ataola-utils.esm.js';

console.log(ataola);
</script>
</html>

https://zhengjiangtao.cn/show/zj/ataola-utils-esm.html

ComonJS

這裡AMD相關的引入需要你先引入require.js的支援,如果是commonJS模組的話,需要用seajs,我試了下不是很好使,我放棄了別打我,建議直接在node.js環境下引入,如樓上

參考文獻

Rollup官方文件:https://rollupjs.org/guide/zh/

Rollup外掛庫: https://github.com/rollup/plugins

IIFE: https://developer.mozilla.org/zh-CN/docs/Glossary/IIFE

相關文章