webpack5基础和配置

初步体验webpack打包

webpack是一个静态资源打包工具。
它会以一个或多个文件作为打包的入口,将我们整个项目所有文件编译组合成一个或多个文件输出出去。
输出的文件就是编译好的文件,就可以在浏览器段运行了。
1.初始化最简单的一个目录文件,手动创建
在这里插入图片描述
main.js

import count from "./js/count";
import sum from "./js/sum";

console.log(count(2,1));
console.log(sum(1,2,3,4));

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h3>webpack</h3>
    <!-- 这里直接运行报错 浏览器不识别ES6模块化 -->
    <!-- <script src="../src/main.js"></script> -->
    <!-- 运行的时候改成这个路径,webpack打包好的js文件 -->
    <script src="../dist/main.js"></script>
</body>
</html>

2.下载依赖
npm init -y
初始化package.json文件 修改一下 main 的路径 ./src/main.js

{
  "name": "webpack_code",
  "version": "1.0.0",
  "description": "",
  "main": "./src/main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

注意:package.json中name字段不能叫做webpack,否则下一步会报错
npm i webpack webpack-cli -D
3.启用webpack
开发模式
npx webpack ./src/main.js --mode=development
生产模式
npx webpack ./src/main.js --mode=production (生产环境会对代码压缩,文件非常小)

默认webpack会将文件打包输出到dist目录下,我们查看dist目录下文件情况就好了

npx webpack:是用来运行本地安装 webpack包的。
./src/main.js:指定webpack从main.js文件开始打包,不但会打包main.js,还会将其依赖也一起打包进来。
–mode=xxx:指定模式(环境)

webpack本身功能比较少,只能处理js资源,一旦遇到css等其他资源就会报错。

5大核心概念

1.entry(入口)
指示webpack从哪个文件开始打包
2.outpu(输出)
指示webpack打包完的文件输出到哪里去,如何命名等
3.loader(加载器)
webpack本身只能处理js、json等资源,其他资源需要借助loader,webpack才能解析
4.plugins(插件)
扩展webpack的功能
5.mode(模式)
主要由两种模式:
开发模式:development
生成模式:production
准备webpack配置文件
在项目 根目录 新建文件:webpack.config.js

const path=require('path');//nodejs核心模块,专门用来处理路径问题
module.exports={
     //入口
    entry:'./src/main.js', //相对路径
     //输出
    output:{
        //文件的输出路径
        //__dirname  nodejs的变量,代表当前文件的文件夹目录
        path:path.resolve(__dirname,'dist'),//绝对路径
        //文件名
        filename:'main.js'
    },
     //加载器
    module:{
        rules:[
            //loader的配置
        ]
    },
     //插件
    plugins:[
        //plugin的配置
    ],
     //模式
    mode:'development',
}

运行打包:npx webpack

开发模式介绍

1.编译代码,使浏览器能识别运行
开发时我们有样式资源,字体图标,图片资源,html资源等,webpack默认都不能处理这些资源,所以我们要加载配置来编译这些资源
2.代码质量检查,树立代码规范
提前检查代码的一些隐患,让代码运行时能更加健壮。
提前检查代码规范和格式,统一团队编码风格,让代码更优雅美观。
官方文档

处理样式资源Css资源

(less,sass也是这样的处理步骤)
1,下载包
npm i css-loader style-loader -D
css-loader:负责将css文件编译成webpack能识别的模块
style-loader:会动态创建一个style标签,里面放置webpack中css模块内容

2. 创建一个css资源引入
main.js

import count from "./js/count";
import sum from "./js/sum";
//想要webpack打包资源,必须引入该资源
import './css/index.css'
console.log(count(2,1));
console.log(sum(1,2,3,4));

3.webpack.config.js 配置(如果有less,sass往rules里面添加即可)
处理图片资源 不需要下载和配置,如果想转换base64就需要配置一下
修改输出文件目录
处理字体图标资源
处理其他资源(比如视频,音频等等)

const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
module.exports={
     //入口
    entry:'./src/main.js', //相对路径
     //输出
    output:{
        //所有文件的输出路径
        //__dirname  nodejs的变量,代表当前文件的文件夹目录
        path:path.resolve(__dirname,'dist'),//绝对路径
        //入口文件打包输出文件名
        filename:'static/js/main.js',
        //原理,在打包前,将path整个目录内容清空,再进行打包
        clean:true, //自动清空上次打包内容
    },
     //加载器
    module:{
        rules:[
            //loader的配置
            {
                test:/\.css$/i, //只检测.css结尾的文件
                use:[ //执行顺序,从右到左(从下到上)
                    "style-loader", //将js中css通过创建style标签添加html文件中生效
                    "css-loader"  //将css资源编译成commonjs的模块到js中
                ]
            },
            {
                test: /\.less$/i,
                use: [
                  // 使用多个loader
                  'style-loader',
                  'css-loader',
                  'less-loader', //将less编译成css文件
                ],
            },
            {
                test:/\.(png|jpe?g|glf|webp|svg)$/,
                type:"asset",
                parser:{
                    dataUrlCondition:{
                        //小于10kb的图片转base64
                        //优点,减少请求数量,缺点,体积会更大
                        maxSize:10 * 1024,//10kb
                    }
                },
                generator:{
                    //输出图片名称
                    //[hash:10] hash值取前10位
                    filename:"static/images/[hash:10][ext][query]"
                }
            },
            {
                test:/\.(ttf|woff2?|mp3|mp4|avi)$/,  //处理字体图标资源或者其他资源
                type:"asset/resource",
                generator:{
                    //输出名称
                    filename:"static/media/[hash:10][ext][query]"
                }
            },
            {
                test:/\.js$/,  //处理字体图标资源或者其他资源
                exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
                loader:'babel-loader',
                //写这里也行,写外面babel.config.js里面也行
                // options:{
                //     presets:["@babel/preset-env"]
                // }
            }
        ]
    },
     //插件
    plugins:[
        //plugin的配置
        new ESLintPlugin({
            //检测哪些文件
            context:path.resolve(__dirname,"src"),
        }),
        new HtmlWebpackPlugin({
            //模板。以public/index.html文件创建新的html文件
            //新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
            template:path.resolve(__dirname,"public/index.html")
        })
    ],
    //开发服务器:不会输出资源,在内存中编译打包
    devServer:{
        host:'localhost',//启动服务器域名
        port:'3000',//启动服务器端口
        open:true,//是否自动打开浏览器
    },
     //模式
    mode:'development',
}

eslint使用

它是用来检测js和jsx语法的工具,可以配置各项功能
使用eslint,关键是写eslint配置文件,里面写上各种rules规则,将来运行eslint时就会以写的规则对代码进行检查
配置文件由很多种写法:
.eslintrc.*:新建文件,位于项目根目录
配置说明
1.下载包
npm i eslint-webpack-plugin eslint -D

vscode可以安装一个插件 ESLint
安装了这个插件就需要在配置一个文件 .eslintignore
忽略dist文件,里面的不检查

dist

2.定义.eslintrc.js 配置文件

module.exports={
    //继承Eslint规则
    extends:['eslint:recommended'],
    env:{
        node:true,//启用node中全局变量
        browser:true,//启用浏览器中全局变量
    },
    parserOptions:{
        ecmaVersion:6, //语法环境ES6
        sourceType:'module' //es  module
    },
    rules:{
        "no-var":2 ,//不能使用var定义变量
    }
}

babel使用

主要用于将ES6语法编写的代码转换为向后兼容的JavaScript语法,以便能够运行在当前和旧版本的浏览器或其他环境中
1.下载
npm i babel-loader @babel/core @babel/preset-env -D

2.定义babel配置文件 babel.config.js

module.exports={
    //智能预设,能够编译ES6语法
    presets:["@babel/preset-env"]
}

处理html资源

1.下载
npm install --save-dev html-webpack-plugin
2.引入

const HtmlWebpackPlugin=require('html-webpack-plugin')

自动化
每次写完代码都需要手动输入指令才能编译代码,太麻烦,希望一切自动化
1.下载
npm i webpack-dev-server -D

2.配置 webpack.config.js

//开发服务器:不会输出资源,在内存中编译打包
    devServer:{
        host:'localhost',//启动服务器域名
        port:'3000',//启动服务器端口
        open:true,//是否自动打开浏览器
    },

3.运行
npx webpack serve

生产模式

生产模式是开发完成代码后,需要得到代码将来部署上线
主要对代码进行优化,让其运行性能更好。
1,优化代码运行性能
2,优化代码打包速度
准备两个配置文件来放不同的配置
在这里插入图片描述
webpack.dev.js 文件

const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
module.exports={
     //入口
    entry:'./src/main.js', //相对路径
     //输出
    output:{
        //所有文件的输出路径
        //开发模式没有输出
        path:undefined,
        //入口文件打包输出文件名
        filename:'static/js/main.js',
    },
     //加载器
    module:{
        rules:[
            //loader的配置
            {
                test:/\.css$/i, //只检测.css结尾的文件
                use:[ //执行顺序,从右到左(从下到上)
                    "style-loader", //将js中css通过创建style标签添加html文件中生效
                    "css-loader"  //将css资源编译成commonjs的模块到js中
                ]
            },
            {
                test: /\.less$/i,
                use: [
                  // 使用多个loader
                  'style-loader',
                  'css-loader',
                  'less-loader', //将less编译成css文件
                ],
            },
            {
                test:/\.(png|jpe?g|glf|webp|svg)$/,
                type:"asset",
                parser:{
                    dataUrlCondition:{
                        //小于10kb的图片转base64
                        //优点,减少请求数量,缺点,体积会更大
                        maxSize:10 * 1024,//10kb
                    }
                },
                generator:{
                    //输出图片名称
                    //[hash:10] hash值取前10位
                    filename:"static/images/[hash:10][ext][query]"
                }
            },
            {
                test:/\.(ttf|woff2?|mp3|mp4|avi)$/,  //处理字体图标资源或者其他资源
                type:"asset/resource",
                generator:{
                    //输出名称
                    filename:"static/media/[hash:10][ext][query]"
                }
            },
            {
                test:/\.js$/,  //处理字体图标资源或者其他资源
                exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
                loader:'babel-loader',
                //写这里也行,写外面babel.config.js里面也行
                // options:{
                //     presets:["@babel/preset-env"]
                // }
            }
        ]
    },
     //插件
    plugins:[
        //plugin的配置
        new ESLintPlugin({
            //检测哪些文件
            context:path.resolve(__dirname,"../src"),
        }),
        new HtmlWebpackPlugin({
            //模板。以public/index.html文件创建新的html文件
            //新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
            template:path.resolve(__dirname,"../public/index.html")
        })
    ],
    //开发服务器:不会输出资源,在内存中编译打包
    devServer:{
        host:'localhost',//启动服务器域名
        port:'3000',//启动服务器端口
        open:true,//是否自动打开浏览器
    },
     //模式
    mode:'development',
}

运行
npx webpack serve --config ./config/webpack.dev.js

webpack.prod.js 文件

const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
module.exports={
     //入口
    entry:'./src/main.js', //相对路径
     //输出
    output:{
        //所有文件的输出路径
        //__dirname  nodejs的变量,代表当前文件的文件夹目录
        path:path.resolve(__dirname,'../dist'),//绝对路径
        //入口文件打包输出文件名
        filename:'static/js/main.js',
        //原理,在打包前,将path整个目录内容清空,再进行打包
        clean:true, //自动清空上次打包内容
    },
     //加载器
    module:{
        rules:[
            //loader的配置
            {
                test:/\.css$/i, //只检测.css结尾的文件
                use:[ //执行顺序,从右到左(从下到上)
                    "style-loader", //将js中css通过创建style标签添加html文件中生效
                    "css-loader"  //将css资源编译成commonjs的模块到js中
                ]
            },
            {
                test: /\.less$/i,
                use: [
                  // 使用多个loader
                  'style-loader',
                  'css-loader',
                  'less-loader', //将less编译成css文件
                ],
            },
            {
                test:/\.(png|jpe?g|glf|webp|svg)$/,
                type:"asset",
                parser:{
                    dataUrlCondition:{
                        //小于10kb的图片转base64
                        //优点,减少请求数量,缺点,体积会更大
                        maxSize:10 * 1024,//10kb
                    }
                },
                generator:{
                    //输出图片名称
                    //[hash:10] hash值取前10位
                    filename:"static/images/[hash:10][ext][query]"
                }
            },
            {
                test:/\.(ttf|woff2?|mp3|mp4|avi)$/,  //处理字体图标资源或者其他资源
                type:"asset/resource",
                generator:{
                    //输出名称
                    filename:"static/media/[hash:10][ext][query]"
                }
            },
            {
                test:/\.js$/,  //处理字体图标资源或者其他资源
                exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
                loader:'babel-loader',
                //写这里也行,写外面babel.config.js里面也行
                // options:{
                //     presets:["@babel/preset-env"]
                // }
            }
        ]
    },
     //插件
    plugins:[
        //plugin的配置
        new ESLintPlugin({
            //检测哪些文件
            context:path.resolve(__dirname,"../src"),
        }),
        new HtmlWebpackPlugin({
            //模板。以public/index.html文件创建新的html文件
            //新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
            template:path.resolve(__dirname,"../public/index.html")
        })
    ],
     //模式
    mode:'production',
}

打包
npx webpack --config ./config/webpack.prod.js

简化运行代码的长度 配置 package.json

 "scripts": {
    "start":"npm run dev",
    "dev": "webpack serve --config ./config/webpack.dev.js",
    "build":"webpack  --config ./config/webpack.prod.js"
  },

提取css成单独文件

css文件目前被打包到js文件中,当js文件加载时,会创建一个style标签来生成样式
这样对于网站来说,会出现闪屏现象,用户体验不好
应该是单独的css文件,通过link标签加载性能才好
1.下载
npm i mini-css-extract-plugin -D
2.配置webpack.prod.js文件

const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
const MiniCssExtractPlugin=require("mini-css-extract-plugin")
module.exports={
     //入口
    entry:'./src/main.js', //相对路径
     //输出
    output:{
        //所有文件的输出路径
        //__dirname  nodejs的变量,代表当前文件的文件夹目录
        path:path.resolve(__dirname,'../dist'),//绝对路径
        //入口文件打包输出文件名
        filename:'static/js/main.js',
        //原理,在打包前,将path整个目录内容清空,再进行打包
        clean:true, //自动清空上次打包内容
    },
     //加载器
    module:{
        rules:[
            //loader的配置
            {
                test:/\.css$/i, //只检测.css结尾的文件
                use:[ //执行顺序,从右到左(从下到上)
                   MiniCssExtractPlugin.loader, //提取css成单独文件
                    "css-loader"  //将css资源编译成commonjs的模块到js中
                ]
            },
            {
                test: /\.less$/i,
                use: [
                  // 使用多个loader
                  MiniCssExtractPlugin.loader, //提取css成单独文件
                  'css-loader',
                  'less-loader', //将less编译成css文件
                ],
            },
            {
                test:/\.(png|jpe?g|glf|webp|svg)$/,
                type:"asset",
                parser:{
                    dataUrlCondition:{
                        //小于10kb的图片转base64
                        //优点,减少请求数量,缺点,体积会更大
                        maxSize:10 * 1024,//10kb
                    }
                },
                generator:{
                    //输出图片名称
                    //[hash:10] hash值取前10位
                    filename:"static/images/[hash:10][ext][query]"
                }
            },
            {
                test:/\.(ttf|woff2?|mp3|mp4|avi)$/,  //处理字体图标资源或者其他资源
                type:"asset/resource",
                generator:{
                    //输出名称
                    filename:"static/media/[hash:10][ext][query]"
                }
            },
            {
                test:/\.js$/,  //处理字体图标资源或者其他资源
                exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
                loader:'babel-loader',
                //写这里也行,写外面babel.config.js里面也行
                // options:{
                //     presets:["@babel/preset-env"]
                // }
            }
        ]
    },
     //插件
    plugins:[
        //plugin的配置
        new ESLintPlugin({
            //检测哪些文件
            context:path.resolve(__dirname,"../src"),
        }),
        new HtmlWebpackPlugin({
            //模板。以public/index.html文件创建新的html文件
            //新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
            template:path.resolve(__dirname,"../public/index.html")
        }),
        new MiniCssExtractPlugin({
            filename:'static/css/main.css'
        })
    ],
     //模式
    mode:'production',
}

Css兼容性处理

1.下载包
npm i postcss-loader postcss postcss-preset-env -D
2.配置webpack.prod.js文件
在css-loader后面 在less-loader前面 加代码

const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
const MiniCssExtractPlugin=require("mini-css-extract-plugin")
module.exports={
     //入口
    entry:'./src/main.js', //相对路径
     //输出
    output:{
        //所有文件的输出路径
        //__dirname  nodejs的变量,代表当前文件的文件夹目录
        path:path.resolve(__dirname,'../dist'),//绝对路径
        //入口文件打包输出文件名
        filename:'static/js/main.js',
        //原理,在打包前,将path整个目录内容清空,再进行打包
        clean:true, //自动清空上次打包内容
    },
     //加载器
    module:{
        rules:[
            //loader的配置
            {
                test:/\.css$/i, //只检测.css结尾的文件
                use:[ //执行顺序,从右到左(从下到上)
                   MiniCssExtractPlugin.loader, //提取css成单独文件
                    "css-loader",  //将css资源编译成commonjs的模块到js中
                    {
                        loader:"postcss-loader",
                        options:{ //配置项
                            postcssOptions:{
                                plugins:[
                                    "postcss-preset-env",//能解决大多数兼容性问题
                                ]
                            }
                        }
                      },
                ]
            },
            {
                test: /\.less$/i,
                use: [
                  // 使用多个loader
                  MiniCssExtractPlugin.loader, //提取css成单独文件
                  'css-loader',
                  {
                    loader:"postcss-loader",
                    options:{ //配置项
                        postcssOptions:{
                            plugins:[
                                "postcss-preset-env",//能解决大多数兼容性问题
                            ]
                        }
                    }
                  },
                  'less-loader', //将less编译成css文件
                ],
            },
            {
                test:/\.(png|jpe?g|glf|webp|svg)$/,
                type:"asset",
                parser:{
                    dataUrlCondition:{
                        //小于10kb的图片转base64
                        //优点,减少请求数量,缺点,体积会更大
                        maxSize:10 * 1024,//10kb
                    }
                },
                generator:{
                    //输出图片名称
                    //[hash:10] hash值取前10位
                    filename:"static/images/[hash:10][ext][query]"
                }
            },
            {
                test:/\.(ttf|woff2?|mp3|mp4|avi)$/,  //处理字体图标资源或者其他资源
                type:"asset/resource",
                generator:{
                    //输出名称
                    filename:"static/media/[hash:10][ext][query]"
                }
            },
            {
                test:/\.js$/,  //处理字体图标资源或者其他资源
                exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
                loader:'babel-loader',
                //写这里也行,写外面babel.config.js里面也行
                // options:{
                //     presets:["@babel/preset-env"]
                // }
            }
        ]
    },
     //插件
    plugins:[
        //plugin的配置
        new ESLintPlugin({
            //检测哪些文件
            context:path.resolve(__dirname,"../src"),
        }),
        new HtmlWebpackPlugin({
            //模板。以public/index.html文件创建新的html文件
            //新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
            template:path.resolve(__dirname,"../public/index.html")
        }),
        new MiniCssExtractPlugin({
            filename:'static/css/main.css'
        })
    ],
     //模式
    mode:'production',
}

package.json 文件还需要做兼容那些处理
实际开发用的是这种

 "browserslist":[
    "last 2 version",
    "> 1%",
    "not dead"
  ]

Css压缩

1.下载包
npm i css-minimizer-webpack-plugin -D
2.配置webpack.prod.js文件

const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
const MiniCssExtractPlugin=require("mini-css-extract-plugin")
const CssMinimizerPlugin=require("css-minimizer-webpack-plugin")

//定义一个函数抽取重复的代码  用来获取处理样式的loader
function getStyleLoader(pre){
    return [ //执行顺序,从右到左(从下到上)
                MiniCssExtractPlugin.loader, //提取css成单独文件
                "css-loader",  //将css资源编译成commonjs的模块到js中
                {
                    loader:"postcss-loader",
                    options:{ //配置项
                        postcssOptions:{
                            plugins:[
                                "postcss-preset-env",//能解决大多数兼容性问题
                            ]
                        }
                    }
                },
                pre,
            ].filter(Boolean);
}


module.exports={
     //入口
    entry:'./src/main.js', //相对路径
     //输出
    output:{
        //所有文件的输出路径
        //__dirname  nodejs的变量,代表当前文件的文件夹目录
        path:path.resolve(__dirname,'../dist'),//绝对路径
        //入口文件打包输出文件名
        filename:'static/js/main.js',
        //原理,在打包前,将path整个目录内容清空,再进行打包
        clean:true, //自动清空上次打包内容
    },
     //加载器
    module:{
        rules:[
            //loader的配置
            {
                test:/\.css$/i, //只检测.css结尾的文件
                use:getStyleLoader(),
            },
            {
                test: /\.less$/i,
                use:getStyleLoader('less-loader'),
            },
            {
                test:/\.(png|jpe?g|glf|webp|svg)$/,
                type:"asset",
                parser:{
                    dataUrlCondition:{
                        //小于10kb的图片转base64
                        //优点,减少请求数量,缺点,体积会更大
                        maxSize:10 * 1024,//10kb
                    }
                },
                generator:{
                    //输出图片名称
                    //[hash:10] hash值取前10位
                    filename:"static/images/[hash:10][ext][query]"
                }
            },
            {
                test:/\.(ttf|woff2?|mp3|mp4|avi)$/,  //处理字体图标资源或者其他资源
                type:"asset/resource",
                generator:{
                    //输出名称
                    filename:"static/media/[hash:10][ext][query]"
                }
            },
            {
                test:/\.js$/,  //处理字体图标资源或者其他资源
                exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
                loader:'babel-loader',
                //写这里也行,写外面babel.config.js里面也行
                // options:{
                //     presets:["@babel/preset-env"]
                // }
            }
        ]
    },
     //插件
    plugins:[
        //plugin的配置
        new ESLintPlugin({
            //检测哪些文件
            context:path.resolve(__dirname,"../src"),
        }),
        new HtmlWebpackPlugin({
            //模板。以public/index.html文件创建新的html文件
            //新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
            template:path.resolve(__dirname,"../public/index.html")
        }),
        new MiniCssExtractPlugin({
            filename:'static/css/main.css'
        }),
        new CssMinimizerPlugin(),
    ],
     //模式
    mode:'production',
}

html压缩

(默认生成模式已经开启了:html压缩和js压缩,不需要额外进行配置)

webpack高级配置

(其实就是进行webpack优化)
1.提升开发体验
2.提升打包构建速度
3.减少代码体积
4.优化代码运行性能

1.提升开发体验

SourceMap(源代码映射)是一个用来生成源代码与构建后代码一一映射的文件的方案。
它会生成一个xxx.map文件,里面包含源代码和构建后代码每一行,每一列的映射关系,当构建后代码出错了,会通过xxx.map文件,从构建后代码出错位置找到映射后源代码出错位置,从而让浏览器提示源代码文件出错位置,帮助我们更快的找到错误根源。

开发模式:cheap-module-source-map
优点:打包编辑速度快,只包含行映射
缺点:没有列映射
webpack.dev.js

 //模式
    mode:'development',
    devtool:"cheap-module-source-map"

生产模式:source-map
优点:包含行/列映射
缺点:打包编辑速度更慢
webpack.prod.js

  //模式
    mode:'production',
    devtool:"source-map"

2.提升打包构建速度

HotModuleReplacement(HMR/热模块替换):在程序运行中,替换,添加或删除模块,而无需重新加载整个页面。
基本配置 webpack.dev.js

//开发服务器:不会输出资源,在内存中编译打包
    devServer:{
        host:"localhost",//启动服务器域名
        port:"3000", //启动服务器端口号
        open:true,//是否自动打开浏览器
        hot:true,//开启HMR功能(只能用于开发环境,生成环境不需要了)默认值是true
    },

此时css样式经过style-loader处理,已经具备HMR功能了,但是js还不行。
main.js

import count from "./js/count";
import sum from "./js/sum";
//想要webpack打包资源,必须引入该资源
import './css/index.css'
import './css/iconfont.css'
console.log(count(2,1));
console.log(sum(1,2,3,4,5));

if(module.hot){
    //判断是否支持热模块替换功能
    module.hot.accept("./js/count")
    module.hot.accept("./js/sum")
}

上面这样写很麻烦,所以实际开发我们会使用其他loader来解决(比如:vue-loader,react-hot-loader)
oneOf(就是只能匹配上一个loader,剩下的就不匹配了)

include/exclude(包含/排除)两者只能存在一个

{
                    test:/\.js$/,  //处理字体图标资源或者其他资源
                    exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
                    //include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
                    loader:'babel-loader',
                    //写这里也行,写外面babel.config.js里面也行
                    // options:{
                    //     presets:["@babel/preset-env"]
                    // }
                }

cache(对Eslint检查和Babel编译结果进行缓存)

{
                    test:/\.js$/,  //处理字体图标资源或者其他资源
                    exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
                    //include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
                    loader:'babel-loader',
                    //写这里也行,写外面babel.config.js里面也行
                    options:{
                        // presets:["@babel/preset-env"]
                        cacheDirectory:true,//开启babel缓存
                        cacheCompression:false,//关闭缓存文件压缩
                    }
                }
//plugin的配置
        new ESLintPlugin({
            //检测哪些文件
            context:path.resolve(__dirname,"../src"),
            exclude:"node_modules", //默认值  
            cache:true,//开启缓存
            cacheLocation:path.resolve(__dirname,"../node_modules/.cache/eslintcache")  //指定缓存文件
        }),

thead(多进程打包,开启电脑的多个进程同时干一件事,速度更快)
需要注意:请仅在特别耗时的操作中使用,因为每个进程启动就有大约为600ms左右开销。
我们启动进程的数量就是我们CPU的核数。
1.如何获取CPU的核数,因为每个电脑都不一样

//nodejs核心模块,直接使用
const os=require('os');
//cpu核数
const threads=os.cpus().length;

2.下载包
npm i thread-loader -D
3.配置

 {
                    test:/\.js$/,  //处理字体图标资源或者其他资源
                    exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
                    //include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
                    use:[
                        {
                            loader:"thread-loader", //开启多进程
                            options:{
                                works:threads, //进程数量
                            }
                        },
                        {
                            loader:'babel-loader',
                            //写这里也行,写外面babel.config.js里面也行
                            options:{
                                // presets:["@babel/preset-env"]
                                cacheDirectory:true,//开启babel缓存
                                cacheCompression:false,//关闭缓存文件压缩
                            }
                        }
                    ]
                }
 //插件
    plugins:[
        //plugin的配置
        new ESLintPlugin({
            //检测哪些文件
            context:path.resolve(__dirname,"../src"),
            exclude:"node_modules", //默认值  
            cache:true,//开启缓存
            cacheLocation:path.resolve(__dirname,"../node_modules/.cache/eslintcache"),  //指定缓存文件
            threads,//开启多进程和设置进程数量
        }),
        new HtmlWebpackPlugin({
            //模板。以public/index.html文件创建新的html文件
            //新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
            template:path.resolve(__dirname,"../public/index.html")
        }),
        new MiniCssExtractPlugin({
            filename:'static/css/main.css'
        }),
        // new CssMinimizerPlugin(),
        // new TerserWebpackPlugin({
        //     parallel:threads,//开启多进程和设置进程数量
        // })
    ],
    optimization:{
        //压缩的操作
        minimizer:[
            //压缩css
            new CssMinimizerPlugin(),
            //压缩js
            new TerserWebpackPlugin({
                parallel:threads,//开启多进程和设置进程数量
            })
        ]
    },

3.减少代码体积

tree Shaking(用于描述移除js中的没有使用上的代码)
webpack已经默认开启了这个功能,无需其他配置
注意:它依赖 ES模块化
babel
1.下载包
npm i @babel/plugin-transform-runtime -D

@babel/plugin-transform-runtime(禁用了Babel自动对每个文件的runtime注入,而是引入,并且使所有辅助代码从这里引用)

{
                    test:/\.js$/,  //处理字体图标资源或者其他资源
                    exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
                    //include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
                    use:[
                        {
                            loader:"thread-loader", //开启多进程
                            options:{
                                works:threads, //进程数量
                            }
                        },
                        {
                            loader:'babel-loader',
                            //写这里也行,写外面babel.config.js里面也行
                            options:{
                                // presets:["@babel/preset-env"]
                                cacheDirectory:true,//开启babel缓存
                                cacheCompression:false,//关闭缓存文件压缩
                                plugins:['@babel/plugin-transform-runtime'],//减少代码体积
                            }
                        }
                    ]
                }

image Minimizer(用来压缩图片的插件)
注意:如果项目中图片都是在线连接,那么就不需要了,本地项目静态图片才需要进行压缩
1.下载包
npm i image-minimizer-webpack-plugin imagemin -D
还有剩下包需要下载,有两种模式:
无损压缩
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo -D
有损压缩
npm install imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo -D

注意:有时候网络问题,需要多下载几次,不然就使用翻墙软件下载

2.配置,以无损压缩配置为例 打包的时候报错 不知道啥问题导致的

 optimization:{
        //压缩的操作
        minimizer:[
            //压缩css
            new CssMinimizerPlugin(),
            //压缩js
            new TerserWebpackPlugin({
                parallel:threads,//开启多进程和设置进程数量
            }),
            //压缩图片
            new ImageMinimizerPlugin({
                minimizer: {
                  implementation: ImageMinimizerPlugin.imageminGenerate,
                  options: {
                    plugins: [
                      ["gifsicle", { interlaced: true }],
                      ["jpegtran", { progressive: true }],
                      ["optipng", { optimizationLevel: 5 }],
                      [
                        "svgo",
                        {
                          plugins: [
                            "preset-default",
                            "prefixIds",
                            {
                              name: "sortAttrs",
                              params: {
                                xmlnsOrder: "alphabetical",
                              },
                            },
                          ],
                        },
                      ],
                    ],
                  },
                },
          }),
        ]
    },

4.优化代码运行性能

code split(代码分割)
1.分割文件:将打包生成的文件进行分割,生成多个js文件
单入口

optimization:{
        //压缩的操作
        minimizer:[
            //压缩css
            new CssMinimizerPlugin(),
            //压缩js
            new TerserWebpackPlugin({
                parallel:threads,//开启多进程和设置进程数量
            }),
           
        ],
        //代码分割配置
        splitChunks:{
            chunks:"all",
            //其他都用默认值
        }
    },

2.按需加载:需要哪个文件就加载哪个文件。
main.js 动态引入按需加载

import count from "./js/count";
import sum from "./js/sum";

//想要webpack打包资源,必须引入该资源
import './css/index.css'
import './css/iconfont.css'
console.log(count(2,1));
console.log(sum(1,2,3,4,5));

document.getElementById('btn').onclick=function(){
    //动态引入按需加载
    //eslint不能识别动态导入需要,需要额外追加配置
    import("./js/math").then(({mul})=>{
         console.log(mul(3,1));
    })
}

if(module.hot){
    //判断是否支持热模块替换功能
    module.hot.accept("./js/count")
    module.hot.accept("./js/sum")
}

.eslintrc.js 解决动态语法导入报错

module.exports={
    //继承Eslint规则
    extends:['eslint:recommended'],
    env:{
        node:true,//启用node中全局变量
        browser:true,//启用浏览器中全局变量
    },
    parserOptions:{
        ecmaVersion:6, //语法环境ES6
        sourceType:'module' //es  module
    },
    rules:{
        "no-var":2 ,//不能使用var定义变量
    },
    plugins:['import']  //解决动态语法导入报错
}

给模块命名
1.main.js

import count from "./js/count";
import sum from "./js/sum";

//想要webpack打包资源,必须引入该资源
import './css/index.css'
import './css/iconfont.css'
console.log(count(2,1));
console.log(sum(1,2,3,4,5));

document.getElementById('btn').onclick=function(){
    //动态引入按需加载
    //eslint不能识别动态导入需要,需要额外追加配置
    // /* webpackChunkName:"math" */  webpack魔法命名
    import(/* webpackChunkName:"math" */ "./js/math").then(({mul})=>{
         console.log(mul(3,1));
    })
}

if(module.hot){
    //判断是否支持热模块替换功能
    module.hot.accept("./js/count")
    module.hot.accept("./js/sum")
}

2.配置webpack.prod.js文件

//输出
    output:{
        //所有文件的输出路径
        //__dirname  nodejs的变量,代表当前文件的文件夹目录
        path:path.resolve(__dirname,'../dist'),//绝对路径
        //入口文件打包输出文件名
        filename:'static/js/main.js',
        //给打包输出的其他文件命名
        chunkFilename:"static/js/[name].js",
        //原理,在打包前,将path整个目录内容清空,再进行打包
        clean:true, //自动清空上次打包内容
    },

统一命名 webpack.prod.js

const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
const MiniCssExtractPlugin=require("mini-css-extract-plugin")
const CssMinimizerPlugin=require("css-minimizer-webpack-plugin")
const TerserWebpackPlugin=require("terser-webpack-plugin")
// const ImageMinimizerPlugin=require("image-minimizer-webpack-plugin")

//nodejs核心模块,直接使用
const os=require('os');
//cpu核数
const threads=os.cpus().length;
//定义一个函数抽取重复的代码  用来获取处理样式的loader
function getStyleLoader(pre){
    return [ //执行顺序,从右到左(从下到上)
                MiniCssExtractPlugin.loader, //提取css成单独文件
                "css-loader",  //将css资源编译成commonjs的模块到js中
                {
                    loader:"postcss-loader",
                    options:{ //配置项
                        postcssOptions:{
                            plugins:[
                                "postcss-preset-env",//能解决大多数兼容性问题
                            ]
                        }
                    }
                },
                pre,
            ].filter(Boolean);
}


module.exports={
     //入口
    entry:'./src/main.js', //相对路径
     //输出
    output:{
        //所有文件的输出路径
        //__dirname  nodejs的变量,代表当前文件的文件夹目录
        path:path.resolve(__dirname,'../dist'),//绝对路径
        //入口文件打包输出文件名
        filename:'static/js/[name].js',
        //给打包输出的其他文件命名
        chunkFilename:"static/js/[name].chunk.js",
        //图片,字体等通过type:asset处理资源命名方式
        assetModuleFilename:"static/media/[hash:10][ext][query]",
        //原理,在打包前,将path整个目录内容清空,再进行打包
        clean:true, //自动清空上次打包内容
    },
     //加载器
    module:{
        rules:[
            //loader的配置
           {
              //每个文件只能被其中一个loader配置处理
            oneOf:[
                {
                    test:/\.css$/i, //只检测.css结尾的文件
                    use:getStyleLoader(),
                },
                {
                    test: /\.less$/i,
                    use:getStyleLoader('less-loader'),
                },
                {
                    test:/\.(png|jpe?g|glf|webp|svg)$/,
                    type:"asset",
                    parser:{
                        dataUrlCondition:{
                            //小于10kb的图片转base64
                            //优点,减少请求数量,缺点,体积会更大
                            maxSize:10 * 1024,//10kb
                        }
                    },
                    // generator:{
                    //     //输出图片名称
                    //     //[hash:10] hash值取前10位
                    //     filename:"static/images/[hash:10][ext][query]"
                    // }
                },
                {
                    test:/\.(ttf|woff2?|mp3|mp4|avi)$/,  //处理字体图标资源或者其他资源
                    type:"asset/resource",
                    // generator:{
                    //     //输出名称
                    //     filename:"static/media/[hash:10][ext][query]"
                    // }
                },
                {
                    test:/\.js$/,  //处理字体图标资源或者其他资源
                    exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
                    //include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
                    use:[
                        {
                            loader:"thread-loader", //开启多进程
                            options:{
                                works:threads, //进程数量
                            }
                        },
                        {
                            loader:'babel-loader',
                            //写这里也行,写外面babel.config.js里面也行
                            options:{
                                // presets:["@babel/preset-env"]
                                cacheDirectory:true,//开启babel缓存
                                cacheCompression:false,//关闭缓存文件压缩
                                plugins:['@babel/plugin-transform-runtime'],//减少代码体积
                            }
                        }
                    ]
                }
            ]
           }
        ]
    },
     //插件
    plugins:[
        //plugin的配置
        new ESLintPlugin({
            //检测哪些文件
            context:path.resolve(__dirname,"../src"),
            exclude:"node_modules", //默认值  
            cache:true,//开启缓存
            cacheLocation:path.resolve(__dirname,"../node_modules/.cache/eslintcache"),  //指定缓存文件
            threads,//开启多进程和设置进程数量
        }),
        new HtmlWebpackPlugin({
            //模板。以public/index.html文件创建新的html文件
            //新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
            template:path.resolve(__dirname,"../public/index.html")
        }),
        new MiniCssExtractPlugin({
            filename:'static/css/[name].css',
            chunkFilename:'static/css/[name].chunk.css'
        }),
        // new CssMinimizerPlugin(),
        // new TerserWebpackPlugin({
        //     parallel:threads,//开启多进程和设置进程数量
        // })
       
    ],
    optimization:{
        //压缩的操作
        minimizer:[
            //压缩css
            new CssMinimizerPlugin(),
            //压缩js
            new TerserWebpackPlugin({
                parallel:threads,//开启多进程和设置进程数量
            }),
            //压缩图片  以下代码打包报错  不知道哪里问题
        //     new ImageMinimizerPlugin({
        //         minimizer: {
        //           implementation: ImageMinimizerPlugin.imageminGenerate,
        //           options: {
        //             plugins: [
        //               ["gifsicle", { interlaced: true }],
        //               ["jpegtran", { progressive: true }],
        //               ["optipng", { optimizationLevel: 5 }],
        //               [
        //                 "svgo",
        //                 {
        //                   plugins: [
        //                     "preset-default",
        //                     "prefixIds",
        //                     {
        //                       name: "sortAttrs",
        //                       params: {
        //                         xmlnsOrder: "alphabetical",
        //                       },
        //                     },
        //                   ],
        //                 },
        //               ],
        //             ],
        //           },
        //         },
        //   }),
        ],
        //代码分割配置
        splitChunks:{
            chunks:"all",
            //其他都用默认值
        }
    },
     //模式
    mode:'production',
    devtool:"source-map"
}

preload(告诉浏览器立即加载资源) / prefetch(告诉浏览器在空闲时才开始加载资源)

共同点: 都只会加载资源,并不执行。都有缓存
区别:preload加载优先级高,prefetch加载优先级低。
preload只能加载当前页面需要使用的资源,prefetch可以加载当前页面资源,也可以加载下一个页面需要使用的资源。

下载包
npm install --save-dev @vue/preload-webpack-plugin

const PreloadWebpackPlugin=require("@vue/preload-webpack-plugin") 
//插件
    plugins:[
        new PreloadWebpackPlugin({
            // rel:'preload',
            // as:'script',
            rel:'prefetch',
        })
    ],

core-js(是专门用来做ES6以及以上的API的polyfill(垫片/补丁,就是用社区上提供的一段代码,让我们在不兼容某些新特性的浏览器上,使用该新特性))
下载包
npm i core-js

main.js

import count from "./js/count";
import sum from "./js/sum";
//完整引入
// import 'core-js'
//按需加载
// import 'core-js/es/promise'

//想要webpack打包资源,必须引入该资源
import './css/index.css'
import './css/iconfont.css'
console.log(count(2,1));
console.log(sum(1,2,3,4,5));

document.getElementById('btn').onclick=function(){
    //动态引入按需加载
    //eslint不能识别动态导入需要,需要额外追加配置
    // /* webpackChunkName:"math" */  webpack魔法命名
    import(/* webpackChunkName:"math" */ "./js/math").then(({mul})=>{
         console.log(mul(3,1));
    })
}

if(module.hot){
    //判断是否支持热模块替换功能
    module.hot.accept("./js/count")
    module.hot.accept("./js/sum")
}

new Promise((resolve)=>{
    setTimeout(()=>{
        resolve();
    },1000)
})

自动引入
文档
babel.config.js

module.exports={
    //智能预设,能够编译ES6语法
    presets:[
        [
            "@babel/preset-env",
            {
                useBuiltIns:'usage',//按需加载自动引入
                corejs:3
            }
        ]
    ]
}

PWA(渐进式网络应用程序,在离线时应用程序能够继续运行功能) 兼容性比较差
下载包
npm i workbox-webpack-plugin -D
文档
配置main.js

import count from "./js/count";
import sum from "./js/sum";
//完整引入
// import 'core-js'
//按需加载
// import 'core-js/es/promise'

//想要webpack打包资源,必须引入该资源
import './css/index.css'
import './css/iconfont.css'
console.log(count(2,1));
console.log(sum(1,2,3,4,5));

document.getElementById('btn').onclick=function(){
    //动态引入按需加载
    //eslint不能识别动态导入需要,需要额外追加配置
    // /* webpackChunkName:"math" */  webpack魔法命名
    import(/* webpackChunkName:"math" */ "./js/math").then(({mul})=>{
         console.log(mul(3,1));
    })
}

if(module.hot){
    //判断是否支持热模块替换功能
    module.hot.accept("./js/count")
    module.hot.accept("./js/sum")
}

new Promise((resolve)=>{
    setTimeout(()=>{
        resolve();
    },1000)
})

const arr=[1,2,3,4];
console.log(arr.includes(1));

if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {
      navigator.serviceWorker.register('/service-worker.js').then(registration => {
        console.log('SW registered: ', registration);
      }).catch(registrationError => {
        console.log('SW registration failed: ', registrationError);
      });
    });
  }
 //插件
    plugins:[
        new WorkboxPlugin.GenerateSW({
            //这些选项帮助快速启用 ServiceWorkers
            //不允许遗留任何‘旧的’ ServiceWorkers
            clientsClaim:true,
            skipWaiting:true
        })
    ],

