React項目中webpack的配置過程

初始化一個web項目
使用npm init -y 初始化一個項目
在項目目錄下創建src, dist文件夾,創建webpack.config.js配置文件
然後在src文件夾下創建index.js, index.html文件
然後安裝依賴包
npm i jquery -S 安裝jQuery包
npm i webpack webpack-cli webpack-dev-server html-webpack-plugin -D 安裝開發調試包
安裝loader調試工具
yarn add style-loader css-loader sass-loader node-sass url-loader file-loader  --dev
安裝babel預編譯工具, babel-loader@7需要添加版本號,否則可能導致babel-loader與babel-core版本不兼容問題
yarn add babel-loader@7 babel-core babel-plugin-transform-runtime babel-preset-env babel-preset-stage-0 babel-preset-react  --dev
安裝項目工具和UI庫
yarn add react react-dom  [email protected] [email protected]
編寫index.js腳本文件
import $ from 'jquery'

$(function () {
    $('li:odd').css('backgroundColor','pink')
    $('li:even').css('backgroundColor','lightblue')
})
在index.html中導入index.js腳本文件
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./index.js"></script>
</head>
編寫webpack.config.js配置文件
const path = require('path')
const htmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    mode: 'development',
    //項目的入口與出口設置
    entry: path.join(__dirname, './src/index.js'),
    output: {
        path: path.join(__dirname, './dist'),
        filename: 'bundle.js'
    },
    plugins: [ //插件
        //在內存中生成一個頁面,默認在項目的根目錄下的內存中
        new htmlWebpackPlugin({
            //頁面模板
            template: path.join(__dirname, './src/index.html'),
            filename: 'index.html'
        })
    ]
}
在package.json項目配置中添加短命令
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    // --cacheBase: 指定託管目錄, 如果沒指定默認在項目內存的根目錄下
    "dev": "webpack-dev-server --open --port 3000 --hot"
  },
執行npm run dev 進行打包調試
 
 
添加調試工具
添加loader加載器和babel預編譯工具

添加loader加載器,讓webpack處理js模塊外的其他模塊。
webpack默認只能打包處理以.js結尾的模塊。其他非.js後綴名結尾的模塊,webpack默認是不處理的。
需要調用loader加載器纔可以正常打包,loader加載器的作用:協作webpack打包處理約定的文件模塊。比如:css-loader: 可以打包處理.css相關的文件。
使用scss設置css樣式,需要使用css-loader解析器進行解析
npm i style-loader css-loader sass-loader node-sass url-loader file-loader -D
js中es6高級語法解析
npm i babel-core babel-loader babel-plugin-transform-runtime babel-preset-env babel-preset-stage-0 -D
在webpack.config.js中添加loader加載器配置
    module: {
        rules: [
            { test: /\.css$/, use:['style-loader', 'css-loader'] },
            { test: /\.scss$/, use:['style-loader', 'css-loader', 'sass-loader'] },
            { test: /\.(png|gif|bmp|jpg)$/, use: 'url-loader?limit=500000' },
            { test: /\.js$/, use:'babel-loader', exclude: /node_modules/ },
        ]
    }

 

開發完成,打包發佈
新建發佈配置文件webpack.pub.config.js
修改它的產物名稱配置文件
module: {
    rules: [
        { test: /\.css$/, use:['style-loader', 'css-loader'] },
        { test: /\.scss$/, use:['style-loader', 'css-loader', 'sass-loader'] },
        { test: /\.(png|gif|bmp|jpg)$/, use: 'url-loader?limit=5000&name=[hash:8]-[name].[ext]' },
        { test: /\.js$/, use:'babel-loader', exclude: /node_modules/ },
    ]
}

在package.json配置文件中,添加短命令pub,並在webpack命令中添加使用的配置文件名參數

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "--cacheBase": "指定託管目錄, 如果沒指定默認在項目內存的根目錄下",
    "dev": "webpack-dev-server --open --port 3000 --hot",
    "pub": "webpack --config webpack.pub.config.js"
  },
調用指令npm run pub, 打包出資源bundle.js, 圖片, index.html。
zhoufeideMacBook-Pro-2:webpack zhoufei$ npm run pub

> [email protected] pub
> webpack --config webpack.pub.config.js

