webpack配置解析


 webpack.config.js 文件解析

const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ClearWebpackPlugin = require('clear-webpack-plugin')

module.exports = {
  mode: 'development',   // 打包模式   測試環境/生產環境
  devtool: 'cheap-module-eval-source-map',   // 是否打包SourceMap文件, 映射代碼錯誤位置
  // 打包入口配置
  entry: {  
    main: './src/index.js',  
  },
  // 使用webpack-dev-server 插件,實現監聽代碼改動自動打包
  devServer: {
    contentBase: './dist',  // 監聽變化的文件
    open: true, // 是否自動打開瀏覽器
    port: 8080, // 監聽的端口
    hot: true,  // 是否啟動模塊代碼熱更新
    hotOnly: true, // 是否只刷新一次瀏覽器
  },
  // 配置編譯的各模塊 loader
  module: {
    noParse: /es6-promise\.js$/, // avoid webpack shimming process
    rules: [
      {
        test: /\.(js|vue)$/,
        loader: 'eslint-loader',
        enforce: 'pre',
        include: [path.resolve(__dirname, '../src/')],
        options: {
          formatter: require('eslint-friendly-formatter')
        }
      },
      // 使用 babel 把ES6轉換成ES5 ,需要配合 @babel/preset-env 
      // 配置ES6轉換成ES5過程中,按需補充必要代碼,在js文件中,需要引入 @babel/polyfill 插件,或者使用 @babel/plugin-transform-runtime
      {
        test: /\.(js|es6)$/,
        loader: 'babel-loader',  
        exclude: /node_modules/, // 表示除了該文件外
        options:{
          presets: [['@babel/preset-env', {
            useBuiltIns: 'usage'  
          }]]
        },
      },
    ]
  },
  // 編譯輸出配置
  output: {
    path: path.resolve(__dirname, '../dist2'),  // 輸出目錄
    publicPath: '/gsh/dist/',    // 輸出目錄添加地址前綴
    filename: '[name].[chunkhash].js'   // 編譯后輸出的文件名稱
  },// 使用 plugins 插件,實現編譯過程中自動使用某個 html模板,以及編譯前清除dist里的文件
  plugins: [
    new HtmlWebpackPlugin({
      template: 'src/index.html',  // 使用某個 html模板
    }),
    new ClearWebpackPlugin(['dist']), // 編譯前清除dist里的文件
    new webpack.HotModuleReplacementPlugin(),  // 使用HMR實現模塊代碼熱更新
  ],
}

 在生產環境和開發環境中,webpack的配置是有所區別的,可以把相同部分提取出來作為 common.js ,最后使用 webpack-merge 插件進行合並

 

 

Tree Shaking

含義為 ’搖樹‘ ,其作用是在打包過程中,去除某些在項目中並沒有引用的模塊,  只支持 ES Module 方式, 即 import

某些在代碼中引入的模塊,假如在邏輯中沒有使用到,那么在最后打包中不會被打包進去。

在 development 模式下,在webpack.config.js 文件中添加下列配置:

 optimization:{
    usedExports: true,
  }

在 package.js 文件中添加下列配置,表示除了某個文件外進行 Tree Shaking :

"sideEffects": ['*.css', '@babel/pollyfill']  // 表示遇到這兩個模塊忽略,可取值為 false

 

打包分析

可以使用webpack 官方提供的工具進行打包分析, 打開鏈接 https://github.com/webpack/analyse 查閱文檔, 點擊 analyse 位置進入分析工具,上傳 stats.json 文件

在打包的時候,生成 stats.json 文件, 生成方法為 : 在 package.json 文件打包命令中添加   --profile --json > stats.json

"scripts": { "build": "webpack --profile --json > stats.json --config ./build/webpack.dev.js", },

也可以采用 webpack 提供的圖形化分析工具  https://wenpack.js.org/guides     選擇 Code Splitting 目錄下的 Bundel Analysis

 

Code Splitting 代碼分割

根據代碼的應用場景和邏輯,打包的時候自動將代碼分割成多個 JS 文件, 避免過大的JS 文件出現,提升頁面渲染速度

同步代碼分割,在webpack.config.js 文件中添加下列配置:

  optimization:{
    splitChunks: {
      chunks: 'all'  // 開啟代碼分割
    }
  }

異步代碼(import):無需任何配置,webpack會自動進行代碼分割

chunks 取值 all , 表示同步代碼和異步代碼都進行代碼分割, 默認取值是 async , 表示只對異步代碼進行分割

關於代碼分割,webpack 推薦使用的是 async 的方式,這個涉及到頁面的代碼使用率,在瀏覽器控制台中, 使用 command + shift + p 的方式,搜索 Coverage 查看頁面代碼使用率

對於頁面渲染速度的優化,使用代碼緩存,並不能解決首屏加載速度的問題,應該盡量提升頁面代碼使用率,對於暫未使用到的代碼邏輯,采用懶加載的方式。如頁面調用的某個方法,方法內的邏輯在未被調用時就是多余的,可以采用異步的方法進行懶加載。