npm i serve -g 全局安装

serve dist 运行

Notwork——》开启 Offline 离线环境 看效果

webpack.prod.js完整代码

const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
const MiniCssExtractPlugin=require("mini-css-extract-plugin")
const CssMinimizerPlugin=require("css-minimizer-webpack-plugin")
const TerserWebpackPlugin=require("terser-webpack-plugin")
// const ImageMinimizerPlugin=require("image-minimizer-webpack-plugin")
const PreloadWebpackPlugin=require("@vue/preload-webpack-plugin")
const WorkboxPlugin=require('workbox-webpack-plugin')
//nodejs核心模块,直接使用
const os=require('os');
//cpu核数
const threads=os.cpus().length;
//定义一个函数抽取重复的代码  用来获取处理样式的loader
function getStyleLoader(pre){
    return [ //执行顺序,从右到左(从下到上)
                MiniCssExtractPlugin.loader, //提取css成单独文件
                "css-loader",  //将css资源编译成commonjs的模块到js中
                {
                    loader:"postcss-loader",
                    options:{ //配置项
                        postcssOptions:{
                            plugins:[
                                "postcss-preset-env",//能解决大多数兼容性问题
                            ]
                        }
                    }
                },
                pre,
            ].filter(Boolean);
}


module.exports={
     //入口
    entry:'./src/main.js', //相对路径
     //输出
    output:{
        //所有文件的输出路径
        //__dirname  nodejs的变量,代表当前文件的文件夹目录
        path:path.resolve(__dirname,'../dist'),//绝对路径
        //入口文件打包输出文件名
        filename:'static/js/[name].js',
        //给打包输出的其他文件命名
        chunkFilename:"static/js/[name].chunk.js",
        //图片,字体等通过type:asset处理资源命名方式
        assetModuleFilename:"static/media/[hash:10][ext][query]",
        //原理,在打包前,将path整个目录内容清空,再进行打包
        clean:true, //自动清空上次打包内容
    },
     //加载器
    module:{
        rules:[
            //loader的配置
           {
              //每个文件只能被其中一个loader配置处理
            oneOf:[
                {
                    test:/\.css$/i, //只检测.css结尾的文件
                    use:getStyleLoader(),
                },
                {
                    test: /\.less$/i,
                    use:getStyleLoader('less-loader'),
                },
                {
                    test:/\.(png|jpe?g|glf|webp|svg)$/,
                    type:"asset",
                    parser:{
                        dataUrlCondition:{
                            //小于10kb的图片转base64
                            //优点,减少请求数量,缺点,体积会更大
                            maxSize:10 * 1024,//10kb
                        }
                    },
                    // generator:{
                    //     //输出图片名称
                    //     //[hash:10] hash值取前10位
                    //     filename:"static/images/[hash:10][ext][query]"
                    // }
                },
                {
                    test:/\.(ttf|woff2?|mp3|mp4|avi)$/,  //处理字体图标资源或者其他资源
                    type:"asset/resource",
                    // generator:{
                    //     //输出名称
                    //     filename:"static/media/[hash:10][ext][query]"
                    // }
                },
                {
                    test:/\.js$/,  //处理字体图标资源或者其他资源
                    exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
                    //include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
                    use:[
                        {
                            loader:"thread-loader", //开启多进程
                            options:{
                                works:threads, //进程数量
                            }
                        },
                        {
                            loader:'babel-loader',
                            //写这里也行,写外面babel.config.js里面也行
                            options:{
                                // presets:["@babel/preset-env"]
                                cacheDirectory:true,//开启babel缓存
                                cacheCompression:false,//关闭缓存文件压缩
                                plugins:['@babel/plugin-transform-runtime'],//减少代码体积
                            }
                        }
                    ]
                }
            ]
           }
        ]
    },
     //插件
    plugins:[
        //plugin的配置
        new ESLintPlugin({
            //检测哪些文件
            context:path.resolve(__dirname,"../src"),
            exclude:"node_modules", //默认值  
            cache:true,//开启缓存
            cacheLocation:path.resolve(__dirname,"../node_modules/.cache/eslintcache"),  //指定缓存文件
            threads,//开启多进程和设置进程数量
        }),
        new HtmlWebpackPlugin({
            //模板。以public/index.html文件创建新的html文件
            //新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
            template:path.resolve(__dirname,"../public/index.html")
        }),
        new MiniCssExtractPlugin({
            filename:'static/css/[name].css',
            chunkFilename:'static/css/[name].chunk.css'
        }),
        // new CssMinimizerPlugin(),
        // new TerserWebpackPlugin({
        //     parallel:threads,//开启多进程和设置进程数量
        // })
        new PreloadWebpackPlugin({
            // rel:'preload',
            // as:'script',
            rel:'prefetch',
        }),
        new WorkboxPlugin.GenerateSW({
            //这些选项帮助快速启用 ServiceWorkers
            //不允许遗留任何‘旧的’ ServiceWorkers
            clientsClaim:true,
            skipWaiting:true
        })
    ],
    optimization:{
        //压缩的操作
        minimizer:[
            //压缩css
            new CssMinimizerPlugin(),
            //压缩js
            new TerserWebpackPlugin({
                parallel:threads,//开启多进程和设置进程数量
            }),
            //压缩图片  以下代码打包报错  不知道哪里问题
        //     new ImageMinimizerPlugin({
        //         minimizer: {
        //           implementation: ImageMinimizerPlugin.imageminGenerate,
        //           options: {
        //             plugins: [
        //               ["gifsicle", { interlaced: true }],
        //               ["jpegtran", { progressive: true }],
        //               ["optipng", { optimizationLevel: 5 }],
        //               [
        //                 "svgo",
        //                 {
        //                   plugins: [
        //                     "preset-default",
        //                     "prefixIds",
        //                     {
        //                       name: "sortAttrs",
        //                       params: {
        //                         xmlnsOrder: "alphabetical",
        //                       },
        //                     },
        //                   ],
        //                 },
        //               ],
        //             ],
        //           },
        //         },
        //   }),
        ],
        //代码分割配置
        splitChunks:{
            chunks:"all",
            //其他都用默认值
        },
        runtimeChunk:{
            name:(entrypoint)=>`runtime~${entrypoint.name}.js`,
        }
    },
     //模式
    mode:'production',
    devtool:"source-map"
}