assets by path *.jpg 61.5 KiB
  asset 56e2b290-phone1.jpg 61.5 KiB [emitted] [immutable] [from: src/images/phone1.jpg] (auxiliary name: main)
  asset 7a417220207de157cf21.jpg 63 bytes [emitted] [immutable] [from: src/images/phone1.jpg] (auxiliary name: main)
asset bundle.js 344 KiB [emitted] (name: main)
asset index.html 660 bytes [emitted]

 

webpack編譯器優化
1.產物圖片優化
把項目中的所有圖片在產物中放到一個images文件夾下面
通過修改webpack.pub.config.js中的module.rules項
{ test: /\.(png|gif|bmp|jpg)$/, use: 'url-loader?limit=5000&name=images/[hash:8]-[name].[ext]' },
2.產物目錄dist重建優化
每次生成產物時,都對dist目錄進行先清理,再生成
npm i clean-webpack-plugin -D

webpack.pub.config.js中進行配置清理插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

plugins: [ //插件
    /*
        每次構建產物都要重新創建dist目錄保存產物
    */
    new CleanWebpackPlugin({cleanAfterEveryBuildPatterns:['dist']})
],
3.抽離第三方包
發佈思路:bundle.js中只存放自己的代碼,第三方包的代碼都抽離到另外的JS包中
webpack@4以後的版本,棄用了許多@3的插件,其中包括:
分離打包js文件的插件 webpack.optimize.CommonChunkPlugin();
壓縮js文件的插件 webpack.optimize.UglifyJsPlugin();
定義產品上線環境webpack.optimize.DedupePlugun();
分離css文件插件extract-text-webpack-plugin();
css文件壓縮插件 CssMinimizerPlugin();
webpack3的抽離方法
在webpack.pub.config.js中修改entry的設置爲如下:
//app和vendors的key名稱都是自己自定義的,隨便取的
entry: {
    app: path.join(__dirname, './src/index.js'),
    vendors: ['jquery'] //把要抽離的第三方包放到這個數組中
}, 

在pulgins的數組中添加抽離設置
new webpack.optimize.CommonsChunkPlugin({
    name: 'vendors', //指定抽離的入口
    filename: 'vendors.js' //抽離的所有第三方包的結果包名稱。
})


然後將js文件放到一個統一的目錄下:
output: {
    path: path.join(__dirname, './dist'),
    filename: 'js/bundle.js'
},
4.壓縮js代碼
在webpack.pub.config.js中的 plugins項目下,添加下面的js優化代碼
js代碼壓縮優化
new webpack.optimize.UglifyJsPlugin({
    compress: { //配置壓縮項
        warnings: false //移除警告
    }
}),
new webpack.optimize.DedupePlugin({
    'process.env.NODE_ENV': '"production"'
})
5.壓縮html代碼
在htmlWebpackPlugin模板中添加html優化配置
new htmlWebpackPlugin({
    //頁面模板
    template: path.join(__dirname, './src/index.html'),
    filename: 'index.html',
    minify: {
        collapseWhitespace: true, //合併多餘的空格
        removeComments: true, // 移除註釋
        removeAttributeQuotes: true //移除屬性上的雙引號
    }
}),
6.從bundle.js中抽離css單獨存放
yarn add extract-text-webpack-plugin --dev
修改webpack.pub.config.js文件

const ExtractTextPlugin = require('extract-text-webpack-plugin')
添加插件
plugins: [ //插件

    //配置提取出來的css名稱
    new ExtractTextPlugin({
        filename: 'style/[name].min.css' 
    })
],
修改css-loader的rules
module: {
    rules: [
        { test: /\.css$/, use: ExtractTextPlugin.extract({
            fallback: 'style-loader',
            use: 'css-loader',
            publicPath: '../' //指定抽離的時候,自動爲我們使用的路徑加上 ../前綴
        }) },
        { test: /\.scss$/, use: ExtractTextPlugin.extract({
            fallback: 'style-loader',
            use: ['css-loader', 'sass-loader'],
            publicPath: '../' //指定抽離的時候,自動爲我們使用的路徑加上 ../前綴
        }) },
    ]
}
7.壓縮css
yarn add optimize-css-assets-webpack-plugin --dev
修改webpack.pub.config.js文件

// 壓縮css插件
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')

