在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` )
行內註釋可設定的屬性
- webpackIgnore: 如果將webpackIgnore被設定為true,將不能動態匯入
- webpackChunkName:給包命名。從2.6.0起,佔位符[index]和[request]在給定的字串中被支援,[index]為遞增的數字,[request]為實際解析的檔名。在註釋中新增webpackChunkName:`my-chunk-name`,這會使分隔的包名為 [my-chunk-name].js而不是[id].js
- webpackPrefetch:告訴瀏覽器,這個資源在將來可能會被需要用於一些導航。
- webpackPreload:告訴瀏覽器,這個資源在當前導航中可能會需要。
- 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支援如下引數:
- dependencies:字串陣列。宣告在callback要執行的所有模組。
- callback:一個函式。當所有的依賴載入完成就會這些這個回撥函式。require會作為這個函式的引數,在函式中可以使用require去引入其他的依賴。
- errorCallback:如果依賴載入失敗就會執行這個函式
- 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中