从0开始搭建一个可用的vue3-webpack5-template(一)

2,000 阅读3分钟

前言

最近对知识点查漏补缺,发现对工程化这一块掌握的不太好,之前的项目又都是基于vue-cli搭建的,所以打算用webpack5手动搭建一套vue3的开发环境,话不多说,我们直接开始。(完整代码可在vue3-webpack5-templatetag0.0.1中查看)

v1乞丐版

我们先完成一个最简单的功能,然后再开始逐步的完善细节,首先先建立好一个基础的vue3模板项目,结构的话可以和vue-cli的结构保持一致,然后手动添加vue3必须的依赖包

yarn add vue/@next vue-router@4 vuex@next --save

webpack基础配置

添加webpack相关依赖

yarn add webpack webpack-cli @webpack-cli/serve webpack-dev-server -D

新建一个build/webpack.conf.js文件,存放我们的webpack配置。对比webpack4output新增了clean属性,不需要再引入webpack-clean-plugin

const { resolve } = require('./utils.js')
module.exports = {
    entry: {
        app: resolve('src/main.js')
    },
    output: {
        path: resolve('dist'),
        filename: 'js/[name].[chunkhash].js',
        publicPath: './',
        clean: true
    },
    resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: { '@': resolve('src') }
    },
    module: {},
    plugins: []
}

添加Babel支持

首先按照babel相关依赖

yarn add core-js --save
yarn add @babel/core @babel/eslint-parser @babel/preset-env babel-loader -D

新建babel.config.js文件,写入babel相关配置

module.exports = {
    presets: [
        '@babel/preset-env'
    ]
}

然后在webpack.conf.js中添加babel-loader,这里我根据个人习惯,只允许src文件夹下的js文件才会被babel转换,各位小伙伴们可以根据自己的实际情况自行调整

rules: [
            ...,
            {
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        cacheDirectory: true
                    }
                },
                include: [resolve('src')]
            }
  
        ]

添加Vue单文件支持

支持vue单文件除了需要引入vue-loader以外,还需要单独下载@vue/compiler-sfc

yarn add vue-loader @vue/compiler-sfc -D

webpack.conf.js文件中添加vue-loaderVueLoaderPlugin

const { VueLoaderPlugin } = require('vue-loader')
...
rules: [
            ...,
            {
                test: /\.vue$/,
                use: 'vue-loader'
            },
  
        ],
plugins: [new VueLoaderPlugin(), ...]

添加scss/postcss支持

还是按照惯例,添加相关依赖,这里我们使用dart-sass

yarn add dart-sass  sass sass-loader style-loader css-loader postcss-loader autoprefixer

rules中添加对应的规则

rules: [
            ...,
            {
                test: /\.(css|scss|sass)$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'postcss-loader',
                    {
                        loader: 'sass-loader',
                        options: { implementation: require('dart-sass') }
                    }
                ]
            }
        ]

添加文件模块支持

webpack5中,webpack5对于文件资源模块进行了统一管理,不再需要单独指定url-loader,file-loader,而是提供了一个type属性来代替,我们先直接看配置,然后再解释相关的含义

rules: [
    ...,
    {
                test: /\.(eot|svg|ttf|woff|)$/,
                type: 'asset/resource',
                generator: {
                    filename: 'fonts/[name].[hash:8][ext]'
                }
            },
            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                type: 'asset',
                generator: {
                    // [ext]前面自带"."
                    filename: 'assets/[name].[hash:8][ext]'
                },
                parser: {
                    dataUrlCondition: {
                        maxSize: 4 * 1024 // 4kb
                    }
                }
            }
]

资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换之前的loader:

  • asset/resource 发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现。
  • asset/inline 导出一个资源的 data URI。之前通过使用 url-loader 实现。
  • asset/source 导出资源的源代码。之前通过使用 raw-loader 实现。
  • asset 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader,并且配置资源体积限制实现。

devserver/HtmlWebpackPlugin

这两个也是经常需要用到的,就不再详细介绍了,下面贴上相关配置代码

yarn add html-webpack-plugin

配置里面有几点需要注意下,devserver的配置项相对于webpack4有一些改动,比如日志相关都移到了client对象中。关于HMR,如果在命令行中使用了 --hot,那么可以不引入webpack.HotModuleReplacementPlugin,其他的变化不大

devServer: {
        // http://[devServer.host]:[devServer.port]/[output.publicPath]/[output.filename] 进行访问
        historyApiFallback: true,
        hot: true,
        client: {
            overlay: false,
            logging: 'none',
            progress: true
        },
        compress: true,
        host: 'localhost',
        port: '8080'
    },
 plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: resolve('public/index.html'),
            title: 'vue3-webpack-title'
        }),
        new VueLoaderPlugin()
    ]

添加脚本

在package.json文件中,添加如下两条脚本

  "scripts": {
    "dev": "webpack serve --config ./build/webpack.base.conf.js --color",
    "build": "webpack --config ./build/webpack.base.conf.js --color"
  }

总结

至此我们已经完成了如下功能