请问如何在webpack生产环境配置中引入基础 webpack 配置

基本情况

首先,我是想将 webpack 一个配置文件分成多个配置文件(基本配置 webpack.config.js、生产环境配置 webpack.prod.config.js 及开发环境配置 webpack.dev.config.js),但是我所遇到的问题是在分离出来的生产环境配置中,启动打包时,无法正确解析 loader,报错信息如下:

ERROR in ./src/index.js
Module not found: Error: Can't resolve './App' in 'D:\git\visual-todos\src'
 @ ./src/index.js 2:0-23 8:16-19 9:17-20

ERROR in ./src/router/index.js
Module not found: Error: Can't resolve '@/components/Layout' in 'D:\git\visual-todos\src\router'
 @ ./src/router/index.js 3:0-40 12:17-23
 @ ./src/index.js

在将生产环境配置放回基本配置中,即基本配置和生产环境配置在同一文件夹时就能正常解析并打包。

若在报错的代码行,手动添加后缀名 .vue,仍报错:

ERROR in ./src/router/index.js
Module not found: Error: Can't resolve '@/components/Layout.vue' in 'D:\git\visual-todos\src\router'
 @ ./src/router/index.js 3:0-44 12:17-23
 @ ./src/index.js

补充说明:

配置结构如下:

visual-todos
     ├──build
     |     ├── webpack.config.js
     |     ├── webpack.dev.config.js
     |     └── webpack.prod.config.js

生产环境代码如下

const webpack = require('webpack')
const path = require('path')
const baseWebpackConfig = require('./webpack.config')
const merge = require('webpack-merge')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const ExtractPlugin = require('extract-text-webpack-plugin')

function resolve (dir) {
  return path.join(__dirname, '..', dir)
}

const webpackConfig = merge(baseWebpackConfig, {
  entry: {
    app: resolve('src/index.js'),
    vendor: ['vue', 'vue-loader']
  },

  output: {
    filename: '[name].[chunkHash:8].js'
  },

  module: {
    rules: [
      {
        test: /\.scss$/,
        use: ExtractPlugin.extract({
          fallback: 'style-loader',
          use: [
            'css-loader',
            {
              loader: 'postcss-loader',
              options: {
                sourceMap: true
              }
            },
            'sass-loader'
          ]
        })
      }
    ]
  },

  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('production')

    }),
    new UglifyJsPlugin(),
    new ExtractPlugin('styles.[contentHash:8].css')
  ],

  optimization: {

    runtimeChunk: {
      name: 'runtime' 
    },
    
    splitChunks: { 
      cacheGroups: { 
        commons: { 
          chunks: 'initial', 
          minSize: 0,
          minChunks: 1
        },
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendor', 
          chunks: 'all'
        }
      }
    }
  }
})

基本配置

const path = require('path')
const HTMLPlugin = require('html-webpack-plugin')
const webpack = require('webpack')

const isDev = process.env.NODE_ENV === 'development'

function resolve (dir) {
  return path.join(__dirname, '..', dir)
}

const config = {
  target: 'web',
  context: path.resolve(__dirname, '../'), 
  entry: resolve('src/index.js'),
  output: {
    filename: 'bundle.[hash:8].js', 
    path: resolve('dist')
  },

  resolve: {
    extensions: ['.js', '.vue', '.jsx',  '.json'],
    alias: {
      'vue$': 'vue/dist/vue.runtime.esm.js',
      '@': resolve('src'),
    }
  },

  module: {
    rules: [
      {
        test: /\.vue$/,
        include: [resolve('src')],
        loader: 'vue-loader'
      },
      {
        test: /\.jsx$/,
        include: [resolve('src')],
        loader: 'babel-loader'
      },
      {
        test: /\.( gif|jpg|jpeg|png|svg )$/,
        use: [
          {  
            loader: 'url-loader', 
            options: {
              limit: 1024,  
              name: '[name].[ext]'
            }
          }
        ]
      },
      {
        test: /\.(png|woff|woff2|eot|ttf|svg)$/, 
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: '[name].[hash:8].[ext]'
        }
      }
    ]
  },

  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: isDev ? '"development"' : '"production"' 
      }
    }),
    new HTMLPlugin({
      filename: 'index.html', 
      template: 'index.html',
    })
  ],

  node: {
    fs: 'empty'
  }
}

if (isDev) {
  config.module.rules.push({
    test: /\.scss$/,
    include: [resolve('src')],
    
    use: [
      'style-loader',
      'css-loader',
      {
        loader: 'postcss-loader',
        options: {
          sourceMap: true,
          config: {
            path: './postcss.config.js'
          }
        }
      },
      'sass-loader'
    ]
  })

  config.devtool = '#cheap-module-eval-source-map' 

  config.devServer = {
    port: '8080', 
    host: '0.0.0.0',
    overlay: {  
      error: true,
    },
    hot: true 
  }

  config.plugins.push(
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin()
  )

}

module.exports = config

node script

"build": "cross-env NODE_ENV=production webpack --progress --config build/webpack.prod.config.js --mode production",
"start": "cross-env NODE_ENV=development webpack-dev-server --progress --config build/webpack.config.js --mode development"

思路

在基本配置中,我的思路是用 if 语句判断当前环境变量载入不同的配置。在没有分离出来前,生产环境配置是在 if 语句判断为 false 的代码块中。

因为放回基本配置能够正常载入模块并打包,而且生产环境配置和基本配置在同一目录下,就应该不是路径问题。

因为我是刚刚学习 webpack 的配置,不知道是我哪里配置错了,在分离出来的生产环境配置无法载入模块。请大佬帮帮忙!谢谢!

参考了分离配置的标准是webpack 文档webpack doc

阅读 2.7k
1 个回答

已解决,在生产环境中,最后模块没有输出 = _ = !!

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题