搜尋
首頁web前端js教程在Webpack中有關優化設定問題

在Webpack中有關優化設定問題

Jun 15, 2018 pm 03:37 PM
webpack最佳化

這篇文章主要介紹了Webpack優化-縮小文件搜尋範圍的相關知識,文中較詳細的給大家介紹了可以優化的途徑,需要的朋友可以參考下

Webpack 啟動後會從配置的Entry 出發,解析出檔案中的導入語句,再遞歸的解析。

在遇到導入語句時 Webpack 會做兩件事:

1.依照導入語句去尋找對應的要導入的檔案。例如 require('react') 導入語句對應的檔案是 ./node_modules/react/react.js , require('./util') 對應的檔案是 ./util.js 。

2.根據找到的要匯入檔案的後綴,使用設定中的 Loader 去處理檔案。例如使用 ES6 開發的 JavaScript 檔案就需要使用 babel-loader 去處理。

以上兩件事雖然對於處理一個檔案非常快,但是當專案大了以後檔案量會變的非常多,這時候建置速度慢的問題就會暴露出來。

雖然以上兩件事情無法避免,但需要盡量減少以上兩件事情的發生,以提高速度。

接下來一一介紹可以優化它們的途徑。

優化 loader 設定

由於 Loader 對檔案的轉換操作很耗時,需要讓盡可能少的檔案被 Loader 處理。

在 2-3 Module 中介紹過在使用 Loader 時可以透過 test 、 include 、 exclude 三個設定項來命中 Loader 要套用規則的檔案。

為了盡可能少的讓檔案被 Loader 處理,可以透過 include 去命中只有哪些檔案需要被處理。

以採用ES6 的專案為例,在設定babel-loader 時,可以這樣:

module.exports = {
 module: {
  rules: [
   {
    // 如果项目源码中只有 js 文件就不要写成 /\.jsx?$/,提升正则表达式性能
    test: /\.js$/,
    // babel-loader 支持缓存转换出的结果,通过 cacheDirectory 选项开启
    use: ['babel-loader?cacheDirectory'],
    // 只对项目根目录下的 src 目录中的文件采用 babel-loader
    include: path.resolve(__dirname, 'src'),
   },
  ]
 },
};

你可以適當的調整專案的目錄結構,以方便在設定Loader 時透過include 去縮小命中範圍。

優化resolve.modules 設定

在2-4 Resolve 中介紹過resolve.modules 用來設定Webpack 去哪些目錄下尋找第三方模組。

resolve.modules 的預設值是 ['node_modules'] ,意思是先去目前目錄下的./node_modules 目錄下去找想找的模組,如果沒找到就去上一級目錄../node_modules 中找,再沒有就去../../node_modules 中找,以此類推,這和Node.js 的模組尋找機制很相似。

當安裝的第三方模組都放在專案根目錄下的./node_modules 目錄下時,沒有必要按照預設的方式去一層層的尋找,可以指明存放第三方模組的絕對路徑,以減少尋找,配置如下:

module.exports = {
 resolve: {
  // 使用绝对路径指明第三方模块存放的位置,以减少搜索步骤
  // 其中 __dirname 表示当前工作目录,也就是项目根目录
  modules: [path.resolve(__dirname, 'node_modules')]
 },
};

##優化resolve.mainFields 配置

在2-4 Resolve 中介紹過resolve.mainFields 用於配置第三方模組使用哪個入口檔案。

安裝的第三方模組中都會有一個package.json 檔案用於描述這個模組的屬性,其中有些欄位用於描述入口檔案在哪裡, resolve.mainFields 用於配置採用哪個欄位作為入口文件的描述。

可以存在多個欄位來描述入口檔案的原因是因為有些模組可以同時用在多個環境中,準對不同的運作環境需要使用不同的程式碼。

以 isomorphic-fetch 為例,它是 fetch API 的實現,但可同時用於瀏覽器和 Node.js 環境。

它的package.json 中就有2個入口檔案描述欄位:

{
 "browser": "fetch-npm-browserify.js",
 "main": "fetch-npm-node.js"
}

