使用Webpack搭建项目(vue篇)

news2024/11/16 8:28:00

本篇承接使用Webpack搭建项目(react篇)

由于大部分配置一样,我们从上一篇react项目中,复制webpack.dev.js以及webpack.prod.js

开发模式

1.删除ReactRefreshWebpackPlugin

2.自动补充拓展名修改为.vue文件,同时处理js文件,不是jsx

const path = require("path")
const EslintWebpackPlugin = require("eslint-webpack-plugin")
const HtmlWebpackPlugin = require("html-webpack-plugin")
//返回处理样式的loader函数
let getStyleLoaders=function(pre){
    return[
        "style-loader", "css-loader", {
            //处理兼容性问题,配合package.json中的browserslist来指定兼容性做到什么程度
            loader: "postcss-loader",
            options: {
                postcssOptions: {
                    plugins: ["postcss-preset-env"]
                }
            }
        },
        pre
    ].filter(Boolean)
}
module.exports = {
    entry: "./src/main.js",
    output: {
        path: undefined,
        filename: "static/js/[name].js",
        chunkFilename: "static/js/[name].chunk.js",
        assetModuleFilename: "static/media/[hash:10][ext][query]"
    },
    module: {
        rules: [
            // 处理css
            {
                test: /\.css$/,
                use: getStyleLoaders(),
            },
            {
                test: /\.less$/,
                use: getStyleLoaders('less-loader'),
            },
            {
                test: /\.s[ac]ss$/,
                use: getStyleLoaders('sass-loader'),
            },
            {
                test: /\.styl$/,
                use: getStyleLoaders('stylus-loader'),
            },
            //处理图片
            {
                test:/\.(jpe?g|png|gif|webp|svg)$/,
                type:"asset",
                parser:{
                    dataCondition:{
                        maxSize:10*1024, //小于10kb以下可以转为base64,减少请求数量
                    }
                }
            },
            // 处理其他资源
            {
                test:/\.(woff2?|ttf)$/,
                type:"asset/resource",
            },
            //处理js
            {
                test:/\.js$/,
                include:path.resolve(__dirname,'../src'),
                loader:"babel-loader",
                options:{
                    cacheDirectory:true,
                    cacheCompression:false,
                }
            }
        ]
    },
    plugins:[
        new EslintWebpackPlugin({
            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"),
        }),
    ],
    mode:"development",
    devtool:"cheap-module-source-map",
    optimization:{
        splitChunks:{
            chunks:"all" //代码分割
        },
        runtimeChunk:{
            name:entrypoint=>`runtime~${entrypoint.name}.js` //单独储存引用的chunk的打包地址,main.js不会随着其他模块的变化导致地址变化而打包变化
        }
    },
    //webpack解析块加载选项
    resolve:{
        //自动补全文件拓展名
        extensions:[".vue",".js",".json"]
    },
    devServer:{
        host:"localhost",
        port:3000,
        open:true,
        hot:true,
        historyApiFallback:true//解决前端路由刷新404的问题
    }
}

3.配置vue loader

npm init -y

npm install -D vue-loader vue-template-compiler
const { VueLoaderPlugin } = require('vue-loader')



let getStyleLoaders = function (pre) {
    return [
        "vue-style-loader", "css-loader", {
            //处理兼容性问题,配合package.json中的browserslist来指定兼容性做到什么程度
            loader: "postcss-loader",
            options: {
                postcssOptions: {
                    plugins: ["postcss-preset-env"]
                }
            }
        },
        pre
    ].filter(Boolean)
}


{
                test: /\.vue$/,
                loader: 'vue-loader'
            }


