webpack 支援的模組方法

QxQstar發表於2019-01-28

webpack中支援的模組語法風格有:ES6,commonJS和AMD

ES6風格(推薦)

在webpack2中,webpack支援ES6模組語法。這意味著在沒有babel等工具處理的情況下你就可以使用import和export。下面的方法在webpack中被支援:

import

靜態地匯入其他模組的匯出

import MyModule from `./my-module.js`;
import { NamedExport } from `./other-module.js`;

注:import只能靜態的匯入其他模板。不能在其他邏輯或者包含變數中動態使用

export

匯出變數,函式

import()

import(`path/to/module`) -> promise

 import()在執行期間動態的載入模組,它在內部依賴promise。import()的呼叫被視為一個分割點,這意味著請求的模組以及它的子模組被分隔到單個的包中。

if(module.hot) {
     import(`loadsh`).then(_ => {
         // Do something with lodash (a.k.a `_`)...
     })
 }

 import()的註釋

行內註釋讓import()更加地強大。新增註釋到import()中,使我們能夠對模組進行命名以及選擇不同的模式。下面有一些列子:

 // single target
    import(
        /* webpackChunkName: "my-chunk-name" */
        /* webpackMode: "lazy" */
        `module`
    )
    // Multiple possible targets
    import(
       /* webpackInclude: /.json$/ */
      /* webpackExclude: /.noimport.json$/ */
      /* webpackChunkName: "my-chunk-name" */
      /* webpackMode: "lazy" */
      /* webpackPrefetch: true */
      /* webpackPreload: true */
      `./locale/${language}`
    )

    import(
        /* webpackIgnore: true */
        `ignored-module.js`
    )

 行內註釋可設定的屬性

  1. webpackIgnore: 如果將webpackIgnore被設定為true,將不能動態匯入
  2. webpackChunkName:給包命名。從2.6.0起,佔位符[index]和[request]在給定的字串中被支援,[index]為遞增的數字,[request]為實際解析的檔名。在註釋中新增webpackChunkName:`my-chunk-name`,這會使分隔的包名為 [my-chunk-name].js而不是[id].js
  3. webpackPrefetch:告訴瀏覽器,這個資源在將來可能會被需要用於一些導航。
  4. webpackPreload:告訴瀏覽器,這個資源在當前導航中可能會需要。
  5. webpackMode:從2.6.0起,能夠指定不同的動態匯入模式。可選項如下:
    • `lazy`(default):為每一個import()的模組生成一個懶載入chunk。
    • `lazy-once`:只生成一個滿足所有import()呼叫的懶載入chunk。在第一次呼叫import()時就會去獲取chunk,在之後呼叫import()會使用相同的網路響應。注意這隻在部分動態語句中才有意義,例如:import(`./locales/${language}.json`),這兒可能有多個模組路徑被請求。
    • `eager`:不生成額外的chunk,所有的模組被包含中當前的chunk中並且不會增加額外的網路請求。只要被解析,promise依然會返回。與靜態匯入不同的是,直到呼叫import(),module才會被執行
    • `weak`:如果模組功能已經在其他地方被載入了(如:在其他模組中匯入了它或者載入了包含這個模組的指令碼),就嘗試去載入這個模組。promise依然會返回,但是隻有當chunk已經在客戶端了才會resolve,如果模組不可用就會reject。不會傳送網路請求。
    • `webpackInclude`:在匯入期間這個正規表示式會用於匹配,只有被匹配到的模組才會被打包。
    • `webpackExclude`:在匯入期間這個正規表示式會用於匹配,只要是被匹配到的模組就不會被打包。

commonJS

commonJS的目標是為瀏覽器之外的JavaScript指定一個生態系統。下面的commonJS方法在webpack中被支援:

require

 require(dependency: String);

 從其他的模組中同步檢索exports。編輯器會確認在輸出包中依賴是可用的

var $ = require(`jquery`);
var myModule = require(`my-module`);

 require.resolve

var ID = require.resolve(dependency: String);

 同步檢索模組ID,編輯器會確認在輸出包中依賴是可用的

require.cache

對同一個模組的多次require,只有一個模組執行並且只有一次匯出。這是因為在執行期間存在cache。從cache中移除值這會導致新的模組執行以及新的匯出。

var d1 = require(`dependency`);
    require(`dependency`) === d1;
    delete require.cache[require.resolve(`dependency`)];
    require(`dependency`) !== d1;

    // in file.js
    require.cache[module.id] === module;
    require(`./file.js`) === module.exports;
    delete require.cache[module.id];
    require.cache[module.id] === undefined;
    require(`./file.js`) !== module.exports; // in theory; in praxis this causes a stack overflow
    require.cache[module.id] !== module;

 require.ensure

 require.ensure(
      dependencies: String[],
      callback: function(require),
      errorCallback: function(error),
      chunkName: String
    )

 分隔指定的依賴到單獨的包中,並且包會被非同步載入。使用commonJs語法這是唯一一種動態載入包的方式。這意味著,該程式碼可以在執行中執行,只有在滿足某些條件時才載入依賴項。這個功能在內部依賴promise

if ( module.hot ) {
  require.ensure([`b`], function(require) {
    var c = require(`c`);

    // Do something special...
  });

 require.ensure支援如下引數:

  1. dependencies:字串陣列。宣告在callback要執行的所有模組。
  2. callback:一個函式。當所有的依賴載入完成就會這些這個回撥函式。require會作為這個函式的引數,在函式中可以使用require去引入其他的依賴。
  3. errorCallback:如果依賴載入失敗就會執行這個函式
  4. chunkName:給通過require.ensure()建立的包名指定一個名字

AMD

AMD是一個JavaScript規範,它為書寫模組,載入模板定義了介面。在webpack中支援如下的AMD方法

define (with factory)

define([name: String], [dependencies: String[]], factoryMethod: function(...))

 如果提供了dependencies,factoryMethod會帶著每個dependency輸出(按dependencies的相同順序)被呼叫,如果dependencies沒有被提供,factoryMethod會帶著require, exports 和 module被呼叫,如果這個函式有返回值,這個值會作為模組的輸出。webpack會忽略name

define([`jquery`, `my-module`], function($, myModule) {
  // Do something with $ and myModule...

  // Export a function
  return function doSomething() {
    // ...
  };
});

 它不能在非同步函式中使用

define (with value)

define(value: !Function)

 

define({
  answer: 42
});

 簡單的匯出value,這兒的value可以是除函式之外的任何值

require (amd-version)

require(dependencies: String[], [callback: function(...)])

 它與require.ensure()類似。它會分隔dependencies到一個獨立中包中,並且這個包會被非同步載入

require([`b`], function(b) {
  var c = require(`c`);
});

 webpack

除了上面描述的模組語法之外,webpack還提供了一些webpack特有的方法

require.context

require.context(
  directory: String,
  includeSubdirs: Boolean /* optional, default true */,
  filter: RegExp /* optional, default /^./.*$/, any file */,
  mode: String  /* optional, `sync` | `eager` | `weak` | `lazy` | `lazy-once`, default `sync` */
)

 require.include

require.include(dependency: String)

 在不執行依賴項的情況下包含依賴項.在優化效能時非常有用

require.include(`a`);
require.ensure([`a`, `b`], function(require) { /* ... */ });
require.ensure([`a`, `c`], function(require) { /* ... */ });

 這會生成如下輸出:

  • 入口chunk:file.js 和 a
  • 非同步chunk:b
  • 非同步chunk:c

如果沒有使用require.include(`a`)。a會被複制在兩個anonymous chunk中

相關文章