isomorphic-fetch 在不同的運作環境下使用不同的程式碼是因為fetch API 的實作機制不一樣,在瀏覽器中透過原生的fetch 或XMLHttpRequest 實現,在Node.js 中透過http 模組實現。

resolve.mainFields 的預設值和目前的target 配置有關係,對應關係如下:

  • 當target 為web 或webworker 時,值為["browser" , "module", "main"]

  • 當target 為其它情況時,值為["module", "main"]

以target 等於web 為例,Webpack 會先採用第三方模組中的browser 字段去尋找模組的入口文件,如果不存在就採用module 字段,以此類推。

為了減少搜尋步驟,當你明確第三方模組的入口檔案描述欄位時,你可以把它設定的盡量少。

由於大多數第三方模組都採用main 欄位去描述入口檔案的位置,可以這樣設定Webpack:

module.exports = {
 resolve: {
  // 只采用 main 字段作为入口文件描述字段,以减少搜索步骤
  mainFields: ['main'],
 },
};

使用本方法最佳化時,你需要考慮到所有執行時間所依賴的第三方模組的入口文件描述字段,就算有一個模組搞錯了都可能會造成構建出的程式碼無法正常運作。

優化resolve.alias 配置

#在2-4 Resolve 中介紹過resolve.alias 配置項目透過別名來將原始導入路徑映射成一個新的導入路徑。

在實戰專案中常常會依賴一些龐大的第三方模組,以 React 函式庫為例,安裝到 node_modules 目錄下的 React 函式庫的目錄結構如下:

├── dist
│   ├── react.js
│   └── react.min.js
├── lib
│   ... 还有几十个文件被忽略
│   ├── LinkedStateMixin.js
│   ├── createClass.js
│   └── React.js
├── package.json
└── react.js

可以看到发布出去的 React 库中包含两套代码:

  • 一套是采用 CommonJS 规范的模块化代码,这些文件都放在 lib 目录下,以 package.json 中指定的入口文件 react.js 为模块的入口。

  • 一套是把 React 所有相关的代码打包好的完整代码放到一个单独的文件中,这些代码没有采用模块化可以直接执行。其中 dist/react.js 是用于开发环境,里面包含检查和警告的代码。 dist/react.min.js 是用于线上环境,被最小化了。

默认情况下 Webpack 会从入口文件 ./node_modules/react/react.js 开始递归的解析和处理依赖的几十个文件,这会时一个耗时的操作。

通过配置 resolve.alias 可以让 Webpack 在处理 React 库时,直接使用单独完整的 react.min.js 文件,从而跳过耗时的递归解析操作。

相关 Webpack 配置如下:

module.exports = {
 resolve: {
  // 使用 alias 把导入 react 的语句换成直接使用单独完整的 react.min.js 文件,
  // 减少耗时的递归解析操作
  alias: {
   'react': path.resolve(__dirname, './node_modules/react/dist/react.min.js'),
  }
 },
};

除了 React 库外,大多数库发布到 Npm 仓库中时都会包含打包好的完整文件,对于这些库你也可以对它们配置 alias。
但是对于有些库使用本优化方法后会影响到后面要讲的 使用 Tree-Shaking 去除无效代码 的优化,因为打包好的完整文件中有部分代码你的项目可能永远用不上。

一般对整体性比较强的库采用本方法优化,因为完整文件中的代码是一个整体,每一行都是不可或缺的。

但是对于一些工具类的库,例如 lodash ,你的项目可能只用到了其中几个工具函数,你就不能使用本方法去优化,因为这会导致你的输出代码中包含很多永远不会执行的代码。

优化 resolve.extensions 配置

在导入语句没带文件后缀时,Webpack 会自动带上后缀后去尝试询问文件是否存在。

在 2-4 Resolve 中介绍过 resolve.extensions 用于配置在尝试过程中用到的后缀列表,默认是:

extensions: ['.js', '.json']

也就是说当遇到 require('./data') 这样的导入语句时,Webpack 会先去寻找 ./data.js 文件,如果该文件不存在就去寻找 ./data.json 文件,如果还是找不到就报错。

