02-Webpack4配置增強(qiáng)

我們已經(jīng)完成了基于React的腳手架工程的創(chuàng)建,現(xiàn)在讓我們來(lái)進(jìn)一步增強(qiáng)我們的工程,已方便日后的開發(fā)。

增強(qiáng)Webpack

清理 /dist 文件夾

dist文件夾里包含了我們生成的各種打包文件,我們更新生成配置后,如果不即使刪除里面的殘留文件,可能導(dǎo)致舊打包文件和新打包文件共存的情況。

我們可以在編譯時(shí)添加腳本刪除,如下所示:

"build": "rd /S /Q dist && webpack"

也可以通過(guò)Webpackclean-webpack-plugin插件來(lái)實(shí)現(xiàn)。

安裝插件yarn add -D clean-webpack-plugin

修改webpack.config.js文件,加入html-webpack-plugin插件

    // 管理插件,通過(guò)插件實(shí)現(xiàn)增強(qiáng)功能
    plugins: [
        // 每次編譯前清除dist文件夾
        new CleanWebpackPlugin(),
    ],

區(qū)分開發(fā)和生成環(huán)境

開發(fā)環(huán)境(development)和生產(chǎn)環(huán)境(production)的構(gòu)建目標(biāo)差異很大。在開發(fā)環(huán)境中,我們需要具有強(qiáng)大的、具有實(shí)時(shí)重新加載(live reloading)或熱模塊替換(hot module replacement)能力的 source map 和 localhost server。而在生產(chǎn)環(huán)境中,我們的目標(biāo)則轉(zhuǎn)向于關(guān)注更小的 bundle,更輕量的 source map,以及更優(yōu)化的資源,以改善加載時(shí)間。由于要遵循邏輯分離,我們通常建議為每個(gè)環(huán)境編寫彼此獨(dú)立的 webpack 配置。
基于以上原理,我們將原有的webpack.config.js一個(gè)配置文件分割為webpack.common.jswebpack.dev.jswebpack.prod.js三個(gè)配置文件。

首先安裝yarn add -D webpack-merge

根據(jù)原有webpack.config.js文件將對(duì)應(yīng)配置分散到三個(gè)配置文件中

webpack.common.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const webpack = require('webpack')

module.exports = {
    // 入口文件
    entry: './src/index.tsx',
    // 需要解析的文件后綴名
    resolve: {
        extensions: ['.tsx', '.ts', '.js']
    },
    // 管理插件,通過(guò)插件實(shí)現(xiàn)增強(qiáng)功能
    plugins: [
        // 自動(dòng)清理dist
        new CleanWebpackPlugin(),
        // 根據(jù)模板生成html
        new HtmlWebpackPlugin({
            title: 'My App',
            template: './src/index.html'
        }),
    ],
    // 配置項(xiàng)目處理的不同文件及模塊
    module: {
        rules: [
            {
                test: /\.(ts|tsx)?$/,
                loader: 'awesome-typescript-loader'
            },
        ]
    }
};

webpack.dev.js

const merge = require('webpack-merge')
const common = require('./webpack.common.js')
const webpack = require('webpack')
const path = require('path');

module.exports = merge(common, {
    // 標(biāo)識(shí)配置為開發(fā)用
    mode: 'development',
    // 控制是否生成,以及如何生成 source map
    devtool: 'cheap-module-eval-source-map',
    // 管理開發(fā)服務(wù)器
    devServer: {
        // 查找文件路徑
        contentBase: 'dist',
        // 啟用 HMR
        hot: true,
    },
    plugins: [
        // 當(dāng)開啟 HMR 的時(shí)候使用該插件會(huì)顯示模塊的相對(duì)路徑,建議用于開發(fā)環(huán)境
        new webpack.NamedModulesPlugin(),
        // 啟用 HMR 熱更新,建議用于開發(fā)環(huán)境
        new webpack.HotModuleReplacementPlugin()
    ],
    // 管理輸出
    output: {
        // 定義輸出文件名規(guī)則
        filename: '[name].bundle.js',
        // 定義輸出文件名路徑
        path: path.resolve(__dirname, 'dist'),
    },
})

webpack.prod.js