plugins: [ //插件
    /*
        壓縮css
    */
    new OptimizeCssAssetsPlugin()
],

 

webpack項目模板
dev的webpack開發模板
const path = require('path')
const htmlWebpackPlugin = require('html-webpack-plugin')
const { name } = require('file-loader')

module.exports = {
    mode: 'development',
    //項目的入口與出口設置
    entry: path.join(__dirname, './src/index.js'),
    output: {
        path: path.join(__dirname, './dist'),
        filename: 'bundle.js'
    },
    plugins: [ //插件
        //在內存中生成一個頁面,默認在項目的根目錄下的內存中
        /*
            html-webpack-plugin的作用有2個:
            1.自動將./src/index.html頁面複製一份到項目根目錄,放到了內存中。
            2.在內存中自動生成的index.html頁面裏,自動注入webpack打包的存在於內存中的bundle.js文件
        */
        new htmlWebpackPlugin({
            //頁面模板
            template: path.join(__dirname, './src/index.html'),
            filename: 'index.html'
        })
    ],
    /*
        webpack默認只能打包處理以.js結尾的模塊。其他非.js後綴名結尾的模塊,webpack默認是不處理的。
        需要調用loader加載器纔可以正常打包,loader加載器的作用:協作webpack打包處理約定的文件模塊。比如:css-loader: 可以打包處理.css相關的文件。
    */
    module: {
        rules: [
            { test: /\.css$/, use:['style-loader', 'css-loader'] },
            //聲明css模塊化,使用CSS模塊化解決多個css的作用域都是全局作用域,導致結果互相覆蓋的情況
            //一般第三方庫的樣式文件是以css結尾的,所以不能直接對css開啓模塊化,會影響其他第三方庫的展示,這裏只對scss進行開啓模塊化
            // { test: /\.css$/, use:['style-loader', {
            //     loader: 'css-loader',
            //     options: {
            //         importLoaders: 1,
            //         modules: true,
            //         //自定義css模塊化後的class名稱
            //         // localIdentName: [name]-[local]-[hash:5]
            //     }
            // }] },
            { test: /\.scss$/, use:['style-loader', {
                loader: 'css-loader',
                options: {
                    importLoaders: 1,
                    modules: true,
                    //自定義css模塊化後的class名稱
                    // localIdentName: [name]-[local]-[hash:5]
                }
            }, 'sass-loader'] },
            { test: /\.(png|gif|bmp|jpg)$/, use: 'url-loader?limit=500000' },
            { test: /\.jsx?$/, use:'babel-loader', exclude: /node_modules/ },
        ]
    }
}
pub的webpack發佈模板
const path = require('path')
const htmlWebpackPlugin = require('html-webpack-plugin')
//導入每次刪除文件夾的插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const webpack = require('webpack')
// 抽取Css插件
const ExtractTextPlugin = require('extract-text-webpack-plugin')
// 壓縮css插件
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')

