連rollup都不會,還寫什麼插件庫!

輕量化Library打包工具

簡介

本文檔地址javascript

本文引用參考文檔地址html

Rollup 是一個 JavaScript 模塊打包器,能夠將小塊代碼編譯成大塊複雜的代碼,例如 library 或應用程序。java

Rollup 對代碼模塊使用新的標準化格式,這些標準都包含在 JavaScript 的 ES6 版本中,而不是之前的特殊解決方案,如 CommonJS 和 AMD。ES6 模塊可使你自由、無縫地使用你最喜好的 library 中那些最有用獨立函數,而你的項目沒必要攜帶其餘未使用的代碼。ES6 模塊最終仍是要由瀏覽器原生實現,但當前 Rollup 可使你提早體驗。node

Why is rollup

Rollup 着眼於將來,採用原生的ES 標準的模塊機制進行構建,將來ES 規範確定會由瀏覽器實現,也是JavaScript語言明確的發展方向。機制更加優於CommonJSwebpack

CommonJS 是在ES規範以前被提出的一種暫時性性解決方案,是一種特殊的傳統格式,git

相比較ES模塊容許進行靜態分析,從而實現像 tree-shaking 的優化,並提供諸如循環引用和動態綁定等高級功能github

Tree-shaking, 也被稱爲 "live code inclusion," 它是清除實際上並無在給定項目中使用的代碼的過程,可是它能夠更加高效。web

構建工具對比

打包工具 體積 注入代碼 code spliting dynamic import Tree-shaking
webpack large more
rollup small less

webpack 是一款強大的 bundle 構建工具,經過 loader機制能夠處理各類類型的文件,良好的 code splittingdynamic import支持使得webpack 成爲了應用程序,單頁應用的全能型的的打包工具。npm

可是由於其打包體積相對較大,注入代碼更多,沒有良好的Tree-shaking因此在Library 的打包工做中,不如rollup打包的精簡。json

配置

rollup 定位是一款輕量級的構建工具,其配置也相對很簡單,可是因爲不支持CommonJs,在配置rollup-plugin-commonjsCommmonJS 轉化成ES 模塊方式的時候,須要配置babel 轉譯

因爲babel 7+升級改動比較大,命名空間改動,市面上的教程大部分說的不夠清楚,並且基本上停留在babel 6的配置,致使一直拋(plugin commonjs) SyntaxError: Unexpected token

在後文中會着力介紹這個部分,分析babel 7+配置以及各個presetsplugins 的做用。

安裝rollup

npm install --save-dev rollup
複製代碼

配置文件

在項目根目錄建立rollup.config.js文件。

rollup 配置比較的簡潔,通常包括input,output,plugins,external

配置項參考

這是一段簡單的配置文件

export default {
  input: 'src/index.js',
  output: {
    name: 'amapUpper',
    file: 'dist/amapUpper.js',
    format: 'umd' //兼容模式
  },
  external: ['@amap/amap-jsapi-loader'],// 配置引入的包是否要打包,在這裏配置的會忽略掉,不打包到咱們的程序裏面
  plugins: []
};
複製代碼

當你的配置文件須要配置多個打包策略的時候,你還能夠這樣配置

export default [{
  input: 'main-a.js',
  output: {
    file: 'dist/bundle-a.js',
    format: 'cjs'
  }
}, {
  input: 'main-b.js',
  output: [
    {
      file: 'dist/bundle-b1.js',
      format: 'cjs'
    },
    {
      file: 'dist/bundle-b2.js',
      format: 'es'
    }
  ]
}]
複製代碼

你還可使用多個配置文件,使用--config來使用配置文件

# pass a custom config file location to Rollup
rollup --config my.config.js
複製代碼

::: danger 使用了umd模式必須指定 Name for UMD export :::

配置rollup插件

配置gollup 的plugin 相似babel 所有移植到了@rollup下,在官方提供的 一站式配置商店,能夠下載所需的插件, 做用在於可維護學習被誤導成本下降,更有利於長期維護。

@plugin 連接地址

插件是什麼

rollup plugin 是一個遵循rollup插件規範的object,通常經過一個工廠函數返回一個對象實現

一段簡單的示例:

export default function myExample () {
  return {
    name: 'my-example', // this name will show up in warnings and errors
    resolveId ( source ) {
      if (source === 'virtual-module') {
        return source; // this signals that rollup should not ask other plugins or check the file system to find this id
      }
      return null; // other ids should be handled as usually
    },
    load ( id ) {
      if (id === 'virtual-module') {
        return 'export default "This is virtual!"'; // the source code for "virtual-module"
      }
      return null; // other ids should be handled as usually
    }
  };
}
複製代碼

而後在配置文件中引用該插件,在plugins中,傳入執行返回的對象

import myExample from 'myExample'


plugins: [ myExample() ]
複製代碼

插件對象遵循的規範

A Rollup plugin is an object with one or more of the properties, build hooks, and output generation hooks

插件執行順序

熟悉webpack loader機制的都應該知道loader 其實是從右到左,自下而上執行的,在頁頭的 rollup打包js的注意點 裏面提到的錯誤記錄/錯誤2裏面,類比webpack loader機制, 實際上是一個錯誤的類比,實際上rollupplugin 機制是從左往右,自上而下而下的執行順序。

一個測試例子