const merge = require('webpack-merge')
const common = require('./webpack.common.js')
const webpack = require('webpack')
const path = require('path');

module.exports = merge(common, {
    // 標(biāo)識(shí)配置為生產(chǎn)用
    mode: 'production',
    // 控制是否生成,以及如何生成 source map
    devtool: 'source-map',
    // 管理輸出
    output: {
        // 定義輸出文件名規(guī)則
        filename: '[name].[contenthash].js',
        // 定義輸出文件名路徑
        path: path.resolve(__dirname, 'dist'),
    },
})

最后修改package.json

"scripts": {
    "build": "webpack --config webpack.prod.js",
    "dev": "webpack-dev-server --config webpack.dev.js"
  },

Source Map說(shuō)明

Webpack的打包過(guò)程中,會(huì)對(duì)源代碼進(jìn)行壓縮,合并,編譯等操作,導(dǎo)致編譯后的代碼和源碼差異較大。為了更容易地追蹤錯(cuò)誤和警告,通過(guò)JavaScript 提供的source map功能,能夠?qū)⒕幾g后的代碼映射到源代碼上,便于錯(cuò)誤定位。

Webpack中,是通過(guò)devtool配置項(xiàng)來(lái)指定構(gòu)造的source map類型。配置項(xiàng)很多,但大致可以劃分為5類,其余配置項(xiàng)可以是其任意組合。

  • eval: 使用eval包裹模塊代碼,尾部通過(guò)souceURL來(lái)定位原始代碼位置,不產(chǎn)生.map文件
  • source-map: 產(chǎn)生.map文件,通過(guò).map文件定位
  • cheap: 不包含列信息(debug時(shí)注意點(diǎn)都在行數(shù)上,不用關(guān)心列數(shù))也不包含loader的sourcemap(意味著如果使用了類似bable類編譯工具,定位到的就是編譯后的代碼而非原始代碼)
  • module: 包含loader的sourcemap(比如babel的sourcemap)
  • inline: 將.map作為DataURI嵌入,不單獨(dú)生成.map文件

綜上所示,我們?cè)陂_發(fā)環(huán)境選用cheap-module-eval-source-map,就能夠定位到各個(gè)原始文件上。生產(chǎn)環(huán)境則考慮使用source-map

代碼壓縮

Webpack4的mode是production時(shí),會(huì)自動(dòng)開啟js的壓縮,不過(guò)這里我們還是使用uglifyjs-webpack-plugin插件。

安裝

yarn add -D uglifyjs-webpack-plugin

修改webpack.prod.js文件

module.exports = merge(common, {
    // 標(biāo)識(shí)配置為生產(chǎn)用
    mode: 'production',
    // 控制是否生成,以及如何生成 source map
    devtool: 'source-map',
    plugins: [
        new UglifyJSPlugin({
            sourceMap: true
        }),
    ],
    // 管理輸出
    output: {
        // 定義輸出文件名規(guī)則
        filename: '[name].[contenthash].js',
        // 定義輸出文件名路徑
        path: path.resolve(__dirname, 'dist'),
    },
})

這里需要注意一點(diǎn),UglifyJSPlugin壓縮插件不能解析es6語(yǔ)法,需要引入bable來(lái)處理es6,es7的js文件的編譯。

指定環(huán)境

程序中使用的某些第三方library可能會(huì)和process.env.NODE_ENV環(huán)境變量關(guān)聯(lián),比如在生產(chǎn)環(huán)境中增加額外的日志記錄或測(cè)試,在生產(chǎn)環(huán)境中增加一些優(yōu)化。因此我們根據(jù)不同的環(huán)境預(yù)設(shè)好process.env.NODE_ENV的值。NODE_ENV本質(zhì)上是Node.js露給執(zhí)行腳本的系統(tǒng)環(huán)境變量,同時(shí)并不能在Webpack.prod.js類似的構(gòu)建腳本中預(yù)設(shè)NODE_ENV的值,但我們可以通過(guò)webpack內(nèi)置的 DefinePlugin為所有的依賴定義這個(gè)變量。

對(duì)應(yīng)環(huán)境的webpack配置文件中增加如下所示的插件配置:

// 預(yù)設(shè)程序執(zhí)行環(huán)境
new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('production')
})
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容