DEV Community

Cover image for Webpack5 + vue3

Posted on

Webpack5 + vue3

Nevertheless you can create a simple vue app by

npm install --save-dev @vue/cli
vue create vue3-project

but it is too simple. Sometimes we need to be close to bare metal - then we need a custom build with our own webpack.config.js. Reasons you might need that:

  • you are a skilled webpack user
  • you have a proven webpack config from a previous project
  • you want to integrate with some third parties

Here a simple proven webpack.config.js which allows using Single File Components (SFC). Here is a project structure we are going to use:

Huge Vue project structure with single file components

Features included:

  • CSS modules
  • extract node_modules to a separate file (or chunk, or bundle)


const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const { VueLoaderPlugin } = require("vue-loader");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

const src  = path.resolve(__dirname, 'src');
const dist = path.resolve(__dirname, 'dist');

module.exports = (env, argv) => {
    const IS_PRODUCTION = argv.mode === 'production';

    const config = {
        entry: './src/index.js',
        output: {
            path: dist,
            filename: "[name]-[contenthash].js",

        resolve: {
            alias: {
                "@": src
        mode: argv.mode,
        devServer: {
            static: dist
        plugins: [
            new HtmlWebpackPlugin(),
            new VueLoaderPlugin(),
            new CleanWebpackPlugin(),
        module: {
            rules: [{
                test: /\.vue$/,
                loader: "vue-loader",
                exclude: /node_modules/
            }, {
                test: /\.css$/,
                use: [
                    IS_PRODUCTION ? MiniCssExtractPlugin.loader : "style-loader",
                        loader: "css-loader",
                        options: {
                            modules: {
                                localIdentName: "[local]--[hash:base64:6]",
            }, {
                test: /\.js$/,
                loader: "babel-loader",
                exclude: /node_modules/
            }, {
                test: /\.(png|jpe?g|gif|webm|mp4|svg)$/,
                loader: "file-loader",
                options: {
                    outputPath: "assets"
        optimization: {
            minimizer: [
                // extend default plugins
                // HTML and JS are minified by default if config.mode === production.
                // But for CSS we need to add this:
                new CssMinimizerPlugin()
            splitChunks: {
                cacheGroups: {
                    commons: {
                      test: /[\\/]node_modules[\\/]/,
                      name: 'node_modules',
                      chunks: 'all',

    if (IS_PRODUCTION) {
        // put all CSS files to a single <link rel="stylesheet" href="...">
        config.plugins.push(new MiniCssExtractPlugin({
            filename: "[contenthash].css"

    } else {
        // config.devtool = "inline-source-map";

    return config;
Enter fullscreen mode Exit fullscreen mode


  "scripts": {
    "start": "webpack serve --open --mode=development",
    "build": "webpack --mode=production --progress",
    "dist-clean": "rm -fr dist/*"
Enter fullscreen mode Exit fullscreen mode

Full project Thanks!

Top comments (1)

georgerocha profile image

I am a begginer in Vue js and thanks in advantage for your page.
Just an add for u.
In my case I needed to add -g in npm install --save-dev @vue/cli and the sentence be like this
npm install -g --save-dev @vue/cli