使用rollup編寫一個現代化的模塊

之全部選用 rollup 是由於它能夠減小打包體積和提升構建速度,下面介紹不會詳細講解配置,你能夠自行查閱官方文檔node

ES6 已經出現好久了,可是爲了兼容之前的瀏覽器,咱們仍是須要使用各類構建工具,例如 webpack,在使用的時候很方便,能夠經過 babel 轉換 es6 的語法,好比下面導入一個模塊webpack

import moduleName from 'module';es6

不過編寫一個現代化模塊呢,預約目標應該有三點web

  1. 支持 typescript,將 ES6 代碼轉化爲 ES5 環境使用
  2. 支持構建工具和script type="module"的導入
  3. 支持 umd 格式引用

就如下面這段代碼爲演示,實現上述的目標typescript

export default (arr = []) => {
  return Array.from(arr).length;
};
複製代碼

準備

npm init -y
npm i rollup -D
cd.>rollup.config.js
md src
cd.>src/index.js
複製代碼

這樣就建立好咱們想要的基本結構了,將上面例子複製到 index.js 文件下。npm

rollup能夠經過命令行也能夠經過腳原本調用,這裏在package.jsonscripts字段,經過腳本調用json

"scripts": {
    "build": "rollup -c"
  }
複製代碼

-c是指配置文件,默認就是rollup.config.js因此不須要額外配置了瀏覽器

編寫第一個例子

rollup.config.jsbabel

export default {
  input: "./src/index.js",
  output: [
    {
      file: "dist/index.esm.browser.js",
      format: "es",
      sourcemap: true
    }
  ]
};
複製代碼

上面配置信息input指的是入口文件,output 是出口文件,file是輸出的文件路徑,sourcemap是是否輸出 map 文件,他能夠方便調試錯誤,在開發模塊中應該是必須的,format是指輸出的格式app

  • amd 異步模塊定義,用於像 RequireJS 這樣的模塊加載器
  • cjs CommonJS,適用於 Node 和 Browserify/Webpack
  • es 將軟件包保存爲 ES 模塊文件
  • iife 一個自動執行的功能,適合做爲<\script>標籤。(若是要爲應用程序建立一個捆綁包,您可能想要使用它,由於它會使文件大小變小。)
  • umd 通用模塊定義,以 amd,cjs 和 iife 爲一體

執行npm run build

dist/index.esm.browser.js

var index = (arr = []) => {
  return Array.from(arr).length;
};

export default index;
//# sourceMappingURL=index.esm.browser.js.map
複製代碼

能夠看到生成的信息十分簡潔,上面說到要同時支持umd 格式和 import 導入,import能夠經過es的形式來供構建工具和script type="module"使用,下面就來定義一下 umd 格式

export default {
  input: "./src/index.js",
  output: [
    {
      file: "dist/index.esm.browser.js",
      format: "es",
      sourcemap: true
    },
    {
      file: "dist/index.js",
      format: "umd",
      sourcemap: true,
      name: "index"
    }
  ]
};
複製代碼

注意使用umd或者iife必須指定 name 字段,他決定了暴露在全局做用下的變量名,再次執行能夠看到index.js的信息了。

babel

上面完成了需求的第一步,不過對於 es6 的代碼,並無轉化爲 es5 的形式,只是將語法轉換了,Array.from依舊存在,下面使用babel來完成需求

npm i @babel/core @babel/preset-env  core-js rollup-plugin-babel rollup-plugin-node-resolve rollup-plugin-commonjs -D
複製代碼

babel.config.js

module.exports = {
  presets: [
    [
      "@babel/preset-env",
      {
        useBuiltIns: "usage",
        corejs: 3,
        modules: false
      }
    ]
  ]
};
複製代碼

上面代碼的useBuiltInsusage是 babel7 的實驗性特性,他支持按需加載

rollup.config.js

import babel from "rollup-plugin-babel";
import resolve from "rollup-plugin-node-resolve";
import commonjs from "rollup-plugin-commonjs";
export default {
  input: "./src/index.js",
  output: [
    {
      file: "dist/index.esm.browser.js",
      format: "es",
      sourcemap: true
    },
    {
      file: "dist/index.js",
      format: "umd",
      sourcemap: true,
      name: "index"
    }
  ],
  plugins: [
    commonjs(),
    resolve(),
    babel({
      exclude: [/\/core-js\//],
      runtimeHelpers: true,
      sourceMap: true,
      extensions: [".js", ".jsx", ".es6", ".es", ".mjs", ".ts"]
    })
  ]
};
複製代碼

再次執行能夠看到Arrar.from已經被babel轉換爲 ES5 的環境了

typescript

這個咱們用babel提供給咱們的@babel/preset-typescript便可完成,不過爲了支持typescript一些其餘擴展語法,咱們還須要安裝一些插件

npm i @babel/preset-typescript @babel/plugin-transform-typescript @babel/plugin-syntax-dynamic-import @babel/plugin-proposal-class-properties -D
複製代碼

babel.config.js

module.exports = {
  presets: [
    [
      "@babel/preset-env",
      {
        useBuiltIns: "usage",
        corejs: 3,
        modules: false
      }
    ],
    ["@babel/preset-typescript"]
  ],
  plugins: [
    "@babel/plugin-transform-typescript",
    "@babel/plugin-syntax-dynamic-import",
    "@babel/plugin-proposal-class-properties"
  ]
};
複製代碼

修改一下 src/index.jsindex.tsrollup.config.jsinput字段

export default (arr: Array<any> = []): number => {
  return Array.from(arr).length;
};
複製代碼

再次執行npm run build,成功輸出

優化

  1. 輸出代碼沒有被壓縮
  2. 每次輸出的時候文件夾沒有被刪除

上面兩個問題,能夠經過插件來解決

npm i rollup-plugin-terser rollup-plugin-clear -D
複製代碼

rollup.config.js

import babel from "rollup-plugin-babel";
import clear from "rollup-plugin-clear";
import resolve from "rollup-plugin-node-resolve";
import commonjs from "rollup-plugin-commonjs";
import { terser } from "rollup-plugin-terser";
export default {
  input: "./src/index.ts",
  output: [
    {
      file: "dist/index.esm.browser.js",
      format: "es",
      sourcemap: true
    },
    {
      file: "dist/index.js",
      format: "umd",
      sourcemap: true,
      name: "index"
    }
  ],
  plugins: [
    clear({
      targets: ["dist"]
    }),
    resolve(),
    commonjs(),
    terser(),
    babel({
      exclude: [/\/core-js\//],
      runtimeHelpers: true,
      sourceMap: true,
      extensions: [".js", ".jsx", ".es6", ".es", ".mjs", ".ts"]
    })
  ]
};
複製代碼

這樣基本的模塊的基本功能就編寫完成了

相關文章
相關標籤/搜索