1. 程式人生 > 其它 >多頁面專案優化webpack打包降低上線風險

多頁面專案優化webpack打包降低上線風險

技術標籤:reactjswebpacknode.jsjavascript

目前的問題

專案中有多個入口,某些入口會提供出去給其他專案使用。這就要求專案的穩定性要高,如果出了問題可能會導致其他的相關聯專案也無法正常使用。(要背鍋)

由於目前整個專案的打包檔案用的同一套版本號,導致當對某個元件進行了修改,進行打包後,所有模組的版本號都會更新,快取將不能使用,所有模組都將更新,這會給專案上線帶來一些風險。

不得不每次上線之後都去對所有的服務進行驗證,哪怕是不涉及改動的,由於版本號更新了,也需要再去線上驗證一下有沒有問題。

目標

優化webpack打包配置,不同入口所打包出來的檔案使用獨立的版本號,只有當該入口所引用的檔案內容被修改時,才對該入口重新打包的檔案的版本號進行更新;所引用檔案內容未被修改時,該入口打包檔案的版本號不變。(概括為:改了才更新,不改不更新)

這樣一來,就不用擔心修改了專案某些元件後對其他的提供出去的服務造成影響,降低專案上線風險。

分析專案目前的webpack打包配置

目前專案的webpack配置如下,這裡打包後文件名中版本號用的hash,hash跟整個專案的構建相關,所有檔案雜湊值相同,當專案中有檔案被更改後,hash會改變,重新打包後所有打包檔案的檔名中的版本號也會統一改為新的雜湊值

//webpack.config.prod.js

var webpack = require('webpack');
var path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
var config = {
    entry:{
        index :__dirname + "/src/scripts/entries/Index.js",
        test :__dirname + "/src/scripts/entries/Test.js",
        main:__dirname + '/src/scripts/entries/main.js',
        weixin:__dirname + '/src/scripts/entries/weixin.js',
        jsbridge:__dirname + '/src/scripts/entries/jsbridge.js'
    },
    output: {
        path: path.resolve( __dirname,"dist"),
        publicPath: '/dist/',
        filename: '[name]-[hash:7].js'
    },

    ......//省略其他配置

    plugins: [
        new CleanWebpackPlugin(),
        new MiniCssExtractPlugin({
            filename: "[name]-[hash:7].css",
          })
    ]
};
module.exports = config;

目前使用hash作為檔案打包版本號的打包效果

執行npm run build 打包後如下圖可以看到,所有打包後的檔案的檔名中的版本號都是一樣的。

在這裡插入圖片描述

更改test.js的內容,再次打包如下圖,可以看到,哪怕是僅僅只修改了test.js,所有檔案的雜湊值都變了。

在這裡插入圖片描述

使用chunkhash作為檔案打包版本號

經瞭解,webpack中關於快取,還提供了其他的新增雜湊值的方法:chunkhash

chunkhash可以根據模組內容來新增雜湊值,只要模組內容沒有變,就不會生成新的雜湊值。emm,這貌似是我們想要的。

修改webpack配置如下:將hash替換為chunkhash

//webpack.config.prod.js

var webpack = require('webpack');
var path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
var config = {
    entry:{
        index :__dirname + "/src/scripts/entries/Index.js",
        test :__dirname + "/src/scripts/entries/Test.js",
        main:__dirname + '/src/scripts/entries/main.js',
        weixin:__dirname + '/src/scripts/entries/weixin.js',
        jsbridge:__dirname + '/src/scripts/entries/jsbridge.js'
    },
    output: {
        path: path.resolve( __dirname,"dist"),
        publicPath: '/dist/',
        filename: '[name]-[chunkhash:7].js'
    },

    ......//省略其他配置

    plugins: [
        new CleanWebpackPlugin(),
        new MiniCssExtractPlugin({
            filename: "[name]-[chunkhash:7].css",
          })
    ]
};
module.exports = config;

執行npm run build 打包後如下圖可以看到,不同模組的打包檔案使用了不同的雜湊值。

在這裡插入圖片描述

更改test.js的內容,再次打包如下圖,可以看到,test模組的打包檔案發生了改變,其他模組的打包沒有改變,nice啊,這就是我們想要的!

這樣就可以做到只更新內容被修改了的模組而不影響其他模組的程式碼了,真棒!

在這裡插入圖片描述

使用contenthash作為檔案打包版本號

使用chunkhash作為檔案打包版本號,貌似已經解決了我們的問題,但是他還是有一點小小的缺陷,當我們只修改了test.js時,css部分的檔案也被重新打包更新了,這樣貌似不太好。

這是由於test.css被test.js引用了,所以共用相同的chunkhash值,如果test.js更改了程式碼,css檔案就算內容沒有任何改變,由於是該模組發生了改變,導致css檔案會重複構建。

查詢資料後學習到,我們可以使用contenthash來解決這個問題。

修改webpack配置如下:將css部分的chunkhash替換為contenthash

//webpack.config.prod.js

var webpack = require('webpack');
var path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
var config = {
    entry:{
        index :__dirname + "/src/scripts/entries/Index.js",
        test :__dirname + "/src/scripts/entries/Test.js",
        main:__dirname + '/src/scripts/entries/main.js',
        weixin:__dirname + '/src/scripts/entries/weixin.js',
        jsbridge:__dirname + '/src/scripts/entries/jsbridge.js'
    },
    output: {
        path: path.resolve( __dirname,"dist"),
        publicPath: '/dist/',
        filename: '[name]-[chunkhash:7].js'
    },

    ......//省略其他配置

    plugins: [
        new CleanWebpackPlugin(),
        new MiniCssExtractPlugin({
            filename: "[name]-[contenthash:7].css",
          })
    ]
};
module.exports = config;

執行npm run build 打包後如下圖可以看到,相同模組的js檔案和css檔案也擁有了不同的雜湊值。

在這裡插入圖片描述

更改test.js的內容,再次打包如下圖,可以看到,test模組的js檔案發生了改變,而css檔案沒有發生改變

在這裡插入圖片描述

更改test.css的內容,再次打包如下圖,可以看到,test模組的css檔案發生了改變,而js檔案沒有發生改變,nice!完美解決了問題。

在這裡插入圖片描述

總結

  • 使用hash:所有檔案的雜湊值都會相同;
  • 使用chunkhash:會根據不同的入口檔案生成對應的雜湊值;
  • 使用contenthash:計算出的雜湊值與檔案內容本身相關,主要用在抽取css檔案時;
    nice!完美解決了問題。

[外鏈圖片轉存中…(img-gnpT9ar6-1612691376881)]

總結

  • 使用hash:所有檔案的雜湊值都會相同;
  • 使用chunkhash:會根據不同的入口檔案生成對應的雜湊值;
  • 使用contenthash:計算出的雜湊值與檔案內容本身相關,主要用在抽取css檔案時;
  • 這裡採用chunkhash + contenthash 達到了我們想要的模組獨立更新的效果,降低了專案上線更新的風險。