webpack.dev.js完整代码

const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')

//nodejs核心模块,直接使用
const os=require('os');
//cpu核数
const threads=os.cpus().length;
module.exports={
     //入口
    entry:'./src/main.js', //相对路径
     //输出
    output:{
        //所有文件的输出路径
        //__dirname  nodejs的变量,代表当前文件的文件夹目录
        path:path.resolve(__dirname,'../dist'),//绝对路径
        //入口文件打包输出文件名
        filename:'static/js/[name].js',
        //给打包输出的其他文件命名
        chunkFilename:"static/js/[name].chunk.js",
        //图片,字体等通过type:asset处理资源命名方式
        assetModuleFilename:"static/media/[hash:10][ext][query]",
        //原理,在打包前,将path整个目录内容清空,再进行打包
        clean:true, //自动清空上次打包内容
    },
     //加载器
    module:{
        rules:[
            //loader的配置
           {
            //每个文件只能被其中一个loader配置处理
             oneOf:[
                {
                    test:/\.css$/i, //只检测.css结尾的文件
                    use:[ //执行顺序,从右到左(从下到上)
                        "style-loader", //将js中css通过创建style标签添加html文件中生效
                        "css-loader"  //将css资源编译成commonjs的模块到js中
                    ]
                },
                {
                    test: /\.less$/i,
                    use: [
                      // 使用多个loader
                      'style-loader',
                      'css-loader',
                      'less-loader', //将less编译成css文件
                    ],
                },
                {
                    test:/\.(png|jpe?g|glf|webp|svg)$/,
                    type:"asset",
                    parser:{
                        dataUrlCondition:{
                            //小于10kb的图片转base64
                            //优点,减少请求数量,缺点,体积会更大
                            maxSize:10 * 1024,//10kb
                        }
                    },
                    // generator:{
                    //     //输出图片名称
                    //     //[hash:10] hash值取前10位
                    //     filename:"static/images/[hash:10][ext][query]"
                    // }
                },
                {
                    test:/\.(ttf|woff2?|mp3|mp4|avi)$/,  //处理字体图标资源或者其他资源
                    type:"asset/resource",
                    // generator:{
                    //     //输出名称
                    //     filename:"static/media/[hash:10][ext][query]"
                    // }
                },
                {
                    test:/\.js$/,  //处理字体图标资源或者其他资源
                    exclude:/node_modules/, //排除node_modules中的js文件(这些文件不处理)
                    //include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
                    use:[
                        {
                            loader:"thread-loader", //开启多进程
                            options:{
                                works:threads, //进程数量
                            }
                        },
                        {
                            loader:'babel-loader',
                            //写这里也行,写外面babel.config.js里面也行
                            options:{
                                // presets:["@babel/preset-env"]
                                cacheDirectory:true,//开启babel缓存
                                cacheCompression:false,//关闭缓存文件压缩
                                plugins:['@babel/plugin-transform-runtime'],//减少代码体积
                            }
                        }
                    ]
                }
             ]
           }
        ]
    },
     //插件
    plugins:[
        //plugin的配置
        new ESLintPlugin({
            //检测哪些文件
            context:path.resolve(__dirname,"../src"),
            exclude:"node_modules", //默认值  
            cache:true,//开启缓存
            cacheLocation:path.resolve(__dirname,"../node_modules/.cache/eslintcache"),  //指定缓存文件
            threads,//开启多进程和设置进程数量
        }),
        new HtmlWebpackPlugin({
            //模板。以public/index.html文件创建新的html文件
            //新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
            template:path.resolve(__dirname,"../public/index.html")
        })
    ],
    //开发服务器:不会输出资源,在内存中编译打包
    devServer:{
        host:"localhost",//启动服务器域名
        port:"3000", //启动服务器端口号
        open:true,//是否自动打开浏览器
        hot:true,//开启HMR功能(只能用于开发环境,生成环境不需要了)默认值是true
    },
     //模式
    mode:'development',
    devtool:"cheap-module-source-map",
}