// rollup.config.js
function myExample1() {
  return {
    name: 'my-example1', // this name will show up in warnings and errors
    resolveId(source) {
      console.log('111 resolve_______________-------------------------------------------');
      return null; // other ids should be handled as usually
    },
    load(id) {
      console.log('111 load_______________-------------------------------------------');
      return null; // other ids should be handled as usually
    }
  };
}
function myExample2() {
  return {
    name: 'my-example1', // this name will show up in warnings and errors
    resolveId(source) {
      console.log('222 resolve_______________-------------------------------------------');
      return null; // other ids should be handled as usually
    },
    load(id) {
      console.log('222 load_______________-------------------------------------------');
      return null; // other ids should be handled as usually
    }
  };
}


export default {
  input: 'src/index.js',
  output: {
    name: 'test',
    file: 'dist/test.js',
    format: 'umd'
  },
  plugins: [
    myExample1(),    
    myExample2()
  ]
};

複製代碼

能夠看到load,resolve 鉤子函數都是從左往右,自上而下而下的執行順序。

配置經常使用的插件

下面介紹正常打包中須要用到的插件,和通常配置。

  • @rollup/plugin-json rollup-plugin-json
  • @rollup/plugin-commonjs rollup-plugin-commonjs
  • @rollup/plugin-node-resolverollup-plugin-node-resolve
  • rollup-plugin-terser

首先,須要做爲開發依賴安裝這些插件

npm i @rollup/plugin-json -D
npm i @rollup/plugin-commonjs -D
npm i @rollup/plugin-node-resolve -D
npm i rollup-plugin-terser -D
複製代碼

而後須要引用配置文件

import json from '@rollup/plugin-json';
import commonjs from '@rollup/plugin-commonjs';
import nodeResolve from '@rollup/plugin-node-resolve';
import babel from 'rollup-plugin-babel';
import { terser } from 'rollup-plugin-terser';

export default {
  ...
  plugins: [
    json(),
    terser(),
    nodeResolve(),
    commonjs(),
    babel({
      exclude: '*', // 排除node_modules 下的文件
      runtimeHelpers: true // 防止生成多個 打包helper 函數
    }),
  ]
};
複製代碼

問題總結

commonjs 插件和 babel7+ 配置

在跟着 rollup 搭建打包 JS 一文配置的過程當中,用到的插件不是官方一站式插件提供的長期維護版本,遇到了 rollup-plugin-commonjs 插件打包報錯的問題

針對使用了放棄維護的rollup-plugin-commonjs插件的打包拋出的這個SyntaxError,能夠有兩種解決方案。推薦方案二。

解決方案一 配置babel

查找了不少資料都顯示,應該是babel 配置問題,主要分爲:

  • babel 配置問題
  • babel 轉譯執行順序問題

綜合這些資料,這個報錯應該是因爲該commonjs 插件庫 被移動到 @rollup/plugin-commonjs下維護,致使非長期維護版本缺乏某些轉譯後的輔助函數,屬性,致使拋出異常。

因此須要babel 輔助編譯以後才能正確執行commonjs 插件。

babel 配置的一些問題

因爲babel 7+版本中,將babel 的各個庫所有移植到了@babel/***下統一官方維護,而市面上大部分的babel教程實際上沒有對這點進行詳細說明,並且教程裏安裝babel組件的時候並無指定版本,實際上致使可能安裝了7+ 版本的babel核心庫,而安裝了放棄維護的babel-plugins-***下的插件預設之類的。就會致使一系列的問題。

這裏要注意一下這個@這個符號,這個是隻有babel7才特有的,babel6都木有,市面上大量代碼都是基於6的因此要特別注意,安裝的時候要使用 npm install i -S @babel\cli 而不能是npm install i -S babel-cli了 這是 babel 7 的一大調整,原來的 babel-xx 包統一遷移到babel域 下 - 域由 @ 符號來標識

參閱文章開頭提到的 babel 7 的使用的我的理解

配置

因爲這裏使用@rollup/plugin-babel,執行babel 轉譯 因此不須要安裝@babel/cli命令行工具。

首先咱們須要安裝:

  • babel核心包@babel/core
  • babel預設包@babel/preset-env
  • 統一的模塊化的helper@babel/runtime
  • helper 的自動化引入工具 @babel/plugin-transform-runtime
npm i -D @babel/core
npm i -D @babel/preset-env
npm i -D @babel/runtime
npm i -D @babel/plugin-transform-runtime
複製代碼

而後在項目根目錄下建立.babelrc的配置文件

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false,
        "targets": {
          "browsers": [
            "> 1%",
            "last 2 versions",
            "not ie <= 8"
          ]
        }
      }
    ]
  ],
  "plugins": ["@babel/plugin-transform-runtime"]
}
複製代碼

而後若是你用的是rollup-plugin-commonjs很是期維護版本的插件的話,因爲和babel有依賴關係,你須要:

commonjs插件以前引入babel插件,並配置須要匹配編譯的文件,目錄。和編譯配置

// rollup.config.js
export default {
  input: 'src/index.js',
  output: {
    name: 'amapUpper',
    file: 'dist/amapUpper.js',
    format: 'umd'
  },
  plugins: [
    babel({
      exclude: '/node_modules/**', // 排除node_modules 下的文件
      runtimeHelpers: true // 與plugin-transform-runtime 插件對應配置,生成統一化helper。
    }),
    commonjs()
  ]
};
複製代碼

解決方案二

使用rollup新的官方提供的移動後的一站式插件庫裏面的插件

rollup @plugin 連接地址

使用了新的插件庫以後,babel仍是須要配置的,只是解決了commonjs 插件依賴babel的問題。

而babel 其實是解決各類瀏覽器,引擎之間的差別,而存在的。因此爲了更好的支持,須要配備良好的babel配置。

this over

歡迎各位看官大佬們點贊,糾錯。

相關文章
相關標籤/搜索