plugins: [
        new EslintWebpackPlugin({
            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 VueLoaderPlugin()
    ],

接下来下载依赖:

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 stylus-loader sass babel-loader vue-loader webpack webpack-cli webpack-dev-server -D

新建配置.eslintrc.js

npm i @babel/eslint-parser -D
module.exports={
    root:true, //根目录就是当前
    env:{
        node:true //启用node中的变量
    },
    extends:["plugin:vue/vue3-essential","eslint:recommended"],//无需安装,已经内置有
    parserOptions:{
        parser:"@babel/eslint-parser" //需要安装
    }
}

新建配置babel.config.js

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

补全src文件以及public文件,下载vue(默认vue3)

npm i vue
//main.js
import {createApp} from "vue"
import App from "./App"

createApp(App).mount(document.getElementById("app"))
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue-cli</title>
</head>
<body>
    <div id="app"></div>
</body>
</html>
//App.vue
<template>
    <h1 class="title">hello app!</h1>
</template>
<script>
export default{
    name:"App"
}
</script>
<style lang="less">
.title{
    color:red
}
</style>

配置package.json

 npm i cross-env -D
"scripts": {
    "start":"npm run dev",
    "dev":"cross-env NODE_ENV=development webpack serve --config ./config/webpack.dev.js"
  },
npm i eslint-plugin-vue -D

然后输入 npm start ,发现如下警告:

我们需要定义这两个标识:

const {DefinePlugin} = require("webpack")




plugins: [
        new EslintWebpackPlugin({
            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 VueLoaderPlugin(),
        //cross-env定义的环境变量给webpack使用
        //DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告问题
        new DefinePlugin({
            __VUE_OPTIONS_API__:true,
            __VUE_PROD_DEVTOOLS__:false
        })
    ],

在编译就解决了,热模块更新HMR,都已内置,无需再配置了。

下面配置一下路由:

npm i vue-router

router.js

import { createRouter, createWebHistory } from "vue-router";

export default createRouter({
    history:createWebHistory(),
    routes:[
        {
            path:"/home",
            component:()=>import ("../views/Home/Home.vue")
        },
        {
            path:"/about",
            component:()=>import ("../views/About/About.vue")
        }
    ]
})

main.js

import {createApp} from "vue"
import App from "./App"
import router from "./router/router"

createApp(App).use(router).mount(document.getElementById("app"))

以上就是开发环境的基本配置,webpack.dev.js代码如下:

const path = require("path")
const EslintWebpackPlugin = require("eslint-webpack-plugin")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const { VueLoaderPlugin } = require('vue-loader')
const {DefinePlugin} = require("webpack")
//返回处理样式的loader函数
let getStyleLoaders = function (pre) {
    return [
        "vue-style-loader", "css-loader", {
            //处理兼容性问题,配合package.json中的browserslist来指定兼容性做到什么程度
            loader: "postcss-loader",
            options: {
                postcssOptions: {
                    plugins: ["postcss-preset-env"]
                }
            }
        },
        pre
    ].filter(Boolean)
}
module.exports = {
    entry: "./src/main.js",
    output: {
        path: undefined,
        filename: "static/js/[name].js",
        chunkFilename: "static/js/[name].chunk.js",
        assetModuleFilename: "static/media/[hash:10][ext][query]"
    },
    module: {
        rules: [
            // 处理css
            {
                test: /\.css$/,
                use: getStyleLoaders(),
            },
            {
                test: /\.less$/,
                use: getStyleLoaders('less-loader'),
            },
            {
                test: /\.s[ac]ss$/,
                use: getStyleLoaders('sass-loader'),
            },
            {
                test: /\.styl$/,
                use: getStyleLoaders('stylus-loader'),
            },
            //处理图片
            {
                test: /\.(jpe?g|png|gif|webp|svg)$/,
                type: "asset",
                parser: {
                    dataCondition: {
                        maxSize: 10 * 1024, //小于10kb以下可以转为base64,减少请求数量
                    }
                }
            },
            // 处理其他资源
            {
                test: /\.(woff2?|ttf)$/,
                type: "asset/resource",
            },
            //处理js
            {
                test: /\.js$/,
                include: path.resolve(__dirname, '../src'),
                loader: "babel-loader",
                options: {
                    cacheDirectory: true,
                    cacheCompression: false,
                }
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            }
        ]
    },
    plugins: [
        new EslintWebpackPlugin({
            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 VueLoaderPlugin(),
        //cross-env定义的环境变量给webpack使用
        //DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告问题
        new DefinePlugin({
            __VUE_OPTIONS_API__:true,
            __VUE_PROD_DEVTOOLS__:false
        })
    ],
    mode: "development",
    devtool: "cheap-module-source-map",
    optimization: {
        splitChunks: {
            chunks: "all" //代码分割
        },
        runtimeChunk: {
            name: entrypoint => `runtime~${entrypoint.name}.js` //单独储存引用的chunk的打包地址,main.js不会随着其他模块的变化导致地址变化而打包变化
        }
    },
    //webpack解析块加载选项
    resolve: {
        //自动补全文件拓展名
        extensions: [".vue", ".js", ".json"]
    },
    devServer: {
        host: "localhost",
        port: 3000,
        open: true,
        hot: true,
        historyApiFallback: true//解决前端路由刷新404的问题,主要解决history模式i,hash模式没有该问题。
    }
}

 生产模式

修改和优化webpack.prod.js,修改只处理js文件,添加vue-loader,修改devtool,修改文件补充的拓展

{
                test: /\.js$/,
                include: path.resolve(__dirname, '../src'),
                loader: "babel-loader",
                options: {
                    cacheDirectory: true,
                    cacheCompression: false,
                }
            },
const { VueLoaderPlugin } = require('vue-loader')
const {DefinePlugin} = require("webpack")



plugins: [
        ...
        new VueLoaderPlugin(),
        //cross-env定义的环境变量给webpack使用
        //DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告问题
        new DefinePlugin({
            __VUE_OPTIONS_API__:true,
            __VUE_PROD_DEVTOOLS__:false
        })
    ],
devtool: "source-map",
resolve: {
        //自动补全文件拓展名
        extensions: [".vue", ".js", ".json"]
    }

添加favicon.ico图片

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
    <title>vue-cli</title>
</head>
<body>
    <div id="app"></div>
</body>
</html>

下载依赖:

npm i mini-css-extract-plugin css-minimizer-webpack-plugin copy-webpack-plugin -D

npm install image-minimizer-webpack-plugin imagemin --save-dev

//无损

npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo --save-dev

开发模式基本配置完毕,webpack.prod.js代码如下:

const path = require("path")
const EslintWebpackPlugin = require("eslint-webpack-plugin")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin")
const TerserWebpackPlugin = require("terser-webpack-plugin")
const ImageMinimizerWebpackPlugin = require("image-minimizer-webpack-plugin")
const CopyWebpackPlugin = require("copy-webpack-plugin")
const { VueLoaderPlugin } = require('vue-loader')
const {DefinePlugin} = require("webpack")
//返回处理样式的loader函数
let getStyleLoaders = function (pre) {
    return [
        MiniCssExtractPlugin.loader, "css-loader", {
            //处理兼容性问题,配合package.json中的browserslist来指定兼容性做到什么程度
            loader: "postcss-loader",
            options: {
                postcssOptions: {
                    plugins: ["postcss-preset-env"]
                }
            }
        },
        pre
    ].filter(Boolean)
}
module.exports = {
    entry: "./src/main.js",
    output: {
        path: path.resolve(__dirname, "../dist"),
        filename: "static/js/[name].[contenthash:10].js",
        chunkFilename: "static/js/[name].[contenthash:10].chunk.js",
        assetModuleFilename: "static/media/[hash:10][ext][query]",
        clean: true
    },
    module: {
        rules: [
            // 处理css
            {
                test: /\.css$/,
                use: getStyleLoaders(),
            },
            {
                test: /\.less$/,
                use: getStyleLoaders('less-loader'),
            },
            {
                test: /\.s[ac]ss$/,
                use: getStyleLoaders('sass-loader'),
            },
            {
                test: /\.styl$/,
                use: getStyleLoaders('stylus-loader'),
            },
            //处理图片
            {
                test: /\.(jpe?g|png|gif|webp|svg)$/,
                type: "asset",
                parser: {
                    dataCondition: {
                        maxSize: 10 * 1024, //小于10kb以下可以转为base64,减少请求数量
                    }
                }
            },
            // 处理其他资源
            {
                test: /\.(woff2?|ttf)$/,
                type: "asset/resource",
            },
            //处理js
            {
                test: /\.js$/,
                include: path.resolve(__dirname, '../src'),
                loader: "babel-loader",
                options: {
                    cacheDirectory: true,
                    cacheCompression: false,
                }
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            }
        ]
    },
    plugins: [
        new EslintWebpackPlugin({
            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 CopyWebpackPlugin({//复制到dist文件下
            patterns: [
                {
                    from: path.resolve(__dirname, "../public"), to: "../dist", globOptions: {
                        ignore: ["**/index.html", "**/ignored-directory/**"],//忽略Index.html文件
                    },
                }
            ]
        }),
        new VueLoaderPlugin(),
        //cross-env定义的环境变量给webpack使用
        //DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告问题
        new DefinePlugin({
            __VUE_OPTIONS_API__:true,
            __VUE_PROD_DEVTOOLS__:false
        })
    ],
    mode: "production",
    devtool: "source-map",
    optimization: {
        splitChunks: {
            chunks: "all" //代码分割
        },
        runtimeChunk: {
            name: entrypoint => `runtime~${entrypoint.name}.js` //单独储存引用的chunk的打包地址,main.js不会随着其他模块的变化导致地址变化而打包变化
        },
        minimizer: [
            new CssMinimizerWebpackPlugin(),
            new TerserWebpackPlugin(),
            new ImageMinimizerWebpackPlugin({
                minimizer: {
                    implementation: ImageMinimizerWebpackPlugin.imageminGenerate,
                    options: {
                        plugins: [
                            ["gifsicle", { interlaced: true }],
                            ["jpegtran", { progressive: true }],
                            ["optipng", { optimizationLevel: 5 }],
                            [
                                "svgo",
                                {
                                    plugins: [
                                        "preset-default",
                                        "prefixIds",
                                        {
                                            name: "sortAttrs",
                                            params: {
                                                xmlnsOrder: "alphabetical",
                                            },
                                        },
                                    ],
                                },
                            ],
                        ],
                    },
                },
            }),
        ]
    },
    //webpack解析块加载选项
    resolve: {
        //自动补全文件拓展名
        extensions: [".vue", ".js", ".json"]
    }
}

合并开发和生产模式 

复制webpack.prod.js为webpack.config.js


const isProduction = process.env.NODE_ENV == "production"


output: {
        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].[contenthash:10].chunk.js",
        assetModuleFilename: "static/media/[hash:10][ext][query]",
        clean: true
    },



plugins: [
        new EslintWebpackPlugin({
            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 CopyWebpackPlugin({//复制到dist文件下
            patterns: [
                {
                    from: path.resolve(__dirname, "../public"), to: "../dist", globOptions: {
                        ignore: ["**/index.html", "**/ignored-directory/**"],//忽略Index.html文件
                    },
                }
            ]
        }),
        new VueLoaderPlugin(),
        //cross-env定义的环境变量给webpack使用
        //DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告问题
        new DefinePlugin({
            __VUE_OPTIONS_API__:true,
            __VUE_PROD_DEVTOOLS__:false
        })
    ].filter(Boolean),
devtool: isProduction? "source-map":"cheap-module-source-map",
optimization: {
        splitChunks: {
            chunks: "all" //代码分割
        },
        runtimeChunk: {
            name: entrypoint => `runtime~${entrypoint.name}.js` //单独储存引用的chunk的打包地址,main.js不会随着其他模块的变化导致地址变化而打包变化
        },
        minimize:isProduction,
        minimizer: [
            new CssMinimizerWebpackPlugin(),
            new TerserWebpackPlugin(),
            new ImageMinimizerWebpackPlugin({
                minimizer: {
                    implementation: ImageMinimizerWebpackPlugin.imageminGenerate,
                    options: {
                        plugins: [
                            ["gifsicle", { interlaced: true }],
                            ["jpegtran", { progressive: true }],
                            ["optipng", { optimizationLevel: 5 }],
                            [
                                "svgo",
                                {
                                    plugins: [
                                        "preset-default",
                                        "prefixIds",
                                        {
                                            name: "sortAttrs",
                                            params: {
                                                xmlnsOrder: "alphabetical",
                                            },
                                        },
                                    ],
                                },
                            ],
                        ],
                    },
                },
            }),
        ]
    },
devServer: {
        host: "localhost",
        port: 3000,
        open: true,
        hot: 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"
  },

然后输入指令尝试打包和编译,合并就是这些,webpack.config.js完整代码如下:

const path = require("path")
const EslintWebpackPlugin = require("eslint-webpack-plugin")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin")
const TerserWebpackPlugin = require("terser-webpack-plugin")
const ImageMinimizerWebpackPlugin = require("image-minimizer-webpack-plugin")
const CopyWebpackPlugin = require("copy-webpack-plugin")
const { VueLoaderPlugin } = require('vue-loader')
const {DefinePlugin} = require("webpack")

const isProduction = process.env.NODE_ENV == "production"

console.log(isProduction);
//返回处理样式的loader函数
let getStyleLoaders = function (pre) {
    return [
        isProduction?MiniCssExtractPlugin.loader:"vue-style-loader", "css-loader", {
            //处理兼容性问题,配合package.json中的browserslist来指定兼容性做到什么程度
            loader: "postcss-loader",
            options: {
                postcssOptions: {
                    plugins: ["postcss-preset-env"]
                }
            }
        },
        pre
    ].filter(Boolean)
}
module.exports = {
    entry: "./src/main.js",
    output: {
        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].[contenthash:10].chunk.js",
        assetModuleFilename: "static/media/[hash:10][ext][query]",
        clean: true
    },
    module: {
        rules: [
            // 处理css
            {
                test: /\.css$/,
                use: getStyleLoaders(),
            },
            {
                test: /\.less$/,
                use: getStyleLoaders('less-loader'),
            },
            {
                test: /\.s[ac]ss$/,
                use: getStyleLoaders('sass-loader'),
            },
            {
                test: /\.styl$/,
                use: getStyleLoaders('stylus-loader'),
            },
            //处理图片
            {
                test: /\.(jpe?g|png|gif|webp|svg)$/,
                type: "asset",
                parser: {
                    dataCondition: {
                        maxSize: 10 * 1024, //小于10kb以下可以转为base64,减少请求数量
                    }
                }
            },
            // 处理其他资源
            {
                test: /\.(woff2?|ttf)$/,
                type: "asset/resource",
            },
            //处理js
            {
                test: /\.js$/,
                include: path.resolve(__dirname, '../src'),
                loader: "babel-loader",
                options: {
                    cacheDirectory: true,
                    cacheCompression: false,
                }
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            }
        ]
    },
    plugins: [
        new EslintWebpackPlugin({
            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 CopyWebpackPlugin({//复制到dist文件下
            patterns: [
                {
                    from: path.resolve(__dirname, "../public"), to: "../dist", globOptions: {
                        ignore: ["**/index.html", "**/ignored-directory/**"],//忽略Index.html文件
                    },
                }
            ]
        }),
        new VueLoaderPlugin(),
        //cross-env定义的环境变量给webpack使用
        //DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告问题
        new DefinePlugin({
            __VUE_OPTIONS_API__:true,
            __VUE_PROD_DEVTOOLS__:false
        })
    ].filter(Boolean),
    mode:isProduction? "production":"development",
    devtool: isProduction? "source-map":"cheap-module-source-map",
    optimization: {
        splitChunks: {
            chunks: "all" //代码分割
        },
        runtimeChunk: {
            name: entrypoint => `runtime~${entrypoint.name}.js` //单独储存引用的chunk的打包地址,main.js不会随着其他模块的变化导致地址变化而打包变化
        },
        minimize:isProduction,
        minimizer: [
            new CssMinimizerWebpackPlugin(),
            new TerserWebpackPlugin(),
            new ImageMinimizerWebpackPlugin({
                minimizer: {
                    implementation: ImageMinimizerWebpackPlugin.imageminGenerate,
                    options: {
                        plugins: [
                            ["gifsicle", { interlaced: true }],
                            ["jpegtran", { progressive: true }],
                            ["optipng", { optimizationLevel: 5 }],
                            [
                                "svgo",
                                {
                                    plugins: [
                                        "preset-default",
                                        "prefixIds",
                                        {
                                            name: "sortAttrs",
                                            params: {
                                                xmlnsOrder: "alphabetical",
                                            },
                                        },
                                    ],
                                },
                            ],
                        ],
                    },
                },
            }),
        ]
    },
    //webpack解析块加载选项
    resolve: {
        //自动补全文件拓展名
        extensions: [".vue", ".js", ".json"]
    },
    devServer: {
        host: "localhost",
        port: 3000,
        open: true,
        hot: true,
        historyApiFallback: true//解决前端路由刷新404的问题
    }
}

拓展:配置element-plus

 npm i element-plus

我们配置按需引入:

npm install -D unplugin-vue-components unplugin-auto-import

修改webpack.config.js文件

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

plugins: [
        new EslintWebpackPlugin({
            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 CopyWebpackPlugin({//复制到dist文件下
            patterns: [
                {
                    from: path.resolve(__dirname, "../public"), to: "../dist", globOptions: {
                        ignore: ["**/index.html", "**/ignored-directory/**"],//忽略Index.html文件
                    },
                }
            ]
        }),
        new VueLoaderPlugin(),
        //cross-env定义的环境变量给webpack使用
        //DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告问题
        new DefinePlugin({
            __VUE_OPTIONS_API__: true,
            __VUE_PROD_DEVTOOLS__: false
        }),
        AutoImport({
            resolvers: [ElementPlusResolver()],
        }),
        Components({
            resolvers: [ElementPlusResolver()],
        }),
    ].filter(Boolean),

引入即可:

<template>
    <h1 class="title">hello app!</h1>
    <ElButton>按钮</ELButton>
    <router-link to="/home">Home</router-link>
    <router-link to="/about">About</router-link>
    <!-- <Home />
    <About /> -->
    <router-view></router-view>
</template>
<script>
import Home from "./views/Home/Home"
import About from "./views/About/About"
import {ElButton} from 'element-plus'
export default{
    name:"App",
    components:{Home,About,ElButton}
}
</script>
<style lang="less">
.title{
    color:red
}
</style>

修改主题:

创建index.scss文件在src下:

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

 配置webpack.config.js

let getStyleLoaders = function (pre) {
    return [
        isProduction ? MiniCssExtractPlugin.loader : "vue-style-loader", "css-loader", {
            //处理兼容性问题,配合package.json中的browserslist来指定兼容性做到什么程度
            loader: "postcss-loader",
            options: {
                postcssOptions: {
                    plugins: ["postcss-preset-env"]
                }
            }
        },
        pre &&{
            loader:pre,
            options:pre=="sass-loader"?{
                additionalData: `@use "@/styles/elementPlus/index.scss" as *;`,
            }:{}
        }
    ].filter(Boolean)
}

配置别名:

resolve: {
        //自动补全文件拓展名
        extensions: [".vue", ".js", ".json"],
        alias:{
            "@":path.resolve(__dirname,"../src")
        }
    },
Components({
            resolvers: [ElementPlusResolver({
                //自定义主题配置引入sass
                importStyle: "sass"
            })],
        }),

配置后即可查看页面,配置成功。Button 按钮 | Element Plus

优化一下cacheGroup的配置:我们希望打包可以分开打包:

optimization: {
        splitChunks: {
            chunks: "all", //代码分割
            cacheGroups:{
                vue:{ // 一起打包成一个js文件
                    test:/[\\/]node_modules[\\/]vue(.*)?[\\/]/,
                    name:'chunk-vue',
                    priority:40, //打包优先级权重
                },
                elementPlus:{ //antd单独打包
                    test:/[\\/]node_modules[\\/]element-plus[\\/]/,
                    name:'chunk-elementPlus',
                    priority:30,
                },
                lib:{ //node_modules单独打包
                    test:/[\\/]node_modules[\\/]/,
                    name:'chunk-lib',
                    priority:20,
                },
            }
        },

关闭性能分析:

performance:false,

webpack内部做一下缓存:

{
                test: /\.vue$/,
                loader: 'vue-loader',
                options:{
                    //开启缓存提高第二次打包速度
                    cacheDirectory:path.resolve(__dirname,"../node_modules/.cache/vue-loader")
                }
            }

 开启webpack内部缓存,有助于下次的打包编译节省时间:

cache: { //可开启webpack5内置缓存
        type: 'filesystem',
        allowCollectingMemory: true
    }

我们就完成了配置:

const path = require("path")
const EslintWebpackPlugin = require("eslint-webpack-plugin")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin")
const TerserWebpackPlugin = require("terser-webpack-plugin")
const ImageMinimizerWebpackPlugin = require("image-minimizer-webpack-plugin")
const CopyWebpackPlugin = 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函数
let getStyleLoaders = function (pre) {
    return [
        isProduction ? MiniCssExtractPlugin.loader : "vue-style-loader", "css-loader", {
            //处理兼容性问题,配合package.json中的browserslist来指定兼容性做到什么程度
            loader: "postcss-loader",
            options: {
                postcssOptions: {
                    plugins: ["postcss-preset-env"]
                }
            }
        },
        pre &&{
            loader:pre,
            options:pre=="sass-loader"?{
                additionalData: `@use "@/styles/elementPlus/index.scss" as *;`,
            }:{}
        }
    ].filter(Boolean)
}
module.exports = {
    entry: "./src/main.js",
    output: {
        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].[contenthash:10].chunk.js",
        assetModuleFilename: "static/media/[hash:10][ext][query]",
        clean: true
    },
    module: {
        rules: [
            // 处理css
            {
                test: /\.css$/,
                use: getStyleLoaders(),
            },
            {
                test: /\.less$/,
                use: getStyleLoaders('less-loader'),
            },
            {
                test: /\.s[ac]ss$/,
                use: getStyleLoaders('sass-loader'),
            },
            {
                test: /\.styl$/,
                use: getStyleLoaders('stylus-loader'),
            },
            //处理图片
            {
                test: /\.(jpe?g|png|gif|webp|svg)$/,
                type: "asset",
                parser: {
                    dataCondition: {
                        maxSize: 10 * 1024, //小于10kb以下可以转为base64,减少请求数量
                    }
                }
            },
            // 处理其他资源
            {
                test: /\.(woff2?|ttf)$/,
                type: "asset/resource",
            },
            //处理js
            {
                test: /\.js$/,
                include: path.resolve(__dirname, '../src'),
                loader: "babel-loader",
                options: {
                    cacheDirectory: true,
                    cacheCompression: false,
                }
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader',
            }
        ]
    },
    plugins: [
        new EslintWebpackPlugin({
            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 CopyWebpackPlugin({//复制到dist文件下
            patterns: [
                {
                    from: path.resolve(__dirname, "../public"), to: "../dist", globOptions: {
                        ignore: ["**/index.html", "**/ignored-directory/**"],//忽略Index.html文件
                    },
                }
            ]
        }),
        new VueLoaderPlugin(),
        //cross-env定义的环境变量给webpack使用
        //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),
    mode: isProduction ? "production" : "development",
    devtool: isProduction ? "source-map" : "cheap-module-source-map",
    optimization: {
        splitChunks: {
            chunks: "all", //代码分割
            cacheGroups:{
                vue:{ // 一起打包成一个js文件
                    test:/[\\/]node_modules[\\/]vue(.*)?[\\/]/,
                    name:'chunk-vue',
                    priority:40, //打包优先级权重
                },
                elementPlus:{ //antd单独打包
                    test:/[\\/]node_modules[\\/]element-plus[\\/]/,
                    name:'chunk-elementPlus',
                    priority:30,
                },
                lib:{ //node_modules单独打包
                    test:/[\\/]node_modules[\\/]/,
                    name:'chunk-lib',
                    priority:20,
                },
            }
        },
        runtimeChunk: {
            name: entrypoint => `runtime~${entrypoint.name}.js` //单独储存引用的chunk的打包地址,main.js不会随着其他模块的变化导致地址变化而打包变化
        },
        minimize: isProduction,
        minimizer: [
            new CssMinimizerWebpackPlugin(),
            new TerserWebpackPlugin(),
            new ImageMinimizerWebpackPlugin({
                minimizer: {
                    implementation: ImageMinimizerWebpackPlugin.imageminGenerate,
                    options: {
                        plugins: [
                            ["gifsicle", { interlaced: true }],
                            ["jpegtran", { progressive: true }],
                            ["optipng", { optimizationLevel: 5 }],
                            [
                                "svgo",
                                {
                                    plugins: [
                                        "preset-default",
                                        "prefixIds",
                                        {
                                            name: "sortAttrs",
                                            params: {
                                                xmlnsOrder: "alphabetical",
                                            },
                                        },
                                    ],
                                },
                            ],
                        ],
                    },
                },
            }),
        ]
    },
    //webpack解析块加载选项
    resolve: {
        //自动补全文件拓展名
        extensions: [".vue", ".js", ".json"],
        alias:{
            "@":path.resolve(__dirname,"../src")
        }
    },
    devServer: {
        host: "localhost",
        port: 3000,
        open: true,
        hot: true,
        historyApiFallback: true//解决前端路由刷新404的问题
    },
    performance:false,
    cache: { //可开启webpack5内置缓存
        type: 'filesystem',
        allowCollectingMemory: true
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

每天一道算法练习题--Day21 第一章 --算法专题 --- ----------位运算

我这里总结了几道位运算的题目分享给大家&#xff0c;分别是 136 和 137&#xff0c; 260 和 645&#xff0c; 总共加起来四道题。 四道题全部都是位运算的套路&#xff0c;如果你想练习位运算的话&#xff0c;不要错过哦&#xff5e;&#xff5e; 前菜 开始之前我们先了解下…

【linux的学习与软件安装】

文章目录 linux的学习一、工具安装与联网&#xff1f;二、Linux软件安装1.安装jdk2.安装MySQL安装redis linux的学习 一、工具安装与联网&#xff1f; 1.1安装好VM后 进入vi /etc/sysconfig/network-scripts/ifcfg-ens33 然后ip addr 查看ip 1.2打开IDEA的tools 二、Linux软…

网络编程 | 多进程多线程并发服务器代码实现

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

5.5 Mybatis Update标签实战,返回值是什么? 教你通常处理做法

本文目录 前言一、update标签实战① 在UserMapper接口中新增update方法② MybatisX插件生成update标签③ 写update SQL 语句 二、update sql返回值是什么?三、Mybatis update标签返回值是什么?四、实现简易的修改密码API1. dal层2. service层3. web层自测通过 五、Git提交最后…

vue - 常见的移动端rem适配方案

移动端rem适配方案 rem适配原理方案1&#xff1a;rem媒体查询方案2&#xff1a;jsrem方案3&#xff1a;vwrem&#xff08;不用查询屏幕宽度&#xff09; 移动端适配经常使用的就是 rem; 主要有以下几种方案&#xff1a; 1&#xff1a;rem 媒体查询&#xff08;media&#xff0…

蓝桥杯最后一战

目录 分巧克力_二分 题目描述 输入格式 输出格式 输入输出样例 说明/提示 代码&#xff1a; 巧克力 - 优先队列 题目描述 输入格式 输出格式 输入输出样例 说明/提示 代码&#xff1a; 思路分析&#xff1a; 秘密行动_dp 蓝桥杯算法提高-秘密行动 题目描述 …

Unity之OpenXR+XR Interaction Toolkit 安装和配置

前言 XR Interaction Toolkit 是Unity基于OpenXR标准&#xff0c;发布的一套XR工具&#xff0c;目的是方便我们快速接入XR相关的SDK&#xff0c;并且做到兼容不同VR设备的目的&#xff0c;目前流行的VR设备如Oculus&#xff0c;Metal&#xff0c;HTC Vive&#xff0c;Pico等统…

改进YOLOv8 | 主干网络篇 | YOLOv8 更换骨干网络之 MobileNetV3 | 《搜寻 MobileNetV3》

论文地址:https://arxiv.org/abs/1905.02244 代码地址:https://github.com/xiaolai-sqlai/mobilenetv3 我们展示了基于互补搜索技术和新颖架构设计相结合的下一代 MobileNets。MobileNetV3通过结合硬件感知网络架构搜索(NAS)和 NetAdapt算法对移动设计如何协同工作,利用互…

【天秤座区块链】元宇宙知识普以及简单解读清华研究报告

本节目录 温馨提示关于分栏【天秤座区块链】由来提前感受元宇宙区块链的两个注意点区块链革命简单认识清华大学报告解读&#xff08;元宇宙&#xff09;前传《雪崩》元宇宙具体是什么&#xff1f;元宇宙不是什么&#xff1f;那为什么要冲击元宇宙呢&#xff1f; 小补充及感谢 温…

前端搭建打字通游戏(内附源码)

The sand accumulates to form a pagoda ✨ 写在前面✨ 打字通功能介绍✨ 页面搭建✨ 样式代码✨ 功能实现 ✨ 写在前面 上周我们实通过前端基础实现了名言生成器&#xff0c;当然很多伙伴再评论区提出了想法&#xff0c;后续我们会考虑实现的&#xff0c;今天还是继续按照我们…

java基础入门-06-【面向对象进阶(多态包final权限修饰符代码块)】

Java基础入门-06-【面向对象进阶&#xff08;多态&包&final&权限修饰符&代码块&#xff09;】 14、面向对象进阶&#xff08;多态&包&final&权限修饰符&代码块&#xff09;1.1 多态的形式1.2 多态的使用场景1.3 多态的定义和前提1.4 多态的运行…

嵌入式设备逆向所需的工具链

导语&#xff1a;本文介绍了嵌入式设备逆向所需的工具链。 相关的应用程序或工具有&#xff1a; UART(Universal Asynchronous Receiver Transmitter&#xff0c;通用异步收发器)&#xff1a; UBoot&#xff1b; Depthcharge&#xff1b; SPI (Serial Peripheral Interface…

利用文本描述替换万物(Inpaint-Anything-Description)

文章目录 引言安装Demo github&#xff1a; https://github.com/Atlas-wuu/Inpaint-Anything-Description 引言 前段时间看了万物分割SAM、文生图Stable Diffusion、开集检测Grounding DINO&#xff0c;它们之间可以互相补充&#xff0c;AIGC变得更加可控。Inpaint Anything将…

RK3568平台开发系列讲解(网络篇)Linux 的 socket 套接字

🚀返回专栏总目录 文章目录 一、套接字的数据结构1.1、struct socket 数据结构1.2、struct sock 数据结构二、套接字的初始化三、套接字与文件四、Socket Buffer沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 Linux 内核支持的套接字如下: 我们创建套接字时,可以…

PCIe物理层弹性缓存机制(详细)解析-PCIe专题知识(四)

目录 前言一、简介二、详细解析2.1 实例解析2.2 具体实现过程 三、总结四、其他相关链接1、PCI总线及发展历程总结2、PCIe物理层总结-PCIE专题知识&#xff08;一&#xff09;3、PCIe数据链路层图文总结-PCIe专题知识&#xff08;二&#xff09;4、PCIe物理层链路训练和初始化总…

国产ChatGPT命名图鉴

很久不见这般热闹的春天。 随着ChatGPT的威名席卷全球&#xff0c;大洋对岸的中国厂商也纷纷亮剑&#xff0c;各式本土大模型你方唱罢我登场&#xff0c;声势浩大的发布会排满日程表。 有趣的是&#xff0c;在这些大模型产品初入历史舞台之时&#xff0c;带给世人的第一印象其…

进程替换函数组介绍exec*

目录 前述 execl execlp execle execv execvp execvpe 前述 介绍后缀的意义&#xff1a; l &#xff08;list&#xff09;&#xff1a;表示参数采用列表。 v&#xff08;vector&#xff09;&#xff1a;参数同数组表示。 p&#xff08;path&#xff09;&#xff1a;自…

力扣题库刷题笔记704-二分查找

1、题目如下&#xff1a; 2、个人Python代码如下&#xff1a; 个人代码如下&#xff1a; class Solution: def search(self, nums: List[int], target: int) -> int: left 0 right len(nums) - 1 while left < right: mid (right left) >> 1 if nums[mid] >…

【C++类和对象之拷贝构造、赋值运算符重载】

拷贝构造、赋值运算符重载 ❀拷贝构造函数 特性 ❀赋值运算符重载 赋值运算符重载格式 &#x1f340;小结&#x1f340; &#x1f389;博客主页&#xff1a;小智_x0___0x_ &#x1f389;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f389;系列…

【数字图像处理】边缘检测

文章目录 0. 前言1. Sobel算子2. Canny算子3. 深度学习算法3.1 Holistically-Nested Edge Detection&#xff08;HED&#xff09;3.2 Richer Convolutional Features&#xff08;RCF&#xff09; 0. 前言 边缘检测是一种图像处理技术&#xff0c;旨在标识和定位数字图像中的边…