摘要:名稱后自動自動補全的功能將被移除在配置時,官方不再允許省略擴展名,的配置寫法上將逐步趨于嚴謹。使用自定義參數作為配置項傳入方式將做調整如果你隨意將自定義參數通過傳入到配置項中,如你會發現這將不會被允許,的執行將會遵循更為嚴格的標準。
從 webpack v1 遷移到 webpack v2 新特性
歡迎小伙伴們為 前端導航平臺 點star
github倉庫: https://github.com/pfan123/fr...
訪問 前端導航平臺
Tree shaking 是一個術語,通常用來描述移除 JavaScript 上下文中無用代碼這個過程,或者更準確的說是按需引用代碼,它依賴于 ES2015 模塊系統中 import/export 的靜態結構特性。這個術語和概念實際上是興起于 ES2015 模塊打包工具 rollup。
webpack 2 原生支持ES6模塊 (別名 harmony modules) ,并能檢測出未使用的模塊輸出。
示例:舉一個 maths.js 庫例子,它輸出兩個方法 square 和 cube:
// 這個函數沒有被其他地方引用過 export function square(x) { return x * x; } // 這個函數被引用了 export function cube(x) { return x * x * x; }
在 main.js 中我們只引用 cube 方法:
import {cube} from "./maths.js"; console.log(cube(5)); // 125
運行 node_modules/.bin/webpack main.js dist.js 并檢查 dist.js 可發現 square 沒有被輸出:
/* ... webpackBootstrap ... */ /******/ ([ /* 0 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* unused harmony export square */ /* harmony export (immutable) */ __webpack_exports__["a"] = cube; // 這個函數沒有被其他地方引用過 function square(x) { return x * x; } // 這個函數被引用了 function cube(x) { return x * x * x; } /***/ }), /* 1 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__maths_js__ = __webpack_require__(0); console.log(__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__maths_js__["a" /* cube */])(5)); // 125 /***/ })resolve.root, resolve.fallback, resolve.modulesDirectories
上述三個選項將被合并為一個標準配置項:resolve.modules. 更多關于resolve的信息信息可查閱 resolving.
resolve: { - root: path.join(__dirname, "src") + modules: [ + path.join(__dirname, "src"), + "node_modules" + ] }resolve.extensions
該配置項將不再要求強制轉入一個空字符串,而被改動到了resolve.enforceExtension下, 更多關于resolve的信息信息可查閱 resolving.
resolve.*更多相關改動和一些不常用的配置項在此不一一列舉,大家如果在實際項目中用到可以到resolving)中進行查看.
module.loaders 將變為 module.rules舊版本中loaders配置項將被功能更為強大的rules取代,同時考慮到新舊版本的兼容,之前舊版本的module.loaders的相關寫法仍舊有效,loaders中的相關配置項也依舊可以被識別。
新的loader配置規則會變得更加通俗易用,因此官方也非常推薦用戶能及時按module.rules中的相關配置進行調整升級。
module: { - loaders: [ + rules: [ { test: /.css$/, - loaders: [ + use: [ { loader: "style-loader" }, { loader: "css-loader", - query: { + options: { modules: true } } ] }, { test: /.jsx$/, loader: "babel-loader", // Do not use "use" here options: { // ... } } ] }鏈式loaders
同webpack1.X中類似,loaders繼續支持鏈式寫法,可將相關正則匹配到的文件資源數據在幾個loader之間進行共享傳遞,詳細使用說明可見 rule.use。
在wepback2中,用戶可通過use項來指定需要用到的loaders列表(官方推薦),而在weback1中,如果需要配置多個loaders則需要依靠簡單的 !符來切分,這種語法出于新舊兼容的考慮,只會在module.loaders中生效。
module: { - loaders: { + rules: { test: /.less$/, - loader: "style-loader!css-loader!less-loader" + use: [ + "style-loader", + "css-loader", + "less-loader" + ] } }module名稱后自動自動補全 -loader的功能將被移除
在配置loader時,官方不再允許省略-loader擴展名,loader的配置寫法上將逐步趨于嚴謹。
module: { rules: [ { use: [ - "style", + "style-loader", - "css", + "css-loader", - "less", + "less-loader", ] } ] }
當然,如果你想繼續保持之前的省略寫法,你寫可以在resolveLoader.moduleExtensions中開啟默認擴展名配置,不過這種做法并不被推薦。
+ resolveLoader: { + moduleExtensions: ["-loader"] + }
可以從這里查看 #2986此次變更的原因;
json-loader無需要獨立安裝當我們需要讀取json格式文件時,我們不再需要安裝任何loader,webpack2中將會內置 json-loader,自動支持json格式的讀?。ㄏ泊笃毡及。?。
module: { rules: [ - { - test: /.json/, - loader: "json-loader" - } ] }
為何需要默認支持json格式官方的解釋是為了在webpack, node.js and browserify三種構建環境下提供無差異的開發體驗。
loader配置項將默認從context中讀取在webpack 1中的一些特殊的loader在讀取對應資源時,需要通過require.resolve指定后才能指定生效。從webpack 2后,配置loader在直接從context中進行讀取,這就解決了一些在使用“npm鏈接”或引用模塊之外的context造成的模塊重復導入的問題。
配置中可以刪除如下代碼:
module: { rules: [ { // ... - loader: require.resolve("my-loader") + loader: "my-loader" } ] }, resolveLoader: { - root: path.resolve(__dirname, "node_modules") }module.preLoaders 和 module.postLoaders 將被移除
module: { - preLoaders: [ + rules: [ { test: /.js$/, + enforce: "pre", loader: "eslint-loader" } ] }
之前需要用到preLoader的地方可以改到rules的enfore中進行配置。
UglifyJsPlugin中的 sourceMap配置項將默認關閉UglifyJsPlugin中的sourceMap 默認項將從 true變為 false。
這就意味著當你的js編譯壓縮后,需要繼續讀取原始腳本信息的行數,位置,警告等有效調試信息時,你需要手動開啟UglifyJsPlugin 的配置項:sourceMap: true 。
devtool: "source-map", plugins: [ new UglifyJsPlugin({ + sourceMap: true }) ]UglifyJsPlugin 的警告配置將默認關閉
UglifyJsPlugin中的 compress.warnings 默認項將從 true變為 false。
這就意味著當你想在編譯壓縮的時候查看一部分js的警告信息時,你需要將compress.warnings 手動設置為 true。
devtool: "source-map", plugins: [ new UglifyJsPlugin({ + compress: { + warnings: true + } }) ]UglifyJsPlugin 不再支持讓 Loaders 最小化文件的模式了
UglifyJsPlugin 將不再支持讓 Loaders 最小化文件的模式。debug 選項已經被移除。Loaders 不能從 webpack 的配置中讀取到他們的配置項。
loade的最小化文件模式將會在webpack 3或者后續版本中被徹底取消掉.
為了兼容部分舊式loader,你可以通過 LoaderOptionsPlugin 的配置項來提供這些功能。
plugins: [ + new webpack.LoaderOptionsPlugin({ + minimize: true + }) ]DedupePlugin 已經被移除
webpack.optimize.DedupePlugin 不再需要. 從你以前的配置移除這個配置選項.
BannerPlugin 配置項將有所改變BannerPlugin 將不再允許接受兩個參數,而是只提供一個對象配置項.
plugins: [ - new webpack.BannerPlugin("Banner", {raw: true, entryOnly: true}); + new webpack.BannerPlugin({banner: "Banner", raw: true, entryOnly: true}); ]OccurrenceOrderPlugin 將被內置加入
不需要再針對OccurrenceOrderPlugin進行配置
plugins: [ - new webpack.optimize.OccurrenceOrderPlugin() ]ExtractTextWebpackPlugin配置項將有所改變
ExtractTextPlugin ] 1.0.0 在webpack v2將無法使用,你需要重新指定安裝ExtractTextPlugin 的webpack2的適配版本.
npm install --save-dev extract-text-webpack-plugin@beta
更新后的ExtractTextPlugin版本會針對wepback2進行相應的調整。
ExtractTextPlugin.extract的配置書寫方式將調整module: { rules: [ test: /.css$/, - loader: ExtractTextPlugin.extract("style-loader", "css-loader", { publicPath: "/dist" }) + loader: ExtractTextPlugin.extract({ + fallbackLoader: "style-loader", + loader: "css-loader", + publicPath: "/dist" + }) ] }new ExtractTextPlugin({options})的配置書寫方式將調整
plugins: [ - new ExtractTextPlugin("bundle.css", { allChunks: true, disable: false }) + new ExtractTextPlugin({ + filename: "bundle.css", + disable: false, + allChunks: true + }) ]全量動態加載資源將默認失效
只有使用一個表達式的資源依賴引用(i. e. require(expr)),現在將創建一個空的context,而不是一個context的完整目錄。
當在es2015的模塊化中無法工作時,請最好重構這部分的代碼,如果無法進行修改這部分代碼,你可以在ContextReplacementPlugin中來提示編譯器做出正確處理。
Cli使用自定義參數作為配置項傳入方式將做調整如果你隨意將自定義參數通過cli傳入到配置項中,如:
webpack --custom-stuff
// webpack.config.js var customStuff = process.argv.indexOf("--custom-stuff") >= 0; /* ... */ module.exports = config;
你會發現這將不會被允許,cli的執行將會遵循更為嚴格的標準。
取而代之的是用一個接口來做傳遞參數配置。這應該是新的代替方案,未來的工具開發也可能依賴于此。
webpack --env.customStuff
module.exports = function(env) { var customStuff = env.customStuff; /* ... */ return config; };
查看更多介紹 CLI.
require.ensure 和 AMD require將采用異步式調用require.ensure和amd require將默認采用異步的加載方式來調用,而非之前的當模塊請求加載完成后再在回調函數中同步觸發。
require.ensure將基于原生的Promise對象重新實現,當你在使用 require.ensure 時請確保你的運行環境默認支持Promise對象,如果缺少則推薦使用安裝polyfill.
Loader的配置項將通過options來設置在webpack.config.js中將不再允許使用自定義屬性來配置loder,這直接帶來的一個影響是:在ts配置項中的自定義屬性將無法在被在webpack2中正確使用:
module.exports = { ... module: { rules: [{ test: /.tsx?$/, loader: "ts-loader" }] }, // does not work with webpack 2 ts: { transpileOnly: false } }什么是 options?
這是一個非常好的提問,嚴格意義上來說,custom property和options均是用于webpack loader的配置方式,從更通俗的說法上看,options應該被稱作query,作為一種類似字符串的形式被追加到每一個loader的命名后面,非常類似我們用于url中的查詢字符串,但在實際應用中功能要更為強大:
module.exports = { ... module: { rules: [{ test: /.tsx?$/, loader: "ts-loader?" + JSON.stringify({ transpileOnly: false }) }] } }
options也可作為一個獨立的字面對象量,在loader的配置中搭配使用。
module.exports = { ... module: { rules: [{ test: /.tsx?$/, loader: "ts-loader", options: { transpileOnly: false } }] } }LoaderOptionsPlugin context
部分loader需要配置context信息, 并且支持從配置文件中讀取。這需要loader通過用長選項傳遞進來,更多loader的明細配置項可以查閱相關文檔。
為了兼容部分舊式的loader配置,也可以采用如下插件的形式來進行配置:
plugins: [ + new webpack.LoaderOptionsPlugin({ + options: { + context: __dirname + } + }) ]debug
debug作為loader中的一個調試模式選項,可以在webpack1的配置中靈活切換。在webpack2中,則需要loader通過用長選項傳遞進來,更多loader的明細配置項可以查閱相關文檔。
loder的debug模式在webpack3.0或者后續版本中將會被移除。
為了兼容部分舊式的loader配置,也可以采用如下插件的形式來進行配置:
- debug: true, plugins: [ + new webpack.LoaderOptionsPlugin({ + debug: true + }) ]Code Splitting with ES2015
在webpack1中,你需要使用require.ensure實現chunks的懶加載,如:
require.ensure([], function(require) { var foo = require("./module"); });
在es2015的 loader中通過定義import()作為資源加載方法,當讀取到符合ES2015規范的模塊時,可實現模塊中的內容在運行時動態加載。
webpack在處理import()時可以實現按需提取開發中所用到的模塊資源,再寫入到各個獨立的chunk中。webpack2已經支持原生的 ES6 的模塊加載器了,這意味著 webpack 2 能夠理解和處理 import和export了。
import()支持將模塊名作為參數出入并且返回一個Promise對象。
function onClick() { import("./module").then(module => { return module.default; }).catch(err => { console.log("Chunk loading failed"); }); }
這樣做的還有一個額外的好處就是當我們的模塊加載失敗時也可以被捕獲到了,因為這些都會遵循Promise的標準來實現。
值得注意的地方:require.ensure的第三個參數選項允許使用簡單的chunk命名方式,但是import API中將不被支持,如果你希望繼續采用函數式的寫法,你可以繼續使用require.ensure。
require.ensure([], function(require) { var foo = require("./module"); }, "custom-chunk-name");
(注: System.import將會被棄用,webpack中將不再推薦使用 System.import,官方也推薦使用import進行替換,詳見 v2.1.0-beta.28)
如果想要繼續使用Babel中提供的import,你需要獨立安裝 dynamic-import 插件并且選擇babel的Stage 3來捕獲時的錯誤, 當然這也可以根據實際情況來操作而不做強制約束。
Dynamic expressions動態表達式現在import()中的傳參可支持部分表達式的寫法了,如果之前有接觸過CommonJS中require()表達式寫法,應該不會對此感到陌生,(它的操作其實和 CommonJS 是類似的,給所有可能的文件創建一個環境,當你傳遞那部分代碼的模塊還不確定的時候,webpack 會自動生成所有可能的模塊,然后根據需求加載。這個特性在前端路由的時候很有用,可以實現按需加載資源)
import() 會針對每一個讀取到的module創建獨立的separte chunk。
function route(path, query) { return import(`./routes/${path}/route`) .then(route => new route.Route(query)); } // This creates a separate chunk for each possible route可以混用 ES2015 和 AMD 和 CommonJS
在 AMD 和 CommonJS 模塊加載器中,你可以混合使用所有(三種)的模塊類型(即使是在同一個文件里面)。
// CommonJS consuming ES2015 Module var book = require("./book"); book.currentPage; book.readPage(); book.default === "This is a book";
// ES2015 Module consuming CommonJS import fs from "fs"; // module.exports map to default import { readFileSync } from "fs"; // named exports are read from returned object+ typeof fs.readFileSync === "function"; typeof readFileSync === "function";
注:es2015 balel 的默認預處理會把 ES6 模塊加載器轉化成 CommonJS 模塊加載。要是想使用 webpack 新增的對原生 ES6 模塊加載器的支持,你需要使用 es2015-webpack 來代替,另外如果你希望繼續使用babel,則需要通過配置babel項,使其不會強制解析這部分的module symbols以便webpack能正確使用它們,babel的配置如下:
.babelrc
{ "presets": [ ["es2015", { "modules": false }] ] }Hints
No need to change something, but opportunities
Template strings模板字符串webpack中的資源參數已經開始支持模板字符串了,這意味著你可以使用如下的配置寫法:
- require("./templates/" + name); + require(`./templates/${name}`);配置支持項支持Promise
webpack現在在配置文件項中返回Promise了,這就允許你在配置中可以進行一些異步的寫法了,如下所示:
webpack.config.js
module.exports = function() { return fetchLangs().then(lang => ({ entry: "...", // ... plugins: [ new DefinePlugin({ LANGUAGE: lang }) ] })); };Loader匹配支持更多的高級寫法
webpack中的loader配置支持如下寫法:
module: { rules: [ { resource: /filename/, // matches "/path/filename.js" resourceQuery: /querystring/, // matches "/filename.js?querystring" issuer: /filename/, // matches "/path/something.js" if requested from "/path/filename.js" } ] }更多的CLI參數項
如下有更多的CLI 參數項可用:
--define process.env.NODE_ENV="production" 支持直接配置DefinePlugin.
--display-depth 能顯示每個entry中的module的資源深度
--display-used-exports 能顯示每個module中依賴使用了哪些資源.
--display-max-modules能限制顯示output中引用到的資源數量 (默認顯示15個).
-p 指定當前的編譯環境為生產環境,即修改:process.env.NODE_ENV 為 "production"
Cacheable緩存項Loaders 現在默認可被緩存。Loaders 如果不想被緩存,需要選擇不被緩存。
// Cacheable loader module.exports = function(source) { - this.cacheable(); return source; }
// Not cacheable loader module.exports = function(source) { + this.cacheable(false); return source; }Complex options復合參數項寫法
webpack v1 只支持能夠「可 JSON.stringify的對象」作為 loader 的 options。
webpack2中的loader參數項中已經可以支持任意的JS對象的寫法了。
使用復合選項時會有一個限制,你需要配置一個ident作為項來保證能正確引用到其他的loader,這意味著通過配置我們可以在內聯寫法中去調用對應依賴的加載器,如下:
require("some-loader??by-ident!resource")
{ test: /.../, loader: "...", options: { ident: "by-ident", magic: () => return Math.random() } }
v2.2.1之前(即從 v2.0.0 到 v2.2.0),使用 Complex options,需要在 options 對象上添加 ident,允許它能夠被其他 loader 引用。這在 v2.2.1 中被刪除,因此目前的遷移不再需要使用 ident 鍵。
{ test: /.ext/ use: { loader: "...", options: { - ident: "id", fn: () => require("./foo.js") } } }
參考資料:
webpack2.0
webpack guide
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/83113.html
摘要:要求模塊編寫必須在真正的代碼之外套上一層規定的代碼包裝,樣子看起來是這樣的模塊代碼通過傳遞一個簽名為的回調函數給函數,就可以把需要注入的變量和函數注入到模塊代碼內。 之前寫的文章急速Js全棧教程得到了不錯的閱讀量,霸屏掘金頭條3天,點贊過千,閱讀近萬,甚至還有人在評論區打廣告,可見也是一個小小的生態了;)??磥砗蚃S全棧有關的內容,還是有人頗有興趣的。 showImg(https://...
摘要:從再到目前當紅明星,前端模塊打包技術日新月異,在今年月份和月份左右接連更新了和版本為了減少冗余模塊,縮減文件大小,中也加入了關于的特征,可以查看知乎如何評價新引入的代碼優化技術的討論。 從Grunt->gulp->webpack,再到目前當紅明星rollup,前端模塊打包技術日新月異,webpack在今年1月份和6月份左右接連更新了v2和v3版本,為了減少冗余模塊,縮減bundle文件...
閱讀 991·2021-09-26 10:15
閱讀 2077·2021-09-24 10:37
閱讀 2585·2019-08-30 13:46
閱讀 2636·2019-08-30 11:16
閱讀 2425·2019-08-29 10:56
閱讀 2598·2019-08-26 12:24
閱讀 3482·2019-08-23 18:26
閱讀 2667·2019-08-23 15:43