vueCli开发模式配置vue3

npm init -y
安装
npm install -D vue-loader vue-template-compiler
配置webpack.dev.js 开发模式

const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const {DefinePlugin} =require("webpack")
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
const { VueLoaderPlugin}=require('vue-loader')
//定义一个函数抽取重复的代码  用来获取处理样式的loader
function getStyleLoader(pre){
    return [ //执行顺序,从右到左(从下到上)
                "vue-style-loader", //提取css成单独文件
                "css-loader",  //将css资源编译成commonjs的模块到js中
                {
                    loader:"postcss-loader",
                    options:{ //配置项
                        postcssOptions:{
                            plugins:[
                                "postcss-preset-env",//能解决大多数兼容性问题
                            ]
                        }
                    }
                },
                pre,
            ].filter(Boolean);
}
module.exports={
     //入口
    entry:'./src/main.js', //相对路径
     //输出
    output:{
        //所有文件的输出路径
        //__dirname  nodejs的变量,代表当前文件的文件夹目录
        path:undefined,//绝对路径
        //入口文件打包输出文件名
        filename:'static/js/[name].js',
        //给打包输出的其他文件命名
        chunkFilename:"static/js/[name].chunk.js",
        //图片,字体等通过type:asset处理资源命名方式
        assetModuleFilename:"static/media/[hash:10][ext][query]"
    },
     //加载器
    module:{
        rules:[
            //loader的配置
            {
                test:/\.css$/, //只检测.css结尾的文件
                use:getStyleLoader(),
            },
            {
                test: /\.less$/,
                use:getStyleLoader('less-loader'),
            },
            {
                test: /\.s[ac]ss$/,
                use:getStyleLoader('sass-loader'),
            },
            {
                test: /\.styl$/,
                use:getStyleLoader('stylus-loader'),
            },
            {
                test:/\.(png|jpe?g|glf|webp|svg)$/,
                type:"asset",
                parser:{
                    dataUrlCondition:{
                        //小于10kb的图片转base64
                        //优点,减少请求数量,缺点,体积会更大
                        maxSize:10 * 1024,//10kb
                    }
                },
            },
            {
                test:/\.(ttf|woff2?|mp3|mp4|avi)$/,  //处理字体图标资源或者其他资源
                type:"asset/resource",
            },
            {
                test:/\.js$/,  //处理字体图标资源或者其他资源
                include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
                loader:'babel-loader',
                //写这里也行,写外面babel.config.js里面也行
                options:{
                    cacheDirectory:true,//开启babel缓存
                    cacheCompression:false,//关闭缓存文件压缩
                }
            },
            {
                test:/\.vue$/,
                loader:'vue-loader'
            }
        ]
    },
     //插件
    plugins:[
        //plugin的配置
        new ESLintPlugin({
            //检测哪些文件
            context:path.resolve(__dirname,"../src"),
            exclude:"node_modules", //默认值  
            cache:true,//开启缓存
            cacheLocation:path.resolve(__dirname,"../node_modules/.cache/.eslintcache"),  //指定缓存文件
        }),
        new HtmlWebpackPlugin({
            //模板。以public/index.html文件创建新的html文件
            //新的html文件特点:1,结构和原来一致,2.自动引入打包输出的资源
            template:path.resolve(__dirname,"../public/index.html")
        }),
        new VueLoaderPlugin(),
        //定义环境变量 cross-env定义的环境变量给打包工具使用
        //DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告的问题
        new DefinePlugin({
            __VUE_OPTIONS_API__:true,
            __VUE_PROD_DEVTOOLS__:false
        })
    ],
    //开发服务器:不会输出资源,在内存中编译打包
    devServer:{
        host:"localhost",//启动服务器域名
        port:"4000", //启动服务器端口号
        open:true,//是否自动打开浏览器
        hot:true,//开启HMR功能(只能用于开发环境,生成环境不需要了)默认值是true
        historyApiFallback:true, //解决前端路由刷新404问题
    },
    optimization:{
       
        //代码分割配置
        splitChunks:{
            chunks:"all",
            //其他都用默认值
        },
        runtimeChunk:{
            name:(entrypoint)=>`runtime~${entrypoint.name}.js`,
        }
    },
    //webpack解析模块加载选项
    resolve:{
        //自动补全文件扩展名
        extensions:['.js','.json','.vue']
    },
     //模式
    mode:'development',
    devtool:"cheap-module-source-map",
}