使用 webpack 里的 Prefetching / Preloading實現代碼的懶加載 ,  在引入代碼邏輯的時候添加  /*webpackPrefetch: true*/

例子:將某個方法里的邏輯 導出, 在調用時再作為模塊導入

// 新建 click.js 文件,將方法的執行邏輯導出
function handleClick() {
  const el = document.getElementById('test')
  el.innerHTML = '點擊頁面后生成'
}

export default handleClick;

// 在 main.js 文件中,方法導入執行邏輯
document.addEventListener('click', () => {
  import(/*webpackPrefetch: true*/ './click.js').then(({default: handleClick}) => {
    handleClick()
  })
})

 

PWA 

全稱 Progressive Web Application ,  這是一項新的技術,可以在用戶進入頁面的時候,緩存頁面內容。當服務器故障后,用戶重新進入這個頁面的時候,可以利用緩存正常顯示頁面。

在webpack 里,可以使用 workbox-webpack-plugin 插件實現。

const WorkboxPlugin = require('workbox-webpack-plugin')

// 在 plugins 添加下列配置
    new WorkboxPlugin.GenerateSw({
      clientsClaim: true,
      skipWaiting: true
    })

 

 

VUE 多頁面打包webpack配置

思路:多配置一個main的文件,用於webpack入口使用, 然后路由的導向也應該默認指向新組件,最后通過webpack構建出一個新的獨立的html文件。

 

缺點:生成多個html會new出多個vue實例,文件大小應該存在優化空間。

 

*注意:以下配置建議在**master分支**中進行(sit分支也可以,但是以下配置的prod相關文件需要換成配置到dev),因為在develop分支中配置有可能導致dev環境構建的過程沒有找到analysis模塊而無法yarn dev在本地跑通項目,影響開發。當然也可以再dev中配置成可在dev環境下忽略analysis.ts環境,這個看個人需求。

 

> 具體做法如下

 

1. 修改webpack入口文件 <u>webpack.base.conf.js</u>

 

/** 修改entry配置項 */
entry: {
style: './src/style/app.scss', // 不變
app: './src/main.ts', //不變, 這個是index.html的組件
analysis: './src/analysis.ts'
// analysis是新增的模塊名字(名字自定義,項目中因為是分析界面模塊所以取名為為analysis)
// 如果還有多個其他頁面,可以繼續添加模塊。。。
// P.S. 注意是模塊不是組件,例如個analysis模塊中實際包含ValueAnalysis,ValueAnalysisBar,ValueAnalysisType等組件,但是不必引入。
// P.S. 最后build打包的時候記得放出所有的模塊
}

 

 

2. 新增<u>analysis.ts</u>文件

 

/** 和main.src同級,創建analysis.ts文件,注意文件名字是對應上面的./src/analysis.ts文件 */
// analysis.ts
import Vue from 'vue'

// register plugins hooks fo vue component
import 'common/registerHooks'

import * as svgicon from 'vue-svgicon'
// import all icons
import 'components/icons'

import App from 'pages/App'

Vue.use(svgicon, {
tagName: 'icon'
})

new Vue({
el: '#app',
render: h => h(App)
})

// 內容基本上和main.src一樣, 但是注意router有所變化,這里router導入了一個新的路由文件routerAnalysis

 

 

3. 配置<u>build/config/index.js</u>文件

 

// 配置build中的文件輸出路徑,當然也可以不配置然后在下一步中直接書寫文件路徑,但是統一比較方便維護
build: {
index: path.resolve(__dirname, `../../dist/${env}/index.html`), // 默認的
analysis: path.resolve(__dirname, `../../dist/${env}/analysis.html`), //新加的模塊


...
...
// 其他配置項不變
}

 

 

4. 配置<u>webpack.prod.conf.js</u>文件

 

> 配置輸出多個html文件

 

/** 用HTMLWebpackPlugin生成多個文件 */


// 原本的htmlWebpackPlugin配置
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'build/tpl/index.html',
inject: true,
dllName,
assetsPublicPath: config.build.assetsPublicPath,
staticHost: '',
minify: {
removeComments: true,
collapseWhitespace: true
},
excludeChunks: ['analysis'], // index.html沒有用到analysis模塊的內容
chunksSortMode: 'dependency'
}),
// 想要生成多少不同的html就配置多少個new HtmlWebpackPlugin
new HtmlWebpackPlugin({
filename: config.build.analysis, // 生成的新的文件位置,步驟4中配置的路徑
template: 'build/tpl/index.html', // html依據模板,可以沿用index.html或者另外寫一個,看具體需求
inject: true,
dllName,
assetsPublicPath: config.build.assetsPublicPath,
staticHost: '',
minify: {
removeComments: true,
collapseWhitespace: true
},
excludeChunks: ['app'], // 該模塊沒有用到app模塊中的組件
chunksSortMode: 'dependency'
}),

 

 

完成配置后的內容,使用yarn build, 選deploy就可構建生成所需的多個html。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM