[譯]webpack官網文件 :指南 -- 7.程式碼分割
原創翻譯,轉載請註明出處。
原文地址:https://webpack.js.org/guides/code-splitting-import/
動態引入
目前,一個把類函式的模組載入語法import()新增到ECMAScript的提議,正在討論中。
ES2015載入器細則定義import()為一個能在執行時動態載入ES2015模組的方法。
webpack把import()當作一個分割點,把需求的模組放到單獨的程式碼塊裡。import()把模組名當作引數,返回一個許諾:import(name) -> Promise
index.js
functiondetermineDate(){ import('moment').then(function(moment){ console.log(moment().format()); }).catch(function(err){ console.log('Failed to load moment', err); }); } determineDate();
許諾polyfill
如果你在舊瀏覽器裡使用import(),別忘了用像es6-promise或者promise-polyfill的polyfill來shim 許諾。
(譯者注:沒找到合適的詞來譯shim和polyfill,其作用是讓各版本的瀏覽器相容Javascript方法)
在你應用的入口點裡:
import Es6Promise from'es6-promise'; Es6Promise.polyfill(); // or import'es6-promise/auto'; // or import Promise from'promise-polyfill'; if(!window.Promise){ window.Promise = Promise; } // or ...
通過Babel使用
如果你想通過Babel使用import,你需要安裝或者新增syntax-dynamic-import外掛,為避免編譯錯誤它仍然在第三階段。等提議完全加到細則裡之後這將完全沒有必要。
npm install --save-dev babel-core babel-loader babel-plugin-syntax-dynamic-import babel-preset-es2015 # for this example npm install --save moment
index-es2015.js
functiondetermineDate(){ import('moment') .then(moment =>moment().format('LLLL')) .then(str => console.log(str)) .catch(err => console.log('Failed to load moment', err)); } determineDate();
webpack.config.js
module.exports ={ entry:'./index-es2015.js', output:{ filename:'dist.js', }, module:{ rules:[{ test:/\.js$/, exclude:/(node_modules)/, use:[{ loader:'babel-loader', options:{ presets:[['es2015',{modules:false}]], plugins:['syntax-dynamic-import'] } }] }] } };
不用syntax-dynamic-import外掛的話將會發生下面的編譯錯誤:
- Module build failed: SyntaxError: 'import' and 'export' may only appear at the top
或
- Module build failed: SyntaxError: Unexpected token, expected {
通過Babel和async/await使用
ES2017 async/await 和import()一起使用:
npm install --save-dev babel-plugin-transform-async-to-generator babel-plugin-transform-regenerator babel-plugin-transform-runtime
index-es2017.js
asyncfunctiondetermineDate(){ const moment =awaitimport('moment'); returnmoment().format('LLLL'); } determineDate().then(str => console.log(str));
webpack.config.js
module.exports ={ entry:'./index-es2017.js', output:{ filename:'dist.js', }, module:{ rules:[{ test:/\.js$/, exclude:/(node_modules)/, use:[{ loader:'babel-loader', options:{ presets:[['es2015',{modules:false}]], plugins:[ 'syntax-dynamic-import', 'transform-async-to-generator', 'transform-regenerator', 'transform-runtime' ] } }] }] } };
import替代require.ensuse?
好訊息:載入程式碼塊失敗的問題現在可以解決,因為他們是基於Promise。
警告:require.ensure考慮到了通過第三個引數的可選配置來簡易命名程式碼塊,但是import API還沒有提供這個功能。如果你想保留這個功能,你可以繼續使用require.ensure。
require.ensure([],function(require){ var foo =require("./module"); },"custom-chunk-name");
棄用System.import
在webpack裡,使用System.import是不符合提議細則的,所以它在v2.1.0-beta.28裡被棄用,支援import()。
一些例子
- https://github.com/webpack/webpack/tree/master/examples/harmony
- https://github.com/webpack/webpack/tree/master/examples/code-splitting-harmony
- https://github.com/webpack/webpack/tree/master/examples/code-splitting-native-import-context
網頁連結
-- End --