webpack 最全配置


const path = require('path')
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); // 壓縮css
const TerserPlugin = require('terser-webpack-plugin') // 壓縮js
/*
代碼分割有三種方法:
1 入口起點(diǎn):使用 entry 配置手動(dòng)地分離代碼。
2 防止重復(fù):使用 Entry dependencies 或者 SplitChunksPlugin 去重和分離chunk。
3 動(dòng)態(tài)導(dǎo)入:通過模塊的內(nèi)聯(lián)函數(shù) import 調(diào)用來分離代碼。
*/
/*
postcss-loader
npm i --save-dev autoprefixer
npm i -D postcss-nested
npm install -D style-loader css-loader postcss-loader postcss
可以使用 autoprefixer 插件為CSS 規(guī)則添加前綴
npm i --save-dev autoprefixer
可以使用 postcss-nested 插件為CSS提供編寫嵌套的樣式語法支持
npm i -D postcss-nested
postcss-loader 需要根據(jù) browserslist 獲取兼容范圍,所以需要在package.json 中標(biāo)明:
?"browserslist": [ // 更多的 browserslist 請(qǐng)參閱https://github.com/browserslist/browserslist#readme
? ?"> 1%", // 支持在全球使用率超過1%的瀏覽器
? ?"last 2 versions" // 每個(gè)瀏覽器中最新的兩個(gè)版本,注意 versions,帶s
?]
*/
/*
集成 typescript
npm i typescript -S
npm i ts-loader -D
在項(xiàng)目根目錄下添加一個(gè)ts的配置文件——tsconfig.json,我們可以用ts自帶的工具來自動(dòng)化生成它。
npx tsc --init
生成配置文件后,保留這些
{
?"compilerOptions": {
? ?"outDir": "./dist/",
? ?"noImplicitAny": true,
? ?"sourceMap": true,
? ?"module": "es6",
? ?"target": "es5",
? ?"jsx": "react",
? ?"allowJs": true,
? ?"moduleResolution": "node"
?}
}
*/
module.exports = {
?entry: {
? ?index: {
? ? ?import: './src/index.js', // 啟動(dòng)時(shí)需加載的模塊
? ? ?dependOn: 'common_chunk', // 當(dāng)前入口所依賴的入口
? ?},
? ?another: {
? ? ?import: './src/another_module.js',
? ? ?dependOn: 'common_chunk', // 當(dāng)前入口所依賴的入口
? ?},
? ?common_chunk: 'lodash' // 當(dāng)上面兩個(gè)模塊有l(wèi)odash這個(gè)模塊時(shí),就提取出來并命名為shared chunk
?},
?output: {
? ?// 將 js 文件放到一個(gè)文件夾中
? ?filename: 'js/bundle_[name]_[contenthash].js',
? ?path: path.resolve(__dirname, 'dist'),
? ?clean: true, // 在生成文件之前清空 output 目錄
? ?assetModuleFilename: 'images/[hash][ext][query]' // 這里
?},
?resolve: {
? ?extensions: ['.tsx', '.ts', '.js'],
?},
?optimization: {
? ?minimizer: [
? ? ?// 這將僅在mode: production 生產(chǎn)環(huán)境開啟 CSS 優(yōu)化
? ? ?// 如果還想在開發(fā)環(huán)境下啟用 CSS 優(yōu)化,optimization.minimize 設(shè)置為 true: ?minimize: true,
? ? ?new CssMinimizerPlugin(),
? ? ?new TerserPlugin()
? ?],
? ?splitChunks: {
? ? ?chunks: "all",
? ? ?cacheGroups: {
? ? ? ?// layouts通常是admin項(xiàng)目的主體布局組件,所有路由組件都要使用的
? ? ? ?// 可以單獨(dú)打包,從而復(fù)用
? ? ? ?// 如果項(xiàng)目中沒有,請(qǐng)刪除
? ? ? ?layouts: {
? ? ? ? ?name: "layouts",
? ? ? ? ?test: path.resolve(__dirname, "../src/layouts"),
? ? ? ? ?priority: 40,
? ? ? ?},
? ? ? ?// 如果項(xiàng)目中使用element-plus,此時(shí)將所有node_modules打包在一起,那么打包輸出文件會(huì)比較大。
? ? ? ?// 所以我們將node_modules中比較大的模塊單獨(dú)打包,從而并行加載速度更好
? ? ? ?// 如果項(xiàng)目中沒有,請(qǐng)刪除
? ? ? ?elementUI: {
? ? ? ? ?name: "chunk-elementPlus",
? ? ? ? ?test: /[\\/]node_modules[\\/]_?element-plus(.*)/,
? ? ? ? ?priority: 30,
? ? ? ?},
? ? ? ?// 將vue相關(guān)的庫單獨(dú)打包,減少node_modules的chunk體積。
? ? ? ?vue: {
? ? ? ? ?name: "vue",
? ? ? ? ?test: /[\\/]node_modules[\\/]vue(.*)[\\/]/,
? ? ? ? ?chunks: "initial",
? ? ? ? ?priority: 20,
? ? ? ?},
? ? ? ?libs: {
? ? ? ? ?name: "chunk-libs",
? ? ? ? ?test: /[\\/]node_modules[\\/]/,
? ? ? ? ?priority: 10, // 權(quán)重最低,優(yōu)先考慮前面內(nèi)容
? ? ? ? ?chunks: "initial",
? ? ? ?},
? ? ?}
? ?}
?},
?plugins: [
? ?new MiniCssExtractPlugin({filename: 'styles/[hash].css'})
?],
?module: {
? ?rules: [
? ? ?/*
? ? ?useBuiltIns
? ? ?參數(shù)有 “entry”、“usage”、false 三個(gè)值
? ? ?默認(rèn)值是 false ,此參數(shù)決定了babel打包時(shí)如何處理 @babel/polyfill 語句。
? ? ?“entry”: 會(huì)將文件中 import '@babel/polyfill' 語句 結(jié)合 targets ,轉(zhuǎn)換為一系列引入語句,去掉目標(biāo)瀏覽器已支持的 polyfill 模塊,不管代碼里有沒有用到,只要目標(biāo)瀏覽器不支持都會(huì)引入對(duì)應(yīng)的 polyfill 模塊。
? ? ?“usage”: 不需要手動(dòng)在代碼里寫 import '@babel/polyfill' ,打包時(shí)會(huì)自動(dòng)根據(jù)實(shí)際代碼的使用情況,結(jié)合 targets 引入代碼里實(shí)際用到部分 polyfill 模塊
? ? ?false: 對(duì) import '@babel/polyfill' 不作任何處理,也不會(huì)自動(dòng)引入 polyfill 模塊。需要注意的是在 webpack 打包文件配置的 entry 中引入的 @babel/polyfill 不會(huì)根據(jù) useBuiltIns 配置任何轉(zhuǎn)換處理。
? ? ?由于 @babel/polyfill 在7.4.0中被棄用,我們建議直接添加corejs并通過corejs選項(xiàng)設(shè)置版本
? ? ?npm i core-js@3 -S
? ? ?npm i babel-loader @babel/core @babel/preset-env -D
? ? ?npm install --save @babel/runtime
? ? ?npm install -D @babel/plugin-transform-runtime
? ? ?*/
? ? ?{
? ? ? ?test: /\.ts$/,
? ? ? ?use: [
? ? ? ? ?{
? ? ? ? ? ?loader: 'babel-loader',
? ? ? ? ? ?options: {
? ? ? ? ? ? ?plugins: ['@babel/plugin-transform-runtime'],
? ? ? ? ? ? ?presets: [
? ? ? ? ? ? ? ?[
? ? ? ? ? ? ? ? ?'@babel/preset-env',
? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ?// 項(xiàng)目所支持的瀏覽器的配置
? ? ? ? ? ? ? ? ? ?targets: [ // 告訴@babel/preset-env遇到了這樣的瀏覽器需要通過Polyfills使用添加墊片
? ? ? ? ? ? ? ? ? ? ?'> 1%', // 支持市場份額超過 1% 的瀏覽器
? ? ? ? ? ? ? ? ? ? ?'last 2 version', // 支持每一個(gè)瀏覽器最后兩個(gè)版本
? ? ? ? ? ? ? ? ? ? ?'safari >= 7', // 大于等于7版本的 safari
? ? ? ? ? ? ? ? ? ?],
? ? ? ? ? ? ? ? ? ?useBuiltIns: 'usage',
? ? ? ? ? ? ? ? ? ?corejs: 3, // 添加corejs配置
? ? ? ? ? ? ? ? ?},
? ? ? ? ? ? ? ?],
? ? ? ? ? ? ?],
? ? ? ? ? ?},
? ? ? ? ?},
? ? ? ? ?{ loader: 'ts-loader'},
? ? ? ? ?{ loader: 'eslint-loader' },
? ? ? ?],
? ? ? ?exclude: /node_modules/,
? ? ?},
? ? ?{
? ? ? ?test: /\.js$/,
? ? ? ?exclude: /node_modules/,
? ? ? ?use: [
? ? ? ? ?{
? ? ? ? ? ?loader: 'babel-loader',
? ? ? ? ? ?options: {
? ? ? ? ? ? ?plugins: ['@babel/plugin-transform-runtime'],
? ? ? ? ? ? ?presets: [
? ? ? ? ? ? ? ?[
? ? ? ? ? ? ? ? ?'@babel/preset-env',
? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ?// 項(xiàng)目所支持的瀏覽器的配置
? ? ? ? ? ? ? ? ? ?targets: [ // 告訴@babel/preset-env遇到了這樣的瀏覽器需要通過Polyfills使用添加墊片
? ? ? ? ? ? ? ? ? ? ?'> 1%', // 支持市場份額超過 1% 的瀏覽器
? ? ? ? ? ? ? ? ? ? ?'last 2 version', // 支持每一個(gè)瀏覽器最后兩個(gè)版本
? ? ? ? ? ? ? ? ? ? ?'safari >= 7', // 大于等于7版本的 safari
? ? ? ? ? ? ? ? ? ?],
? ? ? ? ? ? ? ? ? ?useBuiltIns: 'usage',
? ? ? ? ? ? ? ? ? ?corejs: 3, // 添加corejs配置
? ? ? ? ? ? ? ? ?},
? ? ? ? ? ? ? ?],
? ? ? ? ? ? ?],
? ? ? ? ? ?},
? ? ? ? ?},
? ? ? ? ?{
? ? ? ? ? ?loader: 'eslint-loader',
? ? ? ? ?},
? ? ? ?]
? ? ?},
? ? ?{
? ? ? ?test: /\.css$/i,
? ? ? ?use: [
? ? ? ? ?MiniCssExtractPlugin.loader, 'css-loader',
? ? ? ? ?{
? ? ? ? ? ?loader: 'postcss-loader',
? ? ? ? ? ?options: {
? ? ? ? ? ? ?postcssOptions: { // 也可使用 PostCSS 配置文件 postcss.config.js 代替
? ? ? ? ? ? ? ?plugins: [
? ? ? ? ? ? ? ? ?require('autoprefixer'), // 為CSS 規(guī)則添加前綴
? ? ? ? ? ? ? ? ?require('postcss-nested'), // 為CSS提供編寫嵌套的樣式語法
? ? ? ? ? ? ? ?],
? ? ? ? ? ? ?},
? ? ? ? ? ?},
? ? ? ? ?},
? ? ? ?],
? ? ?},
? ? ?{
? ? ? ?test: /\.(png|svg|jpg|jpeg|gif)$/i,
? ? ? ?type: 'asset/resource',
? ? ? ?parser: {
? ? ? ? ?// 如果不設(shè)置 maxSize,
? ? ? ? ?// webpack 將按照默認(rèn)條件,自動(dòng)地在 resource 和 inline 之間進(jìn)行選擇:小于 8kb 的文件
? ? ? ? ?dataUrlCondition: {
? ? ? ? ? ?maxSize: 4 * 1024 // 4kb
? ? ? ? ?}
? ? ? ?}
? ? ?},
? ? ?{
? ? ? ?test: /\.(woff|woff2|eot|ttf|otf)$/i,
? ? ? ?type: 'asset/resource',
? ? ? ?generator: {
? ? ? ? ?filename: 'fonts/[name]_[hash][ext]'
? ? ? ?}
? ? ?},
? ? ?// asset/resource 發(fā)送一個(gè)單獨(dú)的文件并導(dǎo)出 URL。之前通過使用 file-loader 實(shí)現(xiàn)。
? ? ?// asset/inline 導(dǎo)出一個(gè)資源的 data URI。之前通過使用 url-loader 實(shí)現(xiàn)。
? ? ?// asset/source 導(dǎo)出資源的源代碼。之前通過使用 raw-loader 實(shí)現(xiàn)。
? ? ?// asset 在導(dǎo)出一個(gè) data URI 和發(fā)送一個(gè)單獨(dú)的文件之間自動(dòng)選擇。之前通過使用 url-loader,并且配置資源體積限制實(shí)現(xiàn)。
? ? ?/*
? ? ? ?自定義輸出文件名
? ? ? ?output: {
? ? ? ? ?filename: 'bundle.js',
? ? ? ? ?path: path.resolve(__dirname, 'dist'),
? ? ? ? ?assetModuleFilename: 'images/[hash][ext][query]' // 這里
? ? ? ?},
? ? ?*/
? ?],
?},
}
/*
dev 和 prod config 配置文件的區(qū)別:
?output: {
? ?filename: 'js/[name].[contenthash].js', // 出口文件名
?},
?output: {
? ?filename: 'js/[name].js', // 出口文件名
?},
?devtool: 'inline-source-map', // dev
?devServer mode
?optimization: {
? ?minimize: true, // 開發(fā)環(huán)境下啟用 CSS 優(yōu)化
?},
?optimization: {
? ?minimizer: [
? ? ?new CssMinimizerPlugin(), // css 壓縮
? ? ?new TerserPlugin() // js 壓縮
? ?],
?},
?合并配置文件
?const { merge } = require('webpack-merge')
?const commonConfig = require('./webpack.config.common.js')
?const productionConfig = require('./webpack.config.prod.js')
?const developmentConfig = require('./webpack.config.dev.js')
?module.exports = (env) =>{
? ?switch (true)
? ? ?case env.development:
? ? ? ?return merge(commonConfig, developmentConfig)
? ? ?case env.production:
? ? ? ?return merge(commonConfig, productionConfig)
? ? ?default:
? ? ? ?throw new Error('No matching configuration was found!');
? ?}
?}
?修改package.json npm腳本
?{
? ?"scripts": {
? ? ?"start": "webpack serve -c ./config/webpack.config.js --env development",
? ? ?"build": "webpack -c ./config/webpack.config.js --env production"
? ?},
?}
*/