安装依赖
npm i eslint-webpack-plugin html-webpack-plugin vue-style-loader css-loader postcss-loader postcss-preset-env -D
npm i less-loader sass-loader sass stylus-loader babel-loader vue-loader webpack webpack-cli webpack-dev-server -D

.eslintrc.js 配置

module.exports={
    root:true,
    env:{
        node:true,
    },
    extends:['plugin:vue/vue3-essential','eslint:recommended'],
    parserOptions:{
        parser:'@babel/eslint-parser'
    }
};

npm i @babel/eslint-parser -D
babel.config.js 配置

module.exports={
    presets:["@vue/cli-plugin-babel/preset"]
}

npm i @vue/cli-plugin-babel -D
npm i vue (默认是vue3的版本)

npm i cross-env -D
npm i eslint-plugin-vue -D
npm i vue-router

生产模式 webpack.prod.js

npm i mini-css-extract-plugin css-minimizer-webpack-plugin copy-webpack-plugin -D
下载图片
npm i image-minimizer-webpack-plugin imagemin -D
无损下载
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo -D
不知道为什么,下载图片老是下载失败

const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
const MiniCssExtractPlugin=require("mini-css-extract-plugin")
const CssMinimizerPlugin=require("css-minimizer-webpack-plugin")
const TerserWebpackPlugin=require("terser-webpack-plugin")
// const ImageMinimizerPlugin=require("image-minimizer-webpack-plugin")
const CopyPlugin=require('copy-webpack-plugin')
const { VueLoaderPlugin}=require('vue-loader')
const {DefinePlugin} =require("webpack")
//定义一个函数抽取重复的代码  用来获取处理样式的loader
function getStyleLoader(pre){
    return [ //执行顺序,从右到左(从下到上)
                MiniCssExtractPlugin.loader, //提取css成单独文件
                "css-loader",  //将css资源编译成commonjs的模块到js中
                {
                    loader:"postcss-loader",
                    options:{ //配置项
                        postcssOptions:{
                            plugins:[
                                "postcss-preset-env",//能解决大多数兼容性问题
                            ]
                        }
                    }
                },
                pre,
            ].filter(Boolean);
}


