盘他webpack5 + vue

细数着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版本,编译也会报错
学习总是循序渐进的,是我太急躁不开心了半个月

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • 什么是Vue.js Vue.js是目前最火的一个前端框架,React是最流行的一个前端框架,(React除了开发网...
    EEEEsun阅读 567评论 0 1
  • webpack基础 什么是webpack?webpack是前端的一个项目构建工具,它是基于Node.js开发出来的...
    7ColorLotus阅读 186评论 0 2
  • 准备工作 首先创建一个空文件夹 利用npm init 初始化package.json 创建src文件夹index....
    livetoday阅读 603评论 0 0
  • 在网页中会引用哪些常见的静态资源? JS .js .jsx .coffee .ts(TypeScript ...
    xlystar阅读 271评论 0 0
  • webpack版本:4.8.3webpack-cli版本:2.1.31.全局安装webpack和webpack-c...
    苏打丶观阅读 6,070评论 1 4