如果这个列表越长,或者正确的后缀在越后面,就会造成尝试的次数越多,所以 resolve.extensions 的配置也会影响到构建的性能。

在配置 resolve.extensions 时你需要遵守以下几点,以做到尽可能的优化构建性能:

  • 后缀尝试列表要尽可能的小,不要把项目中不可能存在的情况写到后缀尝试列表中。

  • 频率出现最高的文件后缀要优先放在最前面,以做到尽快的退出寻找过程。

  • 在源码中写导入语句时,要尽可能的带上后缀,从而可以避免寻找过程。例如在你确定的情况下把 require('./data') 写成 require('./data.json') 。

相关 Webpack 配置如下:

module.exports = {
 resolve: {
  // 尽可能的减少后缀尝试的可能性
  extensions: ['js'],
 },
};

优化 module.noParse 配置

在 2-3 Module 中介绍过 module.noParse 配置项可以让 Webpack 忽略对部分没采用模块化的文件的递归解析处理,这样做的好处是能提高构建性能。

原因是一些库,例如 jQuery 、ChartJS, 它们庞大又没有采用模块化标准,让 Webpack 去解析这些文件耗时又没有意义。

在上面的 优化 resolve.alias 配置 中讲到单独完整的 react.min.js 文件就没有采用模块化,让我们来通过配置 module.noParse 忽略对 react.min.js 文件的递归解析处理,

相关 Webpack 配置如下:

const path = require('path');
module.exports = {
 module: {
  // 独完整的 `react.min.js` 文件就没有采用模块化,忽略对 `react.min.js` 文件的递归解析处理
  noParse: [/react\.min\.js$/],
 },
};

注意被忽略掉的文件里不应该包含 import 、 require 、 define 等模块化语句,不然会导致构建出的代码中包含无法在浏览器环境下执行的模块化语句。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在微信小程序中如何获取用户信息(详细教程)

使用百度地图如何去掉marker覆盖物具体该如何解决

在微信小程序中如何实现animation动画

在微信小程序中如何才能获取图片信息

使用百度地圖api如何清除指定覆蓋物Overlay具體怎麼做?

以上是在Webpack中有關優化設定問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python vs. JavaScript:性能和效率注意事項Python vs. JavaScript:性能和效率注意事項Apr 30, 2025 am 12:08 AM

Python和JavaScript在性能和效率方面的差異主要體現在:1)Python作為解釋型語言,運行速度較慢,但開發效率高,適合快速原型開發;2)JavaScript在瀏覽器中受限於單線程,但在Node.js中可利用多線程和異步I/O提升性能,兩者在實際項目中各有優勢。

JavaScript的起源:探索其實施語言JavaScript的起源:探索其實施語言Apr 29, 2025 am 12:51 AM

JavaScript起源於1995年,由布蘭登·艾克創造,實現語言為C語言。 1.C語言為JavaScript提供了高性能和系統級編程能力。 2.JavaScript的內存管理和性能優化依賴於C語言。 3.C語言的跨平台特性幫助JavaScript在不同操作系統上高效運行。

幕後:什麼語言能力JavaScript?幕後:什麼語言能力JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript在瀏覽器和Node.js環境中運行,依賴JavaScript引擎解析和執行代碼。 1)解析階段生成抽象語法樹(AST);2)編譯階段將AST轉換為字節碼或機器碼;3)執行階段執行編譯後的代碼。

Python和JavaScript的未來:趨勢和預測Python和JavaScript的未來:趨勢和預測Apr 27, 2025 am 12:21 AM

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

Python vs. JavaScript:開發環境和工具Python vs. JavaScript:開發環境和工具Apr 26, 2025 am 12:09 AM

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

JavaScript是用C編寫的嗎?檢查證據JavaScript是用C編寫的嗎?檢查證據Apr 25, 2025 am 12:15 AM

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

JavaScript的角色:使網絡交互和動態JavaScript的角色:使網絡交互和動態Apr 24, 2025 am 12:12 AM

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C和JavaScript:連接解釋C和JavaScript:連接解釋Apr 23, 2025 am 12:07 AM

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。