在本次教程中,咱們聚焦於如何在你的應用中減小輸出文件的體積,從而提高用戶體驗。這意味着在生產環境下要用不一樣的方式來處理代碼。今天咱們將闡述webpack經過mode參數來設置其內置的優化措施, 開始吧。javascript
首先,咱們回答究竟爲何要優化你的代碼這個問題。若是你有良好編程實踐,你可能注重代碼的可讀性,所以你在代碼中添加了大量的空白符(製表符、空格、換行符)和註釋。在代碼變得更漂亮的同時,也使得文件的體積大大增長了。另外一方面,爲了用戶體驗(指減小文件體積)而犧牲可讀性也不可取,手工這麼作的話很繁瑣。所以,這兒有一種解決方案供你在項目中選擇。java
Webpack4中引入了一個新參數:mode。要求老是在配置中指定。若是不指定,會產生一個警告並退而其次的使用默認值,默認值就是production。若是你使用 mode:"production", Webpack將配置成生成更適合在生產環境下的代碼。咱們如今就來看看webpack爲咱們確切地作了些什麼。webpack
將mode值設爲production將在配置中添加UglifyJsPlugin插件,它經過壓縮和最小化,使得你的代碼更短,運行得更快。其任務包括簡單的縮短變量名,移除空白符,刪除重複代碼等等。默認會解析每個.js文件。這篇博文中,咱們將講述UglifyJSPlugin這個插件最基本的配置。即便webpack 4 依據選擇的mode值進行了優化,你仍能經過optimization屬性來進行本身的配置。git
// webpack.config.js const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); module.exports = { mode: "production", // using mode: "production" attaches the following configuration: optimization: { minimize: true, minimizer: [ new UglifyJsPlugin() ] }, }
傳給UglifyJsPlugins插件最要緊的屬性是uglifyOptions,它有大量默認的配置。而其中最值得關注的部分是compress屬性。github
new UglifyJsPlugin({ uglifyOptions: { compress: { /*(...)*/ } } })
它負責UglifyJsPlugin插件的不少重要的舉措,從而是你的代碼更短,更輕。完整列表請參閱官方文檔,其也標記出了默認值。web
UglifyJsPlugin插件另一個重要的屬性是output。編程
new UglifyJsPlugin({ uglifyOptions: { compress: { /*(...)*/ }, output: { /*(...)*/ } } })
默認,代碼生成器試圖輸出最短的代碼。你能夠經過更改output的配置來改變這一行爲。你可能無需對默認值改動太多,但有一個值得考慮的屬性:drop_console,默認它的設置值是false。若是改成true,將刪除代碼中全部的console.log調用。若是想了解更多output的屬性,請查閱完整列表。閉包
UglifyJsPlugin還有更多的可能的配置,請參讀它在Github上的文檔。app
這個插件容許你建立全局常量用於編譯時解析。若是設置mode:"production",webpack默認會設置"process.env.NODE_ENV": JSON.stringify("production")。函數
// webpack.config.js module.exports = { mode: "production", // using mode: "production" attaches the following configuration: plugins: [ new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }), ] }
注意由於直接文本替換,所給的屬性值必須包括引號,要這麼作JSON.stringify("production")或'"production"'。
在編譯時解析意味着你在代碼中使用的process.env.NODE_ENV,將被替換成production這個值。
console.log(process.env.NODE_ENV); if(process.env.NODE_ENV === 'production') { console.log('this is production!') }
記住,在webpack編譯完代碼以後就沒有process.env.NODE_ENV這個常量值了。上面的代碼在webpack處理以後變成下面的樣子:
console.log("production"); if(true) { console.log("this is production!") }
在UglifyJSPlugin插件最小化處理以後,它更是簡化爲:
console.log("production"); console.log("this is production!")
使用這個插件將贊助你處理編譯期間的錯誤。例如,可能出現你試圖導入一個webpack不能解析(譯註:就是找不到啦)的文件的情形。此時,Webpack會建立一個有錯誤信息的新版應用。若是使用NoEmitOnErrorsPlugin,就根本不會建立這個版本。
(譯註:原文是這樣子的:
Using this plugin will help you deal with errors during the compilation. For example, there might be a situation in which you try to import a file that Webpack can’t resolve. In this situation, Webpack creates a new version of the application with the information about the error. With the usage of NoEmitOnErrorsPlugin, this version is not created at all.
是否是說得雲裏霧裏?其實意思是,若是沒有使用NoEmitOnErrorsPlugin,當發生錯誤時,就會重載一個有錯誤信息的頁面,把用戶的屏幕搞花。使用NoEmitOnErrorsPlugin插件,就不會加載這個頁面了,錯誤信息只是在控制檯中輸出)
// webpack.config.js const webpack = require('webpack'); module.exports = { mode: "production", // using mode: "production" attaches the following configuration: plugins: [ new webpack.NoEmitOnErrorsPlugin(); ] }
Webpack默認將每個模塊包裝在獨立的閉包函數中,這個包裝函數使得javascript的執行稍微變慢了一點。看看下面的例子:
// one.js const dog = 'Fluffy'; export const one = 1;
// two.js const dog = 'Fluffy'; export const two = 2;
// index.js import { one } from './one'; import { two } from './two'; const dog = 'Fluffy'; console.log(one, two);
如沒有ModuleConcatenationPlugin插件,輸出的打包象這個樣子:
// main.js (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var _one__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var _two__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2); const dog = 'Fluffy'; console.log(_one__WEBPACK_IMPORTED_MODULE_0__["one"], _two__WEBPACK_IMPORTED_MODULE_1__["two"]); /***/ }), /* 1 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "one", function() { return one; }); const dog = 'Fluffy'; const one = 1; /***/ }), /* 2 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "two", function() { return two; }); const dog = 'Fluffy'; const two = 2; /***/ }) /******/ ]);
當設置mode爲production,ModuleConcatenationPlugin插件就會盡心盡責。謝天謝地,如今輸出的打包在一個做用域裏了。更少的函數意味着更少的運行時開銷。
注意,這個例子中我沒有進行任何縮小化。因爲縮小化器如今知道了模塊間的依賴,它能更好的幹活。
// main.js (function(module, __webpack_exports__, __webpack_require__) { "use strict"; // CONCATENATED MODULE: ./src/one.js const dog = 'Fluffy'; const one = 1; // CONCATENATED MODULE: ./src/two.js const two_dog = 'Fluffy'; const two = 2; // CONCATENATED MODULE: ./src/index.js const src_dog = 'Fluffy'; console.log(one, two); /***/ }) /******/ ]);
若是你以爲有趣,請閱讀article on the webpack blog上針對這一特性的博文。
今天咱們學習了配置mode:'production'時Webpack能作的內置優化措施。這樣使得你的應用加載得更快,執行得更好。通過一系列的配置處理,達到如此目標,從而知足產品須要。下一個教程咱們將覆蓋開發模式下的配置,敬請期待!