module.exports={
     //入口
    entry:'./src/main.js', //相对路径
     //输出
    output:{
        //所有文件的输出路径
        //__dirname  nodejs的变量,代表当前文件的文件夹目录
        path:path.resolve(__dirname,'../dist'),//绝对路径
        //入口文件打包输出文件名
        filename:'static/js/[name].[contenthash:10].js',
        //给打包输出的其他文件命名
        chunkFilename:"static/js/[name].[contenthash:10].chunk.js",
        //图片,字体等通过type:asset处理资源命名方式
        assetModuleFilename:"static/media/[hash:10][ext][query]",
        //原理,在打包前,将path整个目录内容清空,再进行打包
        clean:true, //自动清空上次打包内容
    },
     //加载器
    module:{
        rules:[
            //loader的配置
            {
                test:/\.css$/, //只检测.css结尾的文件
                use:getStyleLoader(),
            },
            {
                test: /\.less$/,
                use:getStyleLoader('less-loader'),
            },
            {
                test: /\.s[ac]ss$/,
                use:getStyleLoader('sass-loader'),
            },
            {
                test: /\.styl$/,
                use:getStyleLoader('stylus-loader'),
            },
            {
                test:/\.(png|jpe?g|glf|webp|svg)$/,
                type:"asset",
                parser:{
                    dataUrlCondition:{
                        //小于10kb的图片转base64
                        //优点,减少请求数量,缺点,体积会更大
                        maxSize:10 * 1024,//10kb
                    }
                },
            },
            {
                test:/\.(ttf|woff2?|mp3|mp4|avi)$/,  //处理字体图标资源或者其他资源
                type:"asset/resource",
             
            },
            {
                test:/\.js$/,  //处理字体图标资源或者其他资源
                include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
                loader:'babel-loader',
                //写这里也行,写外面babel.config.js里面也行
                options:{
                    cacheDirectory:true,//开启babel缓存
                    cacheCompression:false,//关闭缓存文件压缩
                }
            },
            {
                test:/\.vue$/,
                loader:'vue-loader'
            }
        ]
    },
     //插件
    plugins:[
        //plugin的配置
        new ESLintPlugin({
            //检测哪些文件
            context:path.resolve(__dirname,"../src"),
            exclude:"node_modules", //默认值  
            cache:true,//开启缓存
            cacheLocation:path.resolve(__dirname,"../node_modules/.cache/.eslintcache"),  //指定缓存文件
         
        }),
        new HtmlWebpackPlugin({
            template:path.resolve(__dirname,"../public/index.html")
        }),
        new MiniCssExtractPlugin({
            filename:'static/css/[name].[contenthash:10].css',
            chunkFilename:'static/css/[name].[contenthash:10].chunk.css'
        }),
        new CopyPlugin({
            patterns:[
                {
                    from:path.resolve(__dirname,"../public"),
                    to:path.resolve(__dirname,"../dist"),
                    globOptions:{
                        //忽略index.html文件
                        ignore:["**/index.html"]
                    }
                }
            ]
        }),
        new VueLoaderPlugin(),
        //定义环境变量 cross-env定义的环境变量给打包工具使用
        //DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告的问题
        new DefinePlugin({
            __VUE_OPTIONS_API__:true,
            __VUE_PROD_DEVTOOLS__:false
        })
    ],
    optimization:{
        //压缩的操作
        minimizer:[
            //压缩css
            new CssMinimizerPlugin(),
            //压缩js
            new TerserWebpackPlugin(),
            //压缩图片  以下代码打包报错  不知道哪里问题
        //     new ImageMinimizerPlugin({
        //         minimizer: {
        //           implementation: ImageMinimizerPlugin.imageminGenerate,
        //           options: {
        //             plugins: [
        //               ["gifsicle", { interlaced: true }],
        //               ["jpegtran", { progressive: true }],
        //               ["optipng", { optimizationLevel: 5 }],
        //               [
        //                 "svgo",
        //                 {
        //                   plugins: [
        //                     "preset-default",
        //                     "prefixIds",
        //                     {
        //                       name: "sortAttrs",
        //                       params: {
        //                         xmlnsOrder: "alphabetical",
        //                       },
        //                     },
        //                   ],
        //                 },
        //               ],
        //             ],
        //           },
        //         },
        //   }),
        ],
        //代码分割配置
        splitChunks:{
            chunks:"all",
            //其他都用默认值
        },
        runtimeChunk:{
            name:(entrypoint)=>`runtime~${entrypoint.name}.js`,
        },
    },
     //模式
    mode:'production',
    devtool:"source-map",
     //webpack解析模块加载选项
     resolve:{
        //自动补全文件扩展名
        extensions:['.js','.json','.vue']
    },
}

package.json

 "scripts": {
    "start": "npm run dev",
    "dev": "cross-env NODE_ENV=development webpack serve --config ./config/webpack.dev.js",
    "build": "cross-env NODE_ENV=production webpack --config ./config/webpack.prod.js"
  },

合并配置
webpack.config.js

const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
const MiniCssExtractPlugin=require("mini-css-extract-plugin")
const CssMinimizerPlugin=require("css-minimizer-webpack-plugin")
const TerserWebpackPlugin=require("terser-webpack-plugin")
// const ImageMinimizerPlugin=require("image-minimizer-webpack-plugin")
const CopyPlugin=require('copy-webpack-plugin')
const { VueLoaderPlugin}=require('vue-loader')
const {DefinePlugin} =require("webpack")

const isProduction=process.env.NODE_ENV==='production';


//定义一个函数抽取重复的代码  用来获取处理样式的loader
function getStyleLoader(pre){
    return [ //执行顺序,从右到左(从下到上)
                isProduction ?  MiniCssExtractPlugin.loader : 'vue-style-loader', //提取css成单独文件
                "css-loader",  //将css资源编译成commonjs的模块到js中
                {
                    loader:"postcss-loader",
                    options:{ //配置项
                        postcssOptions:{
                            plugins:[
                                "postcss-preset-env",//能解决大多数兼容性问题
                            ]
                        }
                    }
                },
                pre,
            ].filter(Boolean);
}


