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中
webpack 支持的模塊方法