美文网首页
盘他webpack5 + vue

盘他webpack5 + vue

作者: eks | 来源:发表于2020-10-24 16:59 被阅读0次

    细数着2020年,从疫情开始就没好事发生过,作为一个半专业的前端bug工程师看着vue3发布了,webpack5发布了,react17发布了,除了react17这一两月都在可劲的盘,今天来聊一聊盘webpack5的血泪史!

    开始之前自个儿准备好node>=10,(c)npm,当然你要用yarn也可以,我这里用不了npm,用的是cnpmv6.1.1nodev12.18.4,不信你就看下面的截图:

    version.png

    一、首先创建文件夹webpack5,并初始化项目 cnpm init -y,得到package.json

    二、安装依赖

    1. webpack相关
    cnpm i -D webpack webpack-cli webpack-dev-server
    

    安装好了webpack是如下这样的


    package.png
    1. 其他依赖
    cnpm i -D cross-env babel-loader html-webpack-plugin mini-css-extract-plugin clean-webpack-plugin style-loader css-loader vue-style-loader html-loader @babel/core
    

    三、安装vue相关

    cnpm i -S vue vue-router
    cnpm i -D vue-template-compiler vue-loader
    

    注意 vue和vue-template-compiler版本号一定要一样

    vue.png

    四、在webpack5目录下webpack.config.js

    1. 编辑config
    const { resolve, join } = require('path');
    const webpack = require('webpack');
    const HtmlWebpackPlugin = require('html-webpack-plugin'); // 自动生成index.html
    const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 文本分离插件,分离js和css
    const { CleanWebpackPlugin } = require('clean-webpack-plugin'); // 清理垃圾文件
    
    const { VueLoaderPlugin } = require('vue-loader'); // vue加载器
    const port = 3002;
    const isProd = process.env.NODE_ENV === 'production';
    
    const cssConfig = [
        isProd ? MiniCssExtractPlugin.loader : 'vue-style-loader',
        {
            loader: 'css-loader',
            options: {
                sourceMap: !isProd
            }
        }
    ];
    
    const config = {
        entry: {
            index: './src/index.js' // 入口文件
        },
        output: {
            path: resolve(__dirname, 'dist'),
            filename: isProd ? 'javascript/[name].[contenthash:5].js' : '[name].js', // [name] 是entry的key
            publicPath: isProd ? './' : '/'
        },
        module: {
            rules: [
                {
                    test: /\.css$/i,
                    use: cssConfig
                },
                {
                    test: /\.vue$/,
                    use: [
                        {
                            loader: 'vue-loader',
                            options: {
                                loaders: {
                                    css: cssConfig
                                },
                                preserveWhitespace: false // 不要留空白
                            }
                        }
                    ],
                    include: [resolve(__dirname, 'src')]
                },
                {
                    test: /\.js$/,
                    use: [
                        {
                            loader: 'babel-loader',
                            options: {
                                cacheDirectory: !isProd
                            }
                        }
                    ],
                    exclude: /node_modules/,
                },
                {
                    test: /\.html$/,
                    use: [{
                        loader: 'html-loader',
                        options: { // 配置html中图片编译
                            minimize: true,
                            attributes: false
                        }
                    }]
                }
            ]
        },
        resolve: { // 配置路径别名
            extensions: ['.js', '.vue', '.styl'] // import引入文件的时候不用加后缀
        },
        plugins: [
            new VueLoaderPlugin(), // vue加载器
            new HtmlWebpackPlugin({
                template: join(__dirname, 'src/index.html'), // 引入模版
                filename: 'index.html',
                minify: { // 对index.html压缩
                    collapseWhitespace: isProd, // 去掉index.html的空格
                    removeAttributeQuotes: isProd // 去掉引号
                },
                hash: true, // 去掉上次浏览器的缓存(使浏览器每次获取到的是最新的html)
                inlineSource: '.(js|css)'
            }),
            new MiniCssExtractPlugin({ // 分离css
                filename: 'stylesheets/[name].[contenthash:5].css'
            })
        ]
    };
    
    if (isProd) {
        config.plugins.push(
            new CleanWebpackPlugin({
                verbose: true, // 打印被删除的文件
                protectWebpackAssets: false, // 允许删除cleanOnceBeforeBuildPatterns中的文件
                cleanOnceBeforeBuildPatterns: ['**/*', resolve(__dirname, 'dist')]
            }),
            new MiniCssExtractPlugin({ // 分离css
                filename: 'stylesheets/[name].[contenthash:5].css'
            })
        );
        config.optimization = { // 抽离第三方插件
            minimize: true,
            splitChunks: {
                chunks: 'all', // 必须三选一: "initial" | "all" | "async"(默认就是异步)
                minChunks: 3, // 共享最少的chunk数,使用次数超过这个值才会被提取
                maxAsyncRequests: 5, // 最多的异步chunk数
                maxInitialRequests: 5, // 最多的同步chunks数
                cacheGroups: { // 这里开始设置缓存的 chunks
                    vendor: { // key 为entry中定义的 入口名称,new webpack.ProvidePlugin中的库
                        test: /node_modules/, // 正则规则验证,如果符合就提取 chunk (指定是node_modules下的第三方包)
                        // test: /[\\/]node_modules[\\/](vue|vue-router|vuex)[\\/]/, // 正则规则验证,如果符合就提取 chunk (指定是node_modules下的第三方包)
                        name: 'vendor', // 要缓存的 分隔出来的 chunk 名称
                        enforce: true,
                    },
                    main: {
                        test: /src/,
                        name: 'main',
                        enforce: true,
                    }
                }
            },
            runtimeChunk: { name: 'runtime' } // 为每个入口提取出webpack runtime模块
        };
    } else {
        config.plugins.push(
            new webpack.HotModuleReplacementPlugin(),
        );
        config.devtool = 'eval-source-map'; // 如果只用source-map开发环境出现错误定位源文件,生产环境会生成map文件
        config.devServer = {
            contentBase: join(__dirname, 'dist'), // 将 dist 目录下的文件,作为可访问文件。
            compress: true, // 开启Gzip压缩
            host: 'localhost', // 设置服务器的ip地址,默认localhost
            port, // 端口号
            open: true, // 自动打开浏览器
            hot: true,
            noInfo: true,
            overlay: { // 当出现编译器错误或警告时,就在网页上显示一层黑色的背景层和错误信息
                errors: true
            },
            disableHostCheck: true //  不检查主机
        };
    }
    
    module.exports = config;
    
    1. 编辑package.json
      在package.json的scripts处添加
        "dev": "cross-env NODE_ENV=development webpack-dev-server --mode development",
        "prod": "cross-env NODE_ENV=production webpack --mode production"
    

    五、在webpack5目录下新建src目录,在src下新建index.html、index.js、router.js、App.vue、Demo.vue,编写相关代码

    1.index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>webpack5</title>
    </head>
    <body>
    <div id="app"></div>
    </body>
    </html>
    
    1. index.js
    import Vue from 'vue';
    import router from './router';
    import App from './App';
    const isProd = process.env.NODE_ENV === 'production';
    Vue.config.productionTip = isProd;
    
    new Vue({
        router,
        render: (h) => h(App)
    }).$mount('#app');
    
    
    1. router.js
    import Vue from 'vue';
    import VueRouter from 'vue-router';
    import Demo from './Demo';
    Vue.use(VueRouter);
    export default new VueRouter({
        routes: [
            {
                path: '/demo',
                name: 'Demo',
                component: Demo,
                meta: {
                    title: 'Demo'
                }
            }
        ]
    });
    
    
    1. App.vue
    <template>
        <div>
        <div class="app">APP</div>
        <router-link to="/demo">to demo page</router-link>
        <router-view/>
        </div>
    </template>
    
    <script>
    export default {
        name: "App"
    }
    </script>
    
    <style scoped>
    .app {
        font-size: 14px;
        color: aquamarine;
    }
    </style>
    
    
    1. Demo.vue
    <template>
        <div class="demo">Demo</div>
    </template>
    
    <script>
    export default {
        name: "Demo"
    }
    </script>
    
    <style scoped>
    .demo {
        font-size: 16px;
        color: blueviolet;
    }
    </style>
    

    六、试运行
    启动项目cnpm run dev

    rundev.png

    报错信息 Error: Cannot find module 'webpack-cli/bin/config-yargs'
    大概猜测意思是找不到webpack-cli下的某个模块
    在没升级到webpack5之前并没有这样的报错,这个问题使我 这半个月以来都不开心
    于是我翻开以前的代码查找官方文档反复研究也没有答案,甚至翻遍全中国网都没有给我答案,欲哭无泪
    于是我放弃了使用wbpack5
    我想 官方的意思是,反正我是发布了,用不用随你
    半个月后,wbpack5已经更新到了5.2.0,我重新入坑,既然webpack-cli@4版本没有config-yargs模块,那我用3.x版本可否?
    于是我重新安装 cnpm i -D webpack-cli@3
    重新启动——成功!

    七、总结
    由此可以看出,不是所有的新东西都是好东西,总要踩许多坑,就如我在使用webpack4的时候,升级了css-loader@4版本,编译也会报错
    学习总是循序渐进的,是我太急躁不开心了半个月

    相关文章

      网友评论

          本文标题:盘他webpack5 + vue

          本文链接:https://www.haomeiwen.com/subject/ltzimktx.html