vue-cli 项目 webpack.prod.conf.js 文件代码注释

本文详细介绍了生产环境下的Webpack配置,包括loader配置、插件使用、优化策略等,旨在帮助开发者理解并掌握如何构建高效、稳定的生产环境打包流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

// 生产模式配置文件 webpack.prod.conf.js
// 注释参考 https://www.cnblogs.com/ye-hcj/p/7082620.html 和 https://yq.aliyun.com/articles/609824 和 https://segmentfault.com/a/1190000012472099

'use strict'
// 下面是引入nodejs的路径模块
const path = require('path')
// 下面是utils工具配置文件,主要用来处理css类文件的loader
const utils = require('./utils')
// 下面引入webpack,来使用webpack内置插件
const webpack = require('webpack')
// 下面是config目录下的index.js配置文件,主要用来定义了生产和开发环境的相关基础配置
const config = require('../config')
// 下面是webpack的merger插件,主要用来处理配置对象合并的,可以将一个大的配置对象拆分成几个小的,合并,相同的项将覆盖
const merge = require('webpack-merge')
// 引入开发环境和生产环境公共的配置
const baseWebpackConfig = require('./webpack.base.conf')
// 引入copy-webpack-plugin模块 这个模块主要用于在webpack中拷贝文件和文件夹
const CopyWebpackPlugin = require('copy-webpack-plugin')
// 引入html-webpack-plugin插件 这个插件主要是用于基于模版生成html文件的
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 引入extract-text-webpack-plugin插件 这个插件主要是用于将入口中所有的chunk,移到独立的分离的css文件中
const ExtractTextPlugin = require('extract-text-webpack-plugin')
// 引入optimize-css-assets-webpack-plugin插件 这个插件主要是用于压缩css模块的
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
// 引入uglifyjs-webpack-plugin插件 这个插件主要是用于压缩js文件的
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

// 引入用于生产环境的一些基本变量
const env = require('../config/prod.env')

