摘要:前言本文基于,主要涉及基本概念基本配置和實際項目打包優化。關于概念方面參考官網,常用配置來自于網絡資源,在文末有相關參考鏈接,實踐部分基于自己的項目進行優化配置。同一文件中,修改某個影響其他。
前言:本文基于weboack4.x,主要涉及webpack4 基本概念、基本配置和實際項目打包優化。關于概念方面參考官網,常用配置來自于網絡資源,在文末有相關參考鏈接,實踐部分基于自己的項目進行優化配置。
webpack 四大概念 entry定義編譯打包入口文件。類型:字符串(單入口)、對象(多入口)
entry: "./src/index.js" // 等同于 entry: { main: "./src/index.js" }output
1、filename:
[name]: 對應著entry中對象的key
[id]: 內部的chumk id
[hash]: 每次打包編譯的唯一hash,改動會影響整個項目的打包,緩存失效
[chunkhash]:對應著每個入口文件計算而來的hash,唯一,文件之間互不影響
[contenthash]: contenthash = (moduleId + content) 生成的hash。同一文件中,修改某個module影響其他module。例如,js代碼中引入css文件,修改js文件造成css文件的hash改變
2、path: 是配置輸出文件存放在本地的目錄,字符串類型,是絕對路徑puclicPath: 對構建出的資源進行異步加載(圖片,文件) 時候的路徑前綴, 可以看作靜態文件托管在cdn
3、chunkFilename: 決定了非入口(non-entry) chunk 文件的名稱,如按需加載、異步加載
參考:從零搭建webpack4 之output輸出
Module 配置Loaderrules 數組,包含多個處理文件的 loader 配置
條件匹配: 通過test、include、exclude三個配置來命中Loader要應用的規則文件。
應用規則: 對選中后的文件通過use配置項來應用loader,可以應用一個loader或者按照從后往前的順序應用一組loader。同時還可以分別給loader傳入參數。
重置順序: 一組loader的執行順序默認是從有道左執行,通過exforce選項可以讓其中一個loader的執行順序放到最前或者是最后。
loader配置屬性test:類型正則、字符串、數組。匹配文件
use:類型字符串、對象、數組【loader字符串或對象】。對選中的文件應用loader。
對象中包含:loader、options:loader的具體配置參數、enforce: 改變該loader的執行的順序【pre/post】
include: 指定需要處理的文件。類型:一般為路徑、可以是數組類型。
exclude:排除不需要處理的文件。類型:一般為路徑、可以是數組類型。
noParse: 排除對沒有采用模塊化的文件解析和處理,類似:jQuery。 類型:RegExp, [RegExp], function其中一個。
parser:可以更細粒度的配置哪些模塊語法【AMD、CommonJS、ES6等】是否需要解析
Plugin 是用來擴展Webpack 功能的,通過在構建流程里注入鉤子實現,它為Webpack 帶
來了很大的靈活性。主要在打包的某個階段執行該插件,對文件進行處理,類似于鉤子函數
觸發treeshking條件:
1.需要代碼是es module規范的并且使用解構賦值的方式引入,
2.開啟optimization.usedExports:true來標記使用和未使用的模塊,
使用壓縮的插件進行刪除未使用代碼。
webpack4的mode設置為production,默認開啟optimization.usedExports和使用代碼壓縮
注:
1、tree shaking 不能作用于有副作用side-effect的代碼
如果所有代碼沒有副作用,在package.json 中添加
sideEffects: false
如果存在副作用代碼/模塊,
sideEffects: [ ".src/some-side-effectful-file.js", "*.css" ]
"side effect(副作用)" 的定義是,在導入時會執行特殊行為的代碼,而不是僅僅暴露一個 export 或多個 export。舉例說明,例如 polyfill,它影響全局作用域,并且通常不提供 export。
2、不要意外地將 ES 模塊編譯成 CommonJS 模塊。如果你使用 Babel 的時候,采用了 babel-preset-env 或者 babel-preset-es2015,請檢查這些預置的設置。默認情況下,它們會將 ES 的導入和導出轉換為 CommonJS 的 require 和 module.exports,可以通過設置.babelrc中 { modules: false } 選項來禁用它
參考:webpack tree shaking 的三個要點
HMR (Hot Module replacement)模塊熱替換devServer: { proxy: { "/api": { target: "http://localhost:3000", pathRewrite: {"^/api" : ""} }, context: ["/api", "/online"], //匹配多個路徑,同時代理到同一個站點 target: "http://localhost:3000" }, hot: true, hotOnly: true }code spiliting
把代碼分離到不同的 bundle 中,可以按需加載或并行加載這些文件
實現方式:
1、入口配置:entry 入口使用多個入口文件 =》 存在重復引用的模塊
2、抽取公有代碼:使用 SplitChunksPlugin 抽取公有代碼,取代CommonsChunkplugin
webpack.config.js 配置: ``` optimizition: { splitChunks: { chunks: "all" } } ```
3、動態加載 :動態加載一些代碼 =》 ECMAScript 提案 的 import() 語法
方式1 + 方式2 需要配合使用,才能達到代碼抽離的效果
prefetch(預取):將來某些導航下可能需要的資源
preload(預加載):當前導航下可能需要資源
import(/* webpackPrefetch: true */ "LoginModel");
/ webpackPrefetch: true /:把主加載流程加載完畢,在空閑時在加載其他,等再點擊其他時,只需要從緩存中讀取即可,性能更好。推薦使用,提高代碼利用率。把一些交互后才能用到的代碼寫到異步組件里,通過懶加載的形式,去把這塊的代碼邏輯加載進來,性能提升,頁面訪問速度更快。
/ webpackPreload: true /: 和主加載流程一起并行加載。
import() 異步加載加載的模塊,開啟代碼分割后,會被多帶帶打包在一個文件中
路由懶加載
const Login = () => import("./components/login")
模塊異步加載
import(/* webpackChunkName: "vendor"*/ "./page/vendor.js").then(({default: _}) => {// todo})公共代碼提取
mini-css-extract-plugin 用于提取公共css,取代 webpack 3 的 extract-text-webpack-plugin
注:一般適用于生產環境,在開發環境會導致HMR功能缺失;在開發環境,使用style-loader
使用方式:
const MiniCssExtractPlugin=require("mini-css-extract-plugin") const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin") // 代碼壓縮 // modules 中 // css,scss,sass,less { test:/.(sa|sc|c)ss$/, use: [ process.env.NODE_ENV === "development" ? "style-loader": MiniCssExtractPlugin.loader, "css-loader", "sass-loader" ] } optimization: { minimizer: [new OptimizeCssAssetsPlugin({})] }, //plugins中 new MiniCssExtractPlugin({ filename: "[name].css" })DllPlugin & DllReferencePlugin
防止第三方包多次編譯打包。 第一次打包時,把第三方模塊多帶帶打包生成一個文件 vendors.dll.js,之后在打包時就可以直接從 vendors.dll.js 中引入之前打包好的第三方模塊
實現過程:
1、編寫一個用于生成動態鏈接庫的配置文件
2、運行生成動態鏈接庫和對應的.mainfest.json映射文件
3、在webpack.config.js中使用動態鏈接庫。這樣第二次編譯打包會從json文件中找相應的模塊
webpack.dll.config.js
module.exports = { entry: { react: ["react"] //react模塊打包到一個動態連接庫 }, output: { path: path.resolve(__dirname, "dist"), filename: "[name].dll.js", //輸出動態連接庫的文件名稱 library: "_dll_[name]" //全局變量名稱 }, plugins: [ new webpack.DllPlugin({ name: "_dll_[name]", //和output.library中一致,值就是輸出的manifest.json中的 name值 path: path.join(__dirname, "dist", "[name].manifest.json") }) ] }
webpack.config.js
plugins: [ new webpack.DllReferencePlugin({ manifest: require(path.join(__dirname, "dist", "react.manifest.json")), }) ],
提高webpack的構建(打包/build)速度
多入口情況下,使用SplitChunk來提取公共代碼
通過externals配置來提取常用庫
利用DllPlugin和DllReferencePlugin預編譯資源模塊 通過DllPlugin來對那些我們引用但是絕對不會修改的npm包來進行預編譯,再通過DllReferencePlugin將預編譯的模塊加載進來。
使用Happypack 實現多線程加速編譯
使用webpack-uglify-parallel來提升uglifyPlugin的壓縮速度。 原理上webpack-uglify-parallel采用了多核并行壓縮來提升壓縮速度
使用Tree-shaking和Scope Hoisting來剔除多余代碼
模式分離webpack 作為模塊化打包工具, 常用來對項目進行打包進行本地調試和發布到線上,所以無論是自己在項目配置使用webpack還是使用開發框架的腳手架進行開發,都需要區分開發和生產環境。在webpack4 的配置項中添加了 mode屬性,可以用來區分兩者模式。
下面是開發和生產模式下一些默認配置和區別:
development 模式下,默認開啟了NamedChunksPlugin 和NamedModulesPlugin方便調試,提供了更完整的錯誤信息,更快的重新編譯的速度。
production 模式下,由于提供了splitChunks和minimize,代碼就會自動分割、壓縮、優化,同時 webpack 也會自動幫你 Scope hoisting 和 Tree-shaking
使用 webpack-bundle-analyzer, 可直觀的看出打包后每個模塊所占比例和大小
使用方法:
安裝
npm i -D webpack-bundle-analyzer
2.在 package.json -> script 中添加啟動命令
"analyz": "cross-env NODE_ENV=prodution npm_config_report=true npm run build"
3.在 webpack.pro.conf.js -> plugin 添加以下代碼,可以改變啟動時的端口等配置
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin
new BundleAnalyzerPlugin({analyzerPort: 8089})
關于使用方法詳細可參考:webpack實踐-webpack-bundle-analyzer使用
具體方案 路由懶加載import xxxx from "@componets/xxx" => const xxx = () => require("@componets/xxx")
模塊化按需加載對于一些類似antd、element-ui、eCharts等庫,可以按需引入,沒有必要全局引入,具體方法見官方文檔
對于loadash等API依賴工具,結合lodash-webpack-plugin和babel-plugin-lodash,實現按需引入,把需要的API一次性引入,并掛載在全局上
// 從lodash 中統一引入你需要的方法 import _ from "lodash" export default { cloneDeep: _.cloneDeep, debounce: _.debounce, throttle: _.throttle, size: _.size, pick: _.pick, isEmpty: _.isEmpty } // 注入到全局 import _ from "@helper/lodash.js" Vue.prototype.$_ = _ // vue 組件內運用 this.$_.debounce()外部模塊使用CDN
對于類似Jquery等大而使用較少的庫,可以在index.html使用cdn引入;如果顧慮到可能造成外部攻擊等問題,可以下載成為本地資源,再引入
參考:webpack 打包優化之體積篇
速度優化 實現方法 縮短路徑,減小文件搜索范圍1、縮小文件搜索范圍或者指定特定的文件夾位置
2、排除不需要進行處理的文件
......
不使用默認的 UglifyJs,使用并行壓縮工具 webpack-parallel-uglify-plugin
......
具體參考:webpack 打包優化之速度篇
實踐 vue 項目我是在我之前開發一大型項目使用webpack進行項目優化
注:此項目使用的webpack版本為2.x,不是最新版本4.x,由于項目比較復雜,升級帶來的潛在問題可能比較多,時間精力有限,暫時未升級
項目技術和庫:vue全家桶 + vue-cli + webpack + jQuery + element-UI + eCharts ...
按照上文中的常用配置,就打包速度和體積進行了優化,從而導致頁面加載速度得到一定提升
圖片上傳失敗,顯示不出來 【手動捂臉】
由于本文參考了許多相關文章,并加以自己的理解和實戰,如有不妥之處,請多包涵并指出,謝謝
參考:
webpack實踐——webpack-bundle-analyzer 的使用
從基礎到實戰 手摸手帶你掌握新版Webpack4.0詳解 教你看文檔
webpack 4.0 基礎到實戰配置github
webpack 官方文檔
關于webpack的面試題總結
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/104930.html
摘要:延伸閱讀學習與實踐資料索引與前端工程化實踐前端每周清單半年盤點之篇前端每周清單半年盤點之與篇前端每周清單半年盤點之篇 前端每周清單專注前端領域內容,以對外文資料的搜集為主,幫助開發者了解一周前端熱點;分為新聞熱點、開發教程、工程實踐、深度閱讀、開源項目、巔峰人生等欄目。歡迎關注【前端之巔】微信公眾號(ID:frontshow),及時獲取前端每周清單;本文則是對于半年來發布的前端每周清單...
摘要:發布是由團隊開源的,操作接口庫,已成為事實上的瀏覽器操作標準。本周正式發布,為我們帶來了,,支持自定義頭部與腳部,支持增強,兼容原生協議等特性變化。新特性介紹日前發布了大版本更新,引入了一系列的新特性與提升,本文即是對這些變化進行深入解讀。 showImg(https://segmentfault.com/img/remote/1460000012940044); 前端每周清單專注前端...
摘要:同構的關鍵要素完善的屬性及生命周期與客戶端的時機是同構的關鍵。的一致性在前后端渲染相同的,將輸出一致的結構。以上便是在同構服務端渲染的提供的基礎條件。可以將封裝至的中,在服務端上生成隨機數并傳入到這個中,從而保證隨機數在客戶端和服務端一致。 原文地址 React 的實踐從去年在 PC QQ家校群開始,由于 PC 上的網絡及環境都相當好,所以在使用時可謂一帆風順,偶爾遇到點小磕絆,也能夠...
摘要:本文介紹了作者接手維護一個中型歷史項目時的一系列改進實踐,包括模塊結構拆分業務邏輯梳理打包優化等。代碼中如菜單名稱結構表單字段名等的各種硬編碼配置分散在各處。最后,在提升面向開發者的打包體驗方面,本次優化中主要實現的是與的解耦。 本文介紹了作者接手維護一個中型 React 歷史項目時的一系列改進實踐,包括模塊結構拆分、業務邏輯梳理、Webpack 打包優化等。 背景 這是一個 PC 的...
摘要:前端每周清單半年盤點之與篇前端每周清單專注前端領域內容,以對外文資料的搜集為主,幫助開發者了解一周前端熱點分為新聞熱點開發教程工程實踐深度閱讀開源項目巔峰人生等欄目。與求同存異近日,宣布將的構建工具由遷移到,引發了很多開發者的討論。 前端每周清單半年盤點之 React 與 ReactNative 篇 前端每周清單專注前端領域內容,以對外文資料的搜集為主,幫助開發者了解一周前端熱點;分為...
閱讀 1517·2021-11-18 10:02
閱讀 1657·2021-09-04 16:40
閱讀 3171·2021-09-01 10:48
閱讀 874·2019-08-30 15:55
閱讀 1853·2019-08-30 15:55
閱讀 1365·2019-08-30 13:05
閱讀 3013·2019-08-30 12:52
閱讀 1624·2019-08-30 11:24