webpack 支援的模組方法
在 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中