// 合并公共配置和生产环境独有的配置并返回一个用于生产环境的webpack配置文件
const webpackConfig = merge(baseWebpackConfig, {
  // 用于生产环境的一些loader配置
  module: {
    // 样式文件的处理规则,对css/sass/scss等不同内容使用相应的styleLoaders
    // 由utils配置出各种类型的预处理语言所需要使用的loader,例如sass需要使用sass-loader
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      // 在生产环境中使用extract选项,这样就会把thunk中的css代码抽离到一份独立的css文件中去
      extract: true,
      usePostCSS: true
    })
  },
  // 配置生产环境中使用的source map的形式。在这里,生产环境使用的是#source map的形式
  devtool: config.build.productionSourceMap ? config.build.devtool : false,
  output: {
    // build所产生的文件的存放的文件夹地址
    path: config.build.assetsRoot,
    // build之后的文件的名称
    // 这里[name]和[chunkhash]都是占位符
    // 其中[name]指的就是模块的名称
    // [chunkhash]chunk内容的hash字符串,长度为20
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    // [id]也是一个占位符,表示的是模块标识符(module identifier)
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    // 下面是利用DefinePlugin插件,定义process.env环境变量为env
    new webpack.DefinePlugin({
      'process.env': env
    }),
    // 压缩javascript的插件
    new UglifyJsPlugin({
      uglifyOptions: {
        compress: {
          // 在删除未使用的变量等时,显示警告信息,默认就是false
          warnings: false // 禁止显示压缩时候的警告信息
        }
      },
      // 使用 source map 将错误信息的位置映射到模块(这会减慢编译的速度)
      // 而且这里不能使用cheap-source-map
      sourceMap: config.build.productionSourceMap,
      // 使用多进程并行运行和文件缓存来提高构建速度
      parallel: true
    }),
    // extract css into its own file
    // 提取css文件到一个独立的文件中去
    new ExtractTextPlugin({
      // 提取之后css文件存放的地方
      // 其中[name]和[contenthash]都是占位符
      // [name]就是指模块的名称
      // [contenthash]根据提取文件的内容生成的 hash
      filename: utils.assetsPath('css/[name].[contenthash].css'),
      // 从所有额外的 chunk(additional chunk) 提取css内容
      // (默认情况下,它仅从初始chunk(initial chunk) 中提取)
      // 当使用 CommonsChunkPlugin 并且在公共 chunk 中有提取的 chunk(来自ExtractTextPlugin.extract)时
      // 这个选项需要设置为true
    }),
    // Compress extracted CSS. We are using this plugin so that possible
    // duplicated CSS from different components can be deduped.
    // 使用这个插件压缩css,主要是因为,对于不同组件中相同的css可以剔除一部分
    new OptimizeCSSPlugin({
      // 这个选项的所有配置都会传递给cssProcessor
      // cssProcessor使用这些选项决定压缩的行为
      cssProcessorOptions: config.build.productionSourceMap
        // safe我不是很明白是什么意思???求留言告知。。。
        ? { safe: true, map: { inline: false } }
        : { safe: true }
    }),
    // generate dist index.html with correct asset hash for caching.
    // you can customize output by editing /index.html
    // see https://github.com/ampedandwired/html-webpack-plugin
    // 创建一个html文件
    new HtmlWebpackPlugin({
      // 生成的文件的名称
      filename: config.build.index,
      // 使用的模板的名称
      template: 'index.html',
      // 把script和link标签放在body底部
      inject: true,
      // 配置html的压缩行为
      minify: {
        removeComments: true, // 移除注释
        collapseWhitespace: true, // 去除空格和换行
        removeAttributeQuotes: true // 尽可能移除属性中的引号和空属性
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      // 控制chunks的顺序,这里表示按照依赖关系进行排序
      // 也可以是一个函数,自己定义排序规则
      chunksSortMode: 'dependency'
    }),
    // keep module.id stable when vendor modules does not change
    // 根据模块的相对路径生成一个四位数的hash作为模块id
    new webpack.HashedModuleIdsPlugin(),
    // enable scope hoisting
    // webpack2处理过的每一个模块都会使用一个函数进行包裹
    // 这样会带来一个问题:降低浏览器中JS执行效率,这主要是闭包函数降低了JS引擎解析速度。
    // webpack3中,通过下面这个插件就能够将一些有联系的模块,
    // 放到一个闭包函数里面去,通过减少闭包函数数量从而加快JS的执行速度。
    new webpack.optimize.ModuleConcatenationPlugin(),
    // split vendor js into its own file
    // 这个插件用于提取多入口chunk的公共模块
    // 通过将公共模块提取出来之后,最终合成的文件能够在最开始的时候加载一次
    // 然后缓存起来供后续使用,这会带来速度上的提升。
    new webpack.optimize.CommonsChunkPlugin({
      // 这是 common chunk 的名称
      name: 'vendor',
      minChunks (module) {
        // any required modules inside node_modules are extracted to vendor
        // 把所有从mnode_modules中引入的文件提取到vendor中
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        )
      }
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    // 为了将项目中的第三方依赖代码抽离出来,官方文档上推荐使用这个插件,当我们在项目里实际使用之后,
    // 发现一旦更改了 app.js 内的代码,vendor.js 的 hash 也会改变,那么下次上线时,
    // 用户仍然需要重新下载 vendor.js 与 app.js——这样就失去了缓存的意义了。所以第二次new就是解决这个问题的
    // 参考:https://github.com/DDFE/DDFE-blog/issues/10
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      minChunks: Infinity
    }),
    // This instance extracts shared chunks from code splitted chunks and bundles them
    // in a separate chunk, similar to the vendor chunk
    // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
    new webpack.optimize.CommonsChunkPlugin({
      name: 'app',
      async: 'vendor-async',
      children: true,
      minChunks: 3
    }),

    // copy custom static assets
    // 拷贝静态资源到build文件夹中
    new CopyWebpackPlugin([
      {
        // 定义要拷贝的资源的源目录
        from: path.resolve(__dirname, '../static'),
        // 定义要拷贝的资源的目标目录
        to: config.build.assetsSubDirectory,
        // 忽略拷贝指定的文件,可以使用模糊匹配
        ignore: ['.*']
      }
    ])
  ]
})

if (config.build.productionGzip) {
  // 如果开启了生产环境的gzip
  const CompressionWebpackPlugin = require('compression-webpack-plugin')

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      // 目标资源的名称
      // [path]会被替换成原资源路径
      // [query]会被替换成原查询字符串
      asset: '[path].gz[query]',
      // gzip算法
      // 这个选项可以配置成zlib模块中的各个算法
      // 也可以是(buffer, cb) => cb(buffer)
      algorithm: 'gzip',
      // 处理所有匹配此正则表达式的资源
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      // 只处理比这个值大的资源
      threshold: 10240,
      // 只有压缩率比这个值小的资源才会被处理
      minRatio: 0.8
    })
  )
}

// 如果启动了report,则通过插件给出webpack构建打包后的产品文件分析报告
if (config.build.bundleAnalyzerReport) {
  // 如果需要生成一分bundle报告,则需要使用下面的这个插件
  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值