module.exports={
     //入口
    entry:'./src/main.js', //相对路径
     //输出
    output:{
        //所有文件的输出路径
        //__dirname  nodejs的变量,代表当前文件的文件夹目录
        path:isProduction ? path.resolve(__dirname,'../dist') : undefined,//绝对路径
        //入口文件打包输出文件名
        filename:isProduction ?  'static/js/[name].[contenthash:10].js' : 'static/js/[name].js',
        //给打包输出的其他文件命名
        chunkFilename:isProduction ?  "static/js/[name].[contenthash:10].chunk.js":"static/js/[name].chunk.js",
        //图片,字体等通过type:asset处理资源命名方式
        assetModuleFilename:"static/media/[hash:10][ext][query]",
        //原理,在打包前,将path整个目录内容清空,再进行打包
        clean:true, //自动清空上次打包内容
    },
     //加载器
    module:{
        rules:[
            //loader的配置
            {
                test:/\.css$/, //只检测.css结尾的文件
                use:getStyleLoader(),
            },
            {
                test: /\.less$/,
                use:getStyleLoader('less-loader'),
            },
            {
                test: /\.s[ac]ss$/,
                use:getStyleLoader('sass-loader'),
            },
            {
                test: /\.styl$/,
                use:getStyleLoader('stylus-loader'),
            },
            {
                test:/\.(png|jpe?g|glf|webp|svg)$/,
                type:"asset",
                parser:{
                    dataUrlCondition:{
                        //小于10kb的图片转base64
                        //优点,减少请求数量,缺点,体积会更大
                        maxSize:10 * 1024,//10kb
                    }
                },
            },
            {
                test:/\.(ttf|woff2?|mp3|mp4|avi)$/,  //处理字体图标资源或者其他资源
                type:"asset/resource",
             
            },
            {
                test:/\.js$/,  //处理字体图标资源或者其他资源
                include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
                loader:'babel-loader',
                //写这里也行,写外面babel.config.js里面也行
                options:{
                    cacheDirectory:true,//开启babel缓存
                    cacheCompression:false,//关闭缓存文件压缩
                }
            },
            {
                test:/\.vue$/,
                loader:'vue-loader'
            }
        ]
    },
     //插件
    plugins:[
        //plugin的配置
        new ESLintPlugin({
            //检测哪些文件
            context:path.resolve(__dirname,"../src"),
            exclude:"node_modules", //默认值  
            cache:true,//开启缓存
            cacheLocation:path.resolve(__dirname,"../node_modules/.cache/.eslintcache"),  //指定缓存文件
         
        }),
        new HtmlWebpackPlugin({
            template:path.resolve(__dirname,"../public/index.html")
        }),
        isProduction && new MiniCssExtractPlugin({
            filename:'static/css/[name].[contenthash:10].css',
            chunkFilename:'static/css/[name].[contenthash:10].chunk.css'
        }),
        isProduction && new CopyPlugin({
            patterns:[
                {
                    from:path.resolve(__dirname,"../public"),
                    to:path.resolve(__dirname,"../dist"),
                    globOptions:{
                        //忽略index.html文件
                        ignore:["**/index.html"]
                    }
                }
            ]
        }),
        new VueLoaderPlugin(),
        //定义环境变量 cross-env定义的环境变量给打包工具使用
        //DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告的问题
        new DefinePlugin({
            __VUE_OPTIONS_API__:true,
            __VUE_PROD_DEVTOOLS__:false
        })
    ].filter(Boolean),
    optimization:{
        minimize:isProduction,
        //压缩的操作
        minimizer:[
            //压缩css
            new CssMinimizerPlugin(),
            //压缩js
            new TerserWebpackPlugin(),
            //压缩图片  以下代码打包报错  不知道哪里问题
        //     new ImageMinimizerPlugin({
        //         minimizer: {
        //           implementation: ImageMinimizerPlugin.imageminGenerate,
        //           options: {
        //             plugins: [
        //               ["gifsicle", { interlaced: true }],
        //               ["jpegtran", { progressive: true }],
        //               ["optipng", { optimizationLevel: 5 }],
        //               [
        //                 "svgo",
        //                 {
        //                   plugins: [
        //                     "preset-default",
        //                     "prefixIds",
        //                     {
        //                       name: "sortAttrs",
        //                       params: {
        //                         xmlnsOrder: "alphabetical",
        //                       },
        //                     },
        //                   ],
        //                 },
        //               ],
        //             ],
        //           },
        //         },
        //   }),
        ],
        //代码分割配置
        splitChunks:{
            chunks:"all",
            //其他都用默认值
        },
        runtimeChunk:{
            name:(entrypoint)=>`runtime~${entrypoint.name}.js`,
        },
    },
     //模式
    mode:isProduction ? 'production' :'development',
    devtool:isProduction ? "source-map" :"cheap-module-source-map",
     //webpack解析模块加载选项
     resolve:{
        //自动补全文件扩展名
        extensions:['.js','.json','.vue']
    },
      //开发服务器:不会输出资源,在内存中编译打包
      devServer:{
        host:"localhost",//启动服务器域名
        port:"4000", //启动服务器端口号
        open:true,//是否自动打开浏览器
        hot:true,//开启HMR功能(只能用于开发环境,生成环境不需要了)默认值是true
        historyApiFallback:true, //解决前端路由刷新404问题
    },
}

package.json

 "scripts": {
    "start": "npm run dev",
    "dev": "cross-env NODE_ENV=development webpack serve --config ./config/webpack.config.js",
    "build": "cross-env NODE_ENV=production webpack --config ./config/webpack.config.js"
  },

优化配置

npm install element-plus --save
按需引入
npm install -D unplugin-vue-components unplugin-auto-import

报错解决
报错 1:AutoImport is not a function
解决:是 unplugin-auto-import版本高了,我用的0.17.3。后面降版本,改成0.16.7,这个问题就不报错了。

报错2:Components is not a function
解决:unplugin-vue-components 版本也高了,从0.27.0 降到了 0.25.2 ,就能正常运行了
webpack.config.js

const path=require('path');//nodejs核心模块,专门用来处理路径问题
//安装的插件需要引入
const ESLintPlugin=require('eslint-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin')
const MiniCssExtractPlugin=require("mini-css-extract-plugin")
const CssMinimizerPlugin=require("css-minimizer-webpack-plugin")
const TerserWebpackPlugin=require("terser-webpack-plugin")
// const ImageMinimizerPlugin=require("image-minimizer-webpack-plugin")
const CopyPlugin=require('copy-webpack-plugin')
const { VueLoaderPlugin}=require('vue-loader')
const {DefinePlugin} =require("webpack")

const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')

const isProduction=process.env.NODE_ENV==='production';


//定义一个函数抽取重复的代码  用来获取处理样式的loader
function getStyleLoader(pre){
    return [ //执行顺序,从右到左(从下到上)
                isProduction ?  MiniCssExtractPlugin.loader : 'vue-style-loader', //提取css成单独文件
                "css-loader",  //将css资源编译成commonjs的模块到js中
                {
                    loader:"postcss-loader",
                    options:{ //配置项
                        postcssOptions:{
                            plugins:[
                                "postcss-preset-env",//能解决大多数兼容性问题
                            ]
                        }
                    }
                },
                pre && {
                    loader:pre,
                    options:
                     pre === 'sass-loader'
                      ? {
                         additionalData : `@use "@/styles/element/index.scss" as *;`,
                      }
                      : {},
                },
            ].filter(Boolean);
}


module.exports={
     //入口
    entry:'./src/main.js', //相对路径
     //输出
    output:{
        //所有文件的输出路径
        //__dirname  nodejs的变量,代表当前文件的文件夹目录
        path:isProduction ? path.resolve(__dirname,'../dist') : undefined,//绝对路径
        //入口文件打包输出文件名
        filename:isProduction ?  'static/js/[name].[contenthash:10].js' : 'static/js/[name].js',
        //给打包输出的其他文件命名
        chunkFilename:isProduction ?  "static/js/[name].[contenthash:10].chunk.js":"static/js/[name].chunk.js",
        //图片,字体等通过type:asset处理资源命名方式
        assetModuleFilename:"static/media/[hash:10][ext][query]",
        //原理,在打包前,将path整个目录内容清空,再进行打包
        clean:true, //自动清空上次打包内容
    },
     //加载器
    module:{
        rules:[
            //loader的配置
            {
                test:/\.css$/, //只检测.css结尾的文件
                use:getStyleLoader(),
            },
            {
                test: /\.less$/,
                use:getStyleLoader('less-loader'),
            },
            {
                test: /\.s[ac]ss$/,
                use:getStyleLoader('sass-loader'),
            },
            {
                test: /\.styl$/,
                use:getStyleLoader('stylus-loader'),
            },
            {
                test:/\.(png|jpe?g|glf|webp|svg)$/,
                type:"asset",
                parser:{
                    dataUrlCondition:{
                        //小于10kb的图片转base64
                        //优点,减少请求数量,缺点,体积会更大
                        maxSize:10 * 1024,//10kb
                    }
                },
            },
            {
                test:/\.(ttf|woff2?|mp3|mp4|avi)$/,  //处理字体图标资源或者其他资源
                type:"asset/resource",
             
            },
            {
                test:/\.js$/,  //处理字体图标资源或者其他资源
                include:path.resolve(__dirname,"../src"),//只处理src下的文件,其他文件不出来
                loader:'babel-loader',
                //写这里也行,写外面babel.config.js里面也行
                options:{
                    cacheDirectory:true,//开启babel缓存
                    cacheCompression:false,//关闭缓存文件压缩
                }
            },
            {
                test:/\.vue$/,
                loader:'vue-loader',
                options:{
                    //开启缓存
                    cacheDirectory:path.resolve(__dirname,"../node_modules/.cache/vue-loader"),
                }
            }
        ]
    },
     //插件
    plugins:[
        //plugin的配置
        new ESLintPlugin({
            //检测哪些文件
            context:path.resolve(__dirname,"../src"),
            exclude:"node_modules", //默认值  
            cache:true,//开启缓存
            cacheLocation:path.resolve(__dirname,"../node_modules/.cache/.eslintcache"),  //指定缓存文件
         
        }),
        new HtmlWebpackPlugin({
            template:path.resolve(__dirname,"../public/index.html")
        }),
        isProduction && new MiniCssExtractPlugin({
            filename:'static/css/[name].[contenthash:10].css',
            chunkFilename:'static/css/[name].[contenthash:10].chunk.css'
        }),
        isProduction && new CopyPlugin({
            patterns:[
                {
                    from:path.resolve(__dirname,"../public"),
                    to:path.resolve(__dirname,"../dist"),
                    globOptions:{
                        //忽略index.html文件
                        ignore:["**/index.html"]
                    }
                }
            ]
        }),
        new VueLoaderPlugin(),
        //定义环境变量 cross-env定义的环境变量给打包工具使用
        //DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告的问题
        new DefinePlugin({
            __VUE_OPTIONS_API__:true,
            __VUE_PROD_DEVTOOLS__:false
        }),
        //按需加载element-plus
        AutoImport({
             resolvers: [ElementPlusResolver()],
        }),
        Components({
             resolvers: [ElementPlusResolver({
                //自定义主题,引入sass
                importStyle:'sass'
             })],
        }),
    ].filter(Boolean),
    optimization:{
        minimize:isProduction,
        //压缩的操作
        minimizer:[
            //压缩css
            new CssMinimizerPlugin(),
            //压缩js
            new TerserWebpackPlugin(),
            //压缩图片  以下代码打包报错  不知道哪里问题
        //     new ImageMinimizerPlugin({
        //         minimizer: {
        //           implementation: ImageMinimizerPlugin.imageminGenerate,
        //           options: {
        //             plugins: [
        //               ["gifsicle", { interlaced: true }],
        //               ["jpegtran", { progressive: true }],
        //               ["optipng", { optimizationLevel: 5 }],
        //               [
        //                 "svgo",
        //                 {
        //                   plugins: [
        //                     "preset-default",
        //                     "prefixIds",
        //                     {
        //                       name: "sortAttrs",
        //                       params: {
        //                         xmlnsOrder: "alphabetical",
        //                       },
        //                     },
        //                   ],
        //                 },
        //               ],
        //             ],
        //           },
        //         },
        //   }),
        ],
        //代码分割配置
        splitChunks:{
            chunks:"all",
            //其他都用默认值
            cacheGroups:{
                vue:{
                   test:/[\\/]node_modules[\\/]vue(.*)?[\\/]/,
                   name:'vue-chunk',
                   priority:40,
                },
                elementPlus:{
                    test:/[\\/]node_modules[\\/]element-plus[\\/]/,
                    name:'elementPlus-chunk',
                    priority:30,
                },
                libs:{
                    test:/[\\/]node_modules[\\/]/,
                    name:'libs-chunk',
                    priority:20,
                },
            }
        },
        runtimeChunk:{
            name:(entrypoint)=>`runtime~${entrypoint.name}.js`,
        },
    },
     //模式
    mode:isProduction ? 'production' :'development',
    devtool:isProduction ? "source-map" :"cheap-module-source-map",
     //webpack解析模块加载选项
     resolve:{
        //自动补全文件扩展名
        extensions:['.js','.json','.vue'],
        //路径别名
        alias:{
            '@':path.resolve(__dirname,'../src'),
        }
    },
      //开发服务器:不会输出资源,在内存中编译打包
      devServer:{
        host:"localhost",//启动服务器域名
        port:"4000", //启动服务器端口号
        open:true,//是否自动打开浏览器
        hot:true,//开启HMR功能(只能用于开发环境,生成环境不需要了)默认值是true
        historyApiFallback:true, //解决前端路由刷新404问题
    },
    //关闭性能分析,提升打包速度
    performance:false,
}