module.exports = {
    mode: 'production',
    //項目的入口與出口設置
    entry: path.join(__dirname, './src/index.js'),
    //app和vendors的key名稱都是自己自定義的,隨便取的
    // entry: {
    //     app: path.join(__dirname, './src/index.js'),
    //     vendors: ['jquery'] //把要抽離的第三方包放到這個數組中
    // }, 
    output: {
        path: path.join(__dirname, './dist'),
        filename: 'js/bundle.js'
    },
    plugins: [ //插件
        //在內存中生成一個頁面,默認在項目的根目錄下的內存中
        /*
            html-webpack-plugin的作用有2個:
            1.自動將./src/index.html頁面複製一份到項目根目錄,放到了內存中。
            2.在內存中自動生成的index.html頁面裏,自動注入webpack打包的存在於內存中的bundle.js文件
        */
        new htmlWebpackPlugin({
            //頁面模板
            template: path.join(__dirname, './src/index.html'),
            filename: 'index.html',
            minify: {
                collapseWhitespace: true, //合併多餘的空格
                removeComments: true, // 移除註釋
                removeAttributeQuotes: true //移除屬性上的雙引號
            }
        }),
        /*
            每次構建產物都要重新創建dist目錄保存產物
        */
        new CleanWebpackPlugin({cleanAfterEveryBuildPatterns:['dist']}),

        new OptimizeCssAssetsPlugin()

        /*
            編譯優化:抽離第三方包名稱
            webpack3的在plugins數組中添加new webpack.optimize.CommonsChunkPlugin配置方式已經廢棄,要在下面的方法進行實現
            webpack3實現方法
            new webpack.optimize.CommonsChunkPlugin({
                name: 'vendors', //指定抽離的入口
                filename: 'vendors.js' //抽離的所有第三方包的結果包名稱。
            })
            webpack5設置無效,先註釋
        */

        /*
            編譯優化:js代碼壓縮優化
            new webpack.optimize.UglifyJsPlugin({
                compress: { //配置壓縮項
                    warnings: false //移除警告
                }
            }),
            new webpack.optimize.DedupePlugin({
                'process.env.NODE_ENV': '"production"'
            })
        */

        /*
            編譯優化:抽離css
            //配置提取出來的css名稱
            new ExtractTextPlugin({
                filename: 'style/[name].min.css' 
            })
        */

    ],

    // webpack V5替代webpack V3的解決方案
    // optimization: {
    //     splitChunks: {
    //         cacheGroups: {
    //             commons: {
    //                 test: /[\\/]node_modules[\\/]/,
    //                 name: 'vendors',
    //                 chunks: 'all',
    //             },
    //         }
    //     }

    // },

    /*
        webpack默認只能打包處理以.js結尾的模塊。其他非.js後綴名結尾的模塊,webpack默認是不處理的。
        需要調用loader加載器纔可以正常打包,loader加載器的作用:協作webpack打包處理約定的文件模塊。比如:css-loader: 可以打包處理.css相關的文件。
        產物圖片優化:
        把項目中的所有圖片在產物中放到一個images文件夾下面
        { test: /\.(png|gif|bmp|jpg)$/, use: 'url-loader?limit=5000&name=images/[hash:8]-[name].[ext]' },
        
    */
    module: {
        rules: [
            { test: /\.css$/, use:['style-loader', 'css-loader'] },
            //聲明css模塊化,使用CSS模塊化解決多個css的作用域都是全局作用域,導致結果互相覆蓋的情況
            //一般第三方庫的樣式文件是以css結尾的,所以不能直接對css開啓模塊化,會影響其他第三方庫的展示,這裏只對scss進行開啓模塊化
            // { test: /\.css$/, use:['style-loader', {
            //     loader: 'css-loader',
            //     options: {
            //         importLoaders: 1,
            //         modules: true,
            //         //自定義css模塊化後的class名稱
            //         // localIdentName: [name]-[local]-[hash:5]
            //     }
            // }] },
            { test: /\.scss$/, use:['style-loader', {
                loader: 'css-loader',
                options: {
                    importLoaders: 1,
                    modules: true,
                    //自定義css模塊化後的class名稱
                    // localIdentName: [name]-[local]-[hash:5]
                }
            }, 'sass-loader'] },
            { test: /\.(png|gif|bmp|jpg)$/, use: 'url-loader?limit=500000' },
            { test: /\.jsx?$/, use:'babel-loader', exclude: /node_modules/ },
        ]
    }

}
對應package.json依賴關係和scripts短命令
{
  "name": "webpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "--cacheBase": "指定託管目錄, 如果沒指定默認在項目內存的根目錄下",
    "dev": "webpack-dev-server --open --port 3000 --hot",
    "pub": "webpack --config webpack.pub.config.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "7",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "clean-webpack-plugin": "^4.0.0",
    "css-loader": "^6.8.1",
    "extract-text-webpack-plugin": "^3.0.2",
    "file-loader": "^6.2.0",
    "html-webpack-plugin": "^5.5.3",
    "node-sass": "^9.0.0",
    "optimize-css-assets-webpack-plugin": "^6.0.1",
    "sass-loader": "^13.3.2",
    "style-loader": "^3.3.3",
    "url-loader": "^4.1.1",
    "webpack": "^5.89.0",
    "webpack-cli": "^5.1.4",
    "webpack-dev-server": "^4.15.1"
  },
  "dependencies": {
    "antd": "^5.10.1",
    "jquery": "^3.7.1",
    "prop-types": "^15.8.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "4.2.2"
  }
}
.babelrc模板
{
    "presets": ["env", "stage-0", "react"],
    "plugins": ["transform-runtime"]
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章