摘要:它會(huì)代替所有的實(shí)例的值為,從而使知道那些判斷表達(dá)式總是錯(cuò)誤的,從而刪除相關(guān)代碼,進(jìn)一步壓縮打包文件模塊機(jī)制項(xiàng)目中使用的,通過(guò)也能通過(guò)打包有用的代碼,進(jìn)一步減少大小。
好久沒(méi)寫文章,這次預(yù)計(jì)會(huì)帶來(lái)3篇的 Webpack 系列文章,將會(huì)在這幾天內(nèi)更新完。
Webpack3 自今年6月20日正式發(fā)布而來(lái),給我們帶來(lái)Scope Hoisting和Magic Comments兩大功能,可惜不在這次系列文章內(nèi)容范疇里,而本次文章的主要內(nèi)容是從項(xiàng)目中總結(jié)得到,當(dāng)然也看了很多別人寫的文章,是可以被應(yīng)用到生產(chǎn)中。這次主要介紹三個(gè)方面,分別是壓縮 JavaScript 和 CSS、配置環(huán)境變量、ES 模塊機(jī)制帶來(lái)的Tree-shaking。
假設(shè)我們有一個(gè)前端開(kāi)發(fā)需求,這個(gè)需求有點(diǎn)特別,不是業(yè)務(wù)上的需求,而是要求減少文件的大小??芍@個(gè)需求算是性能優(yōu)化上范疇,減少文件大小,加速網(wǎng)絡(luò)傳輸,縮短網(wǎng)頁(yè)加載時(shí)間,增加用戶體驗(yàn),提高用戶滿意度。這是一個(gè)正向結(jié)果,得干~
壓縮 JavaScript這里不得不提一下 Google 的 Closure Compiler,一款可以讓 JavaScript 下載與執(zhí)行更快的工具,它的做法是執(zhí)行一些"焦土"(scorched-earth)優(yōu)化策略,它將函數(shù)展開(kāi),重寫變量名,過(guò)濾多余代碼,刪除從不會(huì)調(diào)用的函數(shù),從而生成可能是最優(yōu)化的代碼。如下
優(yōu)化前
function map(array, iteratee) { let index = -1 const length = array == null ? 0 : array.length const result = new Array(length) while (++index < length) { result[index] = iteratee(array[index], index, array) } return result }
優(yōu)化后
function map(n,e){let r=-1;for(const i=null==n?0:n.length,t=Array(i);++r對(duì)比發(fā)現(xiàn)優(yōu)化效果極好,如果使用 UglifyJS 一樣可以達(dá)到相同的優(yōu)化效果。由于 Webpack 內(nèi)置這款插件,可以直接使用,配置如下
// webpack.config.js const webpack = require("webpack"); module.exports = { plugins: [ new webpack.optimize.UglifyJsPlugin() ] };使用該插件優(yōu)化前后的對(duì)比結(jié)果如下說(shuō)明:
假設(shè)我們有一段代碼,如下:
// comments.js import "./comments.css"; export function render(data, target) { console.log("Rendered!"); }Webpack 編譯之后的代碼大概如下:
// bundle.js (part of) "use strict"; Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); var __WEBPACK_IMPORTED_MODULE_0__comments_css__ = __webpack_require__(4); var __WEBPACK_IMPORTED_MODULE_0__comments_css___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__comments_css__); __webpack_exports__["render"] = render; function render(data, target) { console.log("Rendered!"); }如果使用了 UglifyJS 插件,重新編譯之后的代碼大概如下:
// bundle.js (part of) "use strict";function r(e,t){console.log("Rendered!")} Object.defineProperty(t,"__esModule",{value:!0}); var o=n(4);n.n(o);t.render=r特殊情況說(shuō)明:目前,UglifyJS 2(Webpack自帶的) 是無(wú)法編譯 ES2015+ 的代碼,意味著如果代碼中是了類、箭頭函數(shù)或者其他新的特性,而且你沒(méi)有將代碼編譯為 ES5,那么 UglifyJS 插件是無(wú)法處理這些代碼的,這里提供兩種處理方法:
方法1:給 Webpack 添加支持 babel,基本過(guò)程如下
安裝 babel-core、babel-loader、babel-preset-es2015
npm i babel-core babel-loader babel-preset-es2015 --save-dev給 Webpack 添加配置信息
// webpack.config.js module.exports = { module: { rules: [ { test: /.js[x]$/, use: [{"babel-loader", options: { presets: ["es2015"] }] } ] } };方法2:使用 Babili 取代 UglifyJS 2,這是一款基于 Babel 的壓縮工具,更多了解查看 babili-webpack-plugin,這里不作太多的描述
壓縮 CSS壓縮 CSS 的方法比較簡(jiǎn)單,css-loader 就自帶壓縮功能,配置如下:
// webpack.config.js module.exports = { module: { rules: [ { test: /.css$/, use: [ "style-loader", { loader: "css-loader", options: { minimize: true } } ] } ] } };另外我還寫過(guò) Webpack 跟 Less 和 Sass 的配置教程,具體看:here1, here2
配置環(huán)境變量將NODE_ENV設(shè)置為production也能幫助減少前端項(xiàng)目大小
NODE_ENV通常作為環(huán)境變量被各種js框架或庫(kù)作為判斷條件去作為哪種執(zhí)行模式,如開(kāi)發(fā)模式或是生產(chǎn)模式,這些框架或者庫(kù)根據(jù)NODE_ENV的值去表現(xiàn)對(duì)應(yīng)的行為。例如,當(dāng)處于開(kāi)發(fā)模式時(shí),React 會(huì)做額外的檢測(cè)和打印警告:
// … if (process.env.NODE_ENV !== "production") { validateTypeDef(Constructor, propTypes, "prop"); } // …如果要打包構(gòu)建項(xiàng)目到生產(chǎn)環(huán)境中,最好可以告訴項(xiàng)目中的框架或庫(kù)當(dāng)前的環(huán)境變量是生產(chǎn)環(huán)境。對(duì)于適用于 Node.js 的庫(kù)來(lái)說(shuō),直接配置NODE_ENV為production即可,但對(duì)于 Web 端來(lái)說(shuō),可以使用 Webpack 自帶的插件實(shí)現(xiàn)對(duì)
process.env.NODE_ENV的設(shè)置,如下// webpack.config.js const webpack = require("webpack"); module.exports = { plugins: { new webpack.DefinePlugin({ "process.env.NODE_ENV": ""production"" }) } };DefinePlugin 允許我們創(chuàng)建全局變量,同時(shí)這些變量會(huì)作用于webpack的打包編譯期內(nèi)。它會(huì)代替所有的process.env.NODE_ENV實(shí)例的值為"production",從而使 UglifyJS 知道那些判斷表達(dá)式總是錯(cuò)誤的,從而刪除相關(guān)代碼,進(jìn)一步壓縮打包文件
ECMAScript模塊機(jī)制項(xiàng)目中使用 ECMAScript 的import、export,Webpack 通過(guò) tree-shaking 也能通過(guò)打包有用的代碼,進(jìn)一步減少大小。 Tree-shaking 可以檢查整個(gè)打包依賴樹(shù),找到使用的部分。所以如果使用 ECMAScript 模塊機(jī)制,Webpack 會(huì)去掉無(wú)用的代碼,如下:
假設(shè)寫了兩個(gè)文件,但只使用了其中一個(gè)文件
// comments.js export const commentRestEndpoint = "/rest/comments"; export const render = () => { return "Rendered!"; }; // index.js import { render } from "./a.js"; render();Webpack 知道componentRestEndpoint是沒(méi)有被使用,打包文件也不會(huì)有該入口
// bundle.js (part of) (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* unused harmony export commentRestEndpoint */ /* harmony export */__webpack_exports__["b"] = render; var commentRestEndpoint = "/rest/comments"; var render = function () { return "Rendered!"; } })UglifyJS 插件去掉無(wú)用部分
// bundle.js (part of) (function(n,e){"use strict";e.b=r;var r=function(){return"Rendered!"}})如果 JavaScript 框架或庫(kù)使用了 ECMAScript 模塊機(jī)制,那么 Tree-shaking 是對(duì)其也是有效滴
注意事項(xiàng)
1、 如果沒(méi)有 UglifyJS ,tree-shaking 將不作用
實(shí)際上,去掉無(wú)用的代碼不是 Webpack 本身,而是 UglifyJS。Webpack 只是去掉 export 表達(dá)式使那些 exports 不再使用,從而可以在壓縮的時(shí)候被去掉。因此,如果你打包的時(shí)候沒(méi)有使用壓縮,打包文件就不會(huì)變得更小
2、不要將 ES 模塊機(jī)制編譯為 CommonJS
如果你使用了 babel-preset-env 或 babel-preset-es2015,就需要檢查一下這些 preset 的配置了。默認(rèn)情況下,它們都會(huì)ES 模塊機(jī)制的語(yǔ)法特性重新編譯為 CommonJS,如將 ES 的import和export編譯為 CommonJS 的require和module.exports。我們可以使用 { modules: false } 禁止編譯行為,如下:
// webpack.config.js module.exports = { module: { rules: [ { test: /.js[x]$/, use: [{"babel-loader", options: { presets: [["es2015", { modules: false }]] }] } ] } };3、在特殊條件下 Webpack 不會(huì)進(jìn)行優(yōu)化
當(dāng)你使用了export * from "file.js" 或者是 TypeScript,Webpack 是不會(huì)進(jìn)行優(yōu)化。這些特殊條件在代碼中很難被發(fā)覺(jué),也很難知道這些特殊條件的代碼是否被修復(fù),更多了解可以查看 here
總結(jié)Webpack 對(duì)前端項(xiàng)目?jī)?yōu)化有很多種,這里提供了四種技巧,分別是通過(guò) UglifyJS 插件實(shí)現(xiàn)對(duì) JavaScript 文件的壓縮,css-loader 提供的壓縮功能,配置NODE_ENV可以進(jìn)一步去掉無(wú)用代碼,tree-shaking幫助找到更多無(wú)用代碼
內(nèi)容較多,大概就這樣~
文章首發(fā)于:https://www.linpx.com/p/webpa...
歡迎訪問(wèn)我的博客:https://www.linpx.com
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/87338.html
摘要:這里要介紹的是工作流中的一種很普遍的代碼加工流程正常的業(yè)務(wù)邏輯開(kāi)發(fā)流程需要經(jīng)過(guò)預(yù)處理器如或,然后再經(jīng)過(guò)后處理器如進(jìn)行深加工。 還未看的,可以點(diǎn)擊查看上兩篇文章喲:Webpack 最佳實(shí)踐總結(jié)(一)、Webpack 最佳實(shí)踐總結(jié)(二) 好了,這篇是第三篇,也是完結(jié)篇,我感覺(jué)這一篇是最亂的一篇,湊合著看吧,不會(huì)讓你失望的 整合 CSS 加工流 有時(shí)候,前端項(xiàng)目中除了 JavaScript ...
摘要:這里要介紹的是工作流中的一種很普遍的代碼加工流程正常的業(yè)務(wù)邏輯開(kāi)發(fā)流程需要經(jīng)過(guò)預(yù)處理器如或,然后再經(jīng)過(guò)后處理器如進(jìn)行深加工。 還未看的,可以點(diǎn)擊查看上兩篇文章喲:Webpack 最佳實(shí)踐總結(jié)(一)、Webpack 最佳實(shí)踐總結(jié)(二) 好了,這篇是第三篇,也是完結(jié)篇,我感覺(jué)這一篇是最亂的一篇,湊合著看吧,不會(huì)讓你失望的 整合 CSS 加工流 有時(shí)候,前端項(xiàng)目中除了 JavaScript ...
摘要:默認(rèn)做法是告訴瀏覽器這個(gè)文件的緩存時(shí)間,然后當(dāng)文件內(nèi)容被修改,則需要重命名該文件告訴瀏覽器需要重新下載和緩存,例如也能做類似的工作。 上一篇介紹了 Webpack 優(yōu)化項(xiàng)目的四種技巧,分別是通過(guò) UglifyJS 插件實(shí)現(xiàn)對(duì) JavaScript 文件的壓縮,css-loader 提供的壓縮功能,配置NODE_ENV可以進(jìn)一步去掉無(wú)用代碼,tree-shaking幫助找到更多無(wú)用代碼 ...
摘要:如果是在生產(chǎn)環(huán)境下,則加入插件,執(zhí)行代碼壓縮,并且去除。規(guī)定了在開(kāi)發(fā)環(huán)境下才使用。疑問(wèn)目前為止,對(duì)于多頁(yè)面項(xiàng)目還是沒(méi)有找到一個(gè)很好的方案去構(gòu)建自動(dòng)化。原文可以看我的博客最佳實(shí)踐部署生產(chǎn) tip webpack的入門篇可以看我的這一片博文?!度绾问褂脀ebpack—webpack-howto》. 前言 最近一段時(shí)間在項(xiàng)目中使用了webpack和React來(lái)開(kāi)發(fā),總之來(lái)說(shuō)也是遇到了許多坑,...
摘要:基本開(kāi)發(fā)環(huán)境創(chuàng)建的項(xiàng)目,作為代碼編寫工具插件推薦插件配置文章目錄項(xiàng)目目錄結(jié)構(gòu)介紹框架選擇處理請(qǐng)求二次封裝項(xiàng)目目錄結(jié)構(gòu)簡(jiǎn)介業(yè)務(wù)相關(guān)靜態(tài)文件全局組件基礎(chǔ)樣式布局樣式及工具引入請(qǐng)求配置路由全局狀態(tài)管理工具文件入口文件主要配置文件頁(yè)面檢查配置測(cè)試 基本開(kāi)發(fā)環(huán)境 vue-cli3 創(chuàng)建的項(xiàng)目,vscode 作為代碼編寫工具vscode插件推薦:vscode 插件配置 文章目錄 項(xiàng)目目錄結(jié)構(gòu)介紹...
閱讀 3622·2021-11-22 15:11
閱讀 4777·2021-11-18 13:15
閱讀 2771·2019-08-29 14:08
閱讀 3647·2019-08-26 13:49
閱讀 3149·2019-08-26 12:17
閱讀 3349·2019-08-26 11:54
閱讀 3183·2019-08-26 10:58
閱讀 2100·2019-08-26 10:21