自定义主题 styles/element/index.scss

// styles/element/index.scss
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
  $colors: (
    'primary': (
      'base': green,
    ),
  ),
);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/602629.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

以steamDB的好评排名为引 - 详解wilson评分算法

写在前面 中文互联网上缺少关于二项分布估计的知识&#xff0c;而对二项分布参数如何准确且合理的估计的技巧&#xff0c;实际上在商业数据分析领域用处极多。尤其是在互联网企业&#xff0c;算法排名的依据很大程度要依赖这个统计量。我试图抛砖引玉&#xff0c;以steamDB的评…

语言模型测试系列【7】

语言模型 文心一言星火认知大模型通义千问豆包360智脑百川大模型腾讯混元助手Kimi Chat商量C知道 今天看CSDN文章&#xff0c;看到了斐波那契数列这个有趣的数列计算&#xff0c;然后就在文心一言中对答了一波&#xff0c;给的答案很完整&#xff0c;而且给出来python的实现代…

WDW-10B微机控制电子万能试验机技术方案

一&#xff0e;设备外观照片&#xff1a; 项目简介&#xff1a; 微机控制电子式万能试验机是专门针对高等院校、各种金属、非金属科研厂家及国家级质检单位而设计的高端微机控制电子式万能试验机、计算机系统通过全数字控制器&#xff0c;经调速系统控制伺服电机转动&#xff…

证照之星是什么软件 证照之星哪个版本好用?证照之星支持哪些相机 证照之星XE免费版

许多人都需要使用证件照&#xff0c;为了满足这一需求&#xff0c;人们会使用照相机、手机、电脑等工具进行拍摄。除此之外&#xff0c;市面上还存在专门的证件照拍摄软件&#xff0c;比如证照之星。那么&#xff0c;各位小伙伴是否了解证照之星哪个版本好用&#xff0c;证照之…

嵌入式RTOS面试题目

用过哪些嵌入式操作系统&#xff1f;使⽤RTOS和裸机代码开发有什么区别&#xff08;优缺点&#xff09;&#xff1f; 之前的⼀个项⽬是采⽤裸机代码开发的&#xff0c;写起来还⾏&#xff0c;通过状态机来管理业务逻辑和各种外设。 但是随着外设的增加&#xff0c;任务之间的…

【WEB前端2024】简单几步制作web3d《萌宠星球》智体节点模板(2)

【WEB前端2024】简单几步制作web3d《萌宠星球》智体节点模板&#xff08;2&#xff09; 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体…

【优选算法】——Leetcode——611. 有效三角形的个数

目录 ​编辑 1.题目 2 .补充知识 3.解法⼀&#xff08;暴⼒求解&#xff09;&#xff08;可能会超时&#xff09;&#xff1a; 算法思路&#xff1a; 算法代码&#xff1a; 4.解法⼆&#xff08;排序双指针&#xff09;&#xff1a; 算法思路&#xff1a; 以输入: nums …

2024年5月12日(星期天)骑行海囗

2024年5月12日 (星期天&#xff09;骑行海口&#xff0c;早8:30到9:00大观公园门口集合&#xff0c;9:30准时出发【因迟到者&#xff0c;骑行速度快者&#xff0c;可自行追赶偶遇。】 偶遇地点:大观公园门口集合 &#xff0c;家住东&#xff0c;西&#xff0c;南&#xff0c;北…

wangEditor富文本编辑器与layui图片上传

记录&#xff1a;js 显示默认的wangEditor富文本编辑器内容和图片 <style>body {background-color: #ffffff;}.layui-form-select dl{z-index:100000;} </style> <div class"layui-form layuimini-form"><div class"layui-form-item"…

MT3034 算术招亲

跟MT3033新的表达式类似&#xff0c;只多了一个括号合法性的判断 #include <bits/stdc.h> using namespace std; const int N 40; bool tag[N]; bool is_op(char c) {return c || c - || c * || c / || c ^; } int priority(char op) { // 优先级排序if (op ||…

数据结构-线性表-应用题-2.2-9

线性表&#xff08;a1,a2,a3,...,an&#xff09;中的元素递增有序且按顺序存储于计算机内。要求设计一个算法&#xff0c;用最少的时间在表中查找数值为x的元素&#xff0c;若找到&#xff0c;则将其与后继元素位置相交换&#xff0c;若找不到&#xff0c;则将其插入表中并使表…

钉钉开放平台创建企业内部H5微应用或者小程序

前言&#xff1a; 在当今企业数字化转型的浪潮中&#xff0c;创建企业内部H5微应用或小程序已成为提升工作效率和促进内部沟通的重要举措。发话不多说本文将介绍如何利用钉钉平台快速创建这些应用&#xff0c;让企业内部的工作更加便捷高效。 步骤 1.在浏览器打开链接…

618好物大放送:5大必买好物,抢购倒计时开始!

嘿&#xff0c;各位购物达人们&#xff0c;年度最燃购物盛宴618已经进入准备阶段&#xff0c;是不是已经开始摩拳擦掌&#xff0c;准备迎接这场消费的狂欢了呢&#xff1f;每年的这个时候&#xff0c;各大电商平台都会推出力度空前的优惠活动&#xff0c;从数码尖货到生活日用品…

Python运维-文本处理、系统和文件信息监控、外部命令

本节主要目录如下&#xff1a; 一、文本处理 1.1、Python编码解码 1.2、文件操作 1.3、读写配置文件 1.4、解析XML文件 二、系统信息监控 2.1、监控CPU信息 2.2、监控内存信息 2.3、监控磁盘信息 2.4、监控网络信息 2.5、获取进程信息 2.6、实例&#xff1a;常见的…

CentOS操作

1.如何修改主机名 方法一&#xff1a; 修改命令&#xff1a;hostnamectl set-hostname 主机名 查看命令&#xff1a;hostname 方法二和方法三都是永久改变主机名&#xff0c;需要密码验证 方法二 修改命令&#xff1a;nmcli general hostname 主机名 查看命令&#xff…

[图解]SysML和EA建模住宅安全系统-02

1 00:00:00,900 --> 00:00:02,690 这个就是一个块定义图了 2 00:00:03,790 --> 00:00:04,780 简称BDD 3 00:00:05,610 --> 00:00:08,070 实际上就是UML里面的类图 4 00:00:08,080 --> 00:00:09,950 和组件图的一个结合体 5 00:00:13,150 --> 00:00:14,690 我…

正点原子i.MX 93开发板,双核A55+M33+NPU,双路RS485FDCAN千兆网,异核/AI/工业开发!

正点原子i.MX 93开发板新品上市&#xff01;双核A55M33NPU&#xff0c;双路RS485&FDCAN&千兆网&#xff0c;异核/AI/工业开发&#xff01; NXP的i.MX系列是一系列面向多媒体和工业应用的ARM架构微处理器。从i.MX6U到i.MX93&#xff0c;这一系列经历了显著的发展&#x…

指代消解类方法梳理

概念&#xff1a; MLM&#xff1a;带遮罩的语言模型 NSP&#xff1a;单句预测&#xff0c;任务包括两个输入序列 SBO&#xff1a;分词边界目标 1.spanBERT&#xff0c;2019 spanBERT是对bert从分词到文本跨度的优化&#xff0c;主要有两方面的优化&#xff1a;&#xff08…

Stable Diffusion Ai绘画模型推荐:二次元Coriander_Mix v1大模型推荐

负tag嵌入式:EasyNegative,badhandv4 此模型经测试是写实偏3D的效果 画质灰暗的话请加&#xff1a;VAE840000 或者负tag&#xff1a;(watermark:2),(blurry:2),fat,paintings,sketches,(worst quality:2),(low quality:2),(normal quality:2),((monochrome)), ((grayscale))…

iOS xib布局

1.多次启动发现启动图和截屏的图片不一致,设置launch storyboard 不能到顶部 https://blog.csdn.net/u011960171/article/details/104053696/ 2.multipiler是比例&#xff0c;需要控制顺序1.视图&#xff0c;2父视图&#xff0c;选择宽度比例&#xff0c;默认是1 3.Aspect R…
最新文章