Search code examples
node.jsnpmwebpackvue.jswebpack-2

Creating a webpack.config with two configurations but with the same plugins


I am working on a vue.js based project, where I will have a SPA for the admin dashboard and an another SPA on the public side. I want to handle the projects separately, but build them in the same time. (or it would be nice to have something like: run build --public OR --admin (to specify which one to build))

I created a config array, and with this setup it creates the output but for some reason it doesn't minifies. With a single configuration it did.

I tried to put the plugins to the configs separately like plugins: [ .. ] but no success.

webpack.config.js:

var path = require('path') var webpack = require('webpack')

module.exports = [
    {
        entry: {
            public : './resources/js/public-spa/main.js',
        },
        output: {
            path: path.resolve(__dirname, './public/public-spa/dist/'),
            filename: '[name].build.js',
            chunkFilename: "public.[name].chunk.js"
        },
        module: {
            rules: [
                {
                    test: /\.vue$/,
                    loader: 'vue-loader',
                    options: {
                        loaders: {
                            'scss': 'vue-style-loader!css-loader!sass-loader',
                            'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
                        }
                    }
                },
                {
                    test: /\.js$/,
                    loader: 'babel-loader',
                    exclude: /node_modules/
                },
                {
                    test: /\.(png|jpg|gif|svg)$/,
                    loader: 'file-loader',
                    options: {
                        name: '[name].[ext]?[hash]'
                    }
                }
            ]
        },
        resolve: {
            alias: {
                'vue$': 'vue/dist/vue.esm.js'
            }
        },
        devServer: {
            historyApiFallback: true,
            noInfo: true
        },
        performance: {
            hints: false
        },
        devtool: '#eval-source-map'
    },
    {
        entry: {
            public : './resources/js/admin-spa/main.js',
        },
        output: {
            path: path.resolve(__dirname, './public/admin-spa/dist/'),
            filename: '[name].build.js',
            chunkFilename: "admin.[name].chunk.js"
        },
        module: {
            rules: [
                {
                    test: /\.vue$/,
                    loader: 'vue-loader',
                    options: {
                        loaders: {
                            'scss': 'vue-style-loader!css-loader!sass-loader',
                            'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
                        }
                    }
                },
                {
                    test: /\.js$/,
                    loader: 'babel-loader',
                    exclude: /node_modules/
                },
                {
                    test: /\.(png|jpg|gif|svg)$/,
                    loader: 'file-loader',
                    options: {
                        name: '[name].[ext]?[hash]'
                    }
                }
            ]
        },
        resolve: {
            alias: {
                'vue$': 'vue/dist/vue.esm.js'
            }
        },
        devServer: {
            historyApiFallback: true,
            noInfo: true
        },
        performance: {
            hints: false
        },
        devtool: '#eval-source-map'
    }
];

if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'
  // http://vue-loader.vuejs.org/en/workflow/production.html
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
        sourceMap: false,
        compress: {
            warnings: false,
        },
        output: {
            comments: false,
        },
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    }),
    new webpack.optimize.AggressiveMergingPlugin()
  ])
}

Solution

  • Your module.exports is an array of configs. Setting any properties on the array doesn't do anything, because webpack will receive each individual config and does not look for any properties on the array.

    You need to loop over the configs and change each config.

    if (process.env.NODE_ENV === 'production') {
      for (const config of module.exports) {
        config.devtool = '#source-map'
        // http://vue-loader.vuejs.org/en/workflow/production.html
        config.plugins = (config.plugins || []).concat([
          new webpack.DefinePlugin({
            'process.env': {
              NODE_ENV: '"production"'
            }
          }),
          new webpack.optimize.UglifyJsPlugin({
            sourceMap: false,
            compress: {
              warnings: false,
            },
            output: {
              comments: false,
            },
          }),
          new webpack.LoaderOptionsPlugin({
            minimize: true
          }),
          new webpack.optimize.AggressiveMergingPlugin()
        ])
      }
    }