vue中webpack配置介绍

2017-10-10  本文已影响1041人  郝特么冷

在my-project项目中的build文件夹下我们看到了这四个文件:


image.png

下面我们一个一个剖析:

webpack.base.conf.js 主要对build目录下的webpack配置做详细分析

'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')

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

module.exports = {
    //入口
  entry: {
    app: './src/main.js'
  },
  //输出
  output: {
    path: config.build.assetsRoot,//导出目录的绝对路径
    filename: '[name].js',//导出文件的文件名
    publicPath: process.env.NODE_ENV === 'production'
      ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath//生产模式或开发模式下html、js等文件内部引用的公共路径
  },
  //文件解析
  resolve: {
    extensions: ['.js', '.vue', '.json'],//自动解析确定的拓展名,使导入模块时不带拓展名
    alias: {// 创建import或require的别名
//       'vue': 'vue/dist/vue.js',
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
    }
  },
  //模块解析
  module: {
    rules: [
      {
        test: /\.(js|vue)$/,//js和vue文件后缀
        loader: 'eslint-loader',//使用eslint-loader处理
        enforce: 'pre',//
        include: [resolve('src'), resolve('test')],//
        options: {
          formatter: require('eslint-friendly-formatter')
        }//对eslint-loader做的额外处理
      },
      {
        test: /\.vue$/,//vue文件后缀
        loader: 'vue-loader',//使用vue-loader处理
        options: vueLoaderConfig//对vueloader的一些额外处理
      },
      {
        test: /\.js$/,//js文件后缀
        loader: 'babel-loader',//使用babel-loader处理
        include: [resolve('src'), resolve('test')]//必须包含src和test文件夹
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,//图片后缀
        loader: 'url-loader',//使用url-loader处理
        options: { //对loader做的额外的选项配置
          limit: 10000,//图片小于10000字节,以base64方式引用
          name: utils.assetsPath('img/[name].[hash:7].[ext]')//文件名是name.7位hash值.拓展名
        }
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,//媒体文件
        loader: 'url-loader',//媒体文件使用url-loader来处理
        options: {//对loader做的额外的选项配置
          limit: 10000,//媒体文件小于10000字节,以base64方式引用
          name: utils.assetsPath('media/[name].[hash:7].[ext]')//文件名是name.7位hash值.拓展名
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,//字体文件
        loader: 'url-loader',//使用url-loader来处理
        options: {//对字体文件的loader做的额外的选项配置
          limit: 10000,//字体文件小于10000字节,以base64方式引用
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')//文件名是name.7位hash值.拓展名
        }
      }
    ]
  }
}
//注: 关于query 仅由于兼容性原因而存在。请使用 options 代替。

webpack.dev.conf.js 开发环境下的webpack配置,通过merge方法合并webpack.base.conf.js基础配置

'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')

// add hot-reload related code to entry chunks
Object.keys(baseWebpackConfig.entry).forEach(function (name) {
  baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
})

module.exports = merge(baseWebpackConfig, {
    //模块配置
  module: {
    //通过传入一些配置来获取rules配置,此处传入了sourceMap: false,表示不生成sourceMap
    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
  },
  // cheap-module-eval-source-map is faster for development
  devtool: '#cheap-module-eval-source-map',
  //插件配置
  plugins: [
    new webpack.DefinePlugin({// 编译时配置的全局变量
      'process.env': config.dev.env//当前环境为开发环境
    }),
    // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
    new webpack.HotModuleReplacementPlugin(),//热更新插件
    new webpack.NoEmitOnErrorsPlugin(),//不触发错误,即编译后运行的包正常运行
    // https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({//自动生成html文件,比如编译后文件的引入
      filename: 'index.html',//生成的文件名
      template: 'index.html',//模板
      inject: true
    }),
    new FriendlyErrorsPlugin()//友好的错误提示
  ]
})

webpack.prod.conf.js 生产环境下的webpack配置,通过merge方法合并webpack.base.conf.js基础配置

'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')

const env = process.env.NODE_ENV === 'testing'
  ? require('../config/test.env')
  : config.build.env

const webpackConfig = merge(baseWebpackConfig, {
    //module的处理,主要是针对css的处理
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true
    })
  },
  devtool: config.build.productionSourceMap ? '#source-map' : false,
  //输出文件
  output: {
    path: config.build.assetsRoot,//导出文件目录
    filename: utils.assetsPath('js/[name].[chunkhash].js'),//导出文件名
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')//非入口文件的文件名,而又需要被打包出来的文件命名配置,如按需加载的模块
  },
  //插件
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      'process.env': env//配置全局环境为生产环境
    }),
    // UglifyJs do not support ES6+, you can also use babel-minify for better treeshaking: https://github.com/babel/minify
    new webpack.optimize.UglifyJsPlugin({//js文件压缩插件
      compress: {//压缩配置
        warnings: false//不显示警告
      },
      sourceMap: true//生成sourceMap文件
    }),
    // extract css into its own file
    new ExtractTextPlugin({//将js中引入的CSS分离的插件
      filename: utils.assetsPath('css/[name].[contenthash].css')//分离出的CSS文件名
    }),
    // Compress extracted CSS. We are using this plugin so that possible
    // duplicated CSS from different components can be deduped.
    //压缩提取的CSS,并解决ExtractTextPlugin分离出的js重复的问题(多个文件引入同一CSS文件)
    new OptimizeCSSPlugin({
      cssProcessorOptions: {
        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文件的插件,引入CSS文件和js文件
    new HtmlWebpackPlugin({
      filename: process.env.NODE_ENV === 'testing'
        ? 'index.html'
        : config.build.index,//生成的HTML文件名
      template: 'index.html',//依据的模板
      inject: true,//注入的js文件将会被放在body标签中,当值为head时将会被放在head标签中
      minify: {//压缩配置
        removeComments: true,//删除HTML中的注释代码
        collapseWhitespace: true,//删除HTML中的空白字符
        removeAttributeQuotes: true//删除HTML元素中属性的引号
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'//按照dependency的顺序引入
    }),
    // keep module.id stable when vender modules does not change  保持模块。当vender模块没有改变时,id就稳定了
    new webpack.HashedModuleIdsPlugin(),
    // split vendor js into its own file  将供应商js分解为自己的文件
    //分离公共js到vendor中
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',//文件名
      minChunks: function (module) {//申明公共的模块来自node_modules中
        // any required modules inside node_modules are extracted to 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
    //将webpack运行时和模块清单提取到自己的文件中,以防止当应用程序包被更新时,供应商哈希被更新。
    //上面虽然已经分离了第三方库,每次修改编译都会改变vendor的hash值,导致浏览器缓存失效。
        //原因是vendor包含了webpack在打包过程中会产生一些运行时代码,运行时代码中实际上保存了打包后的文件名。
        //当修改业务代码时,业务代码的js文件的hash值必然会改变。一旦改变必然会导致vendor变化。vendor变化会导致其hash值变化。
    //下面主要是将运行时代码提取到单独的manifest文件中,防止其影响vendor.js
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      chunks: ['vendor']
    }),
    // copy custom static assets
     // 复制静态资源,将static文件内的内容复制到指定文件夹
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.build.assetsSubDirectory,
        ignore: ['.*']//忽略*文件
      }
    ])
  ]
})
//额外配置
if (config.build.productionGzip) {//配置文件开启了gzip压缩
    //引入压缩文件的组件,该插件会对生成的文件进行压缩,生成一个.gz文件
  const CompressionWebpackPlugin = require('compression-webpack-plugin')

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',//目标文件名
      algorithm: 'gzip',//使用gzip压缩
      test: new RegExp(//满足正则表达式的文件会被压缩
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      threshold: 10240,//资源文件大于10240B = 10KB大小才会被压缩
      minRatio: 0.8//最小压缩比达到0.8时才会被压缩
    })
  )
}

if (config.build.bundleAnalyzerReport) {
  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig

webpack.test.conf.js

'use strict'
// This is the webpack config used for unit tests.
//这是用于单元测试的webpack配置。
const utils = require('./utils')
const webpack = require('webpack')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')

const webpackConfig = merge(baseWebpackConfig, {
  // use inline sourcemap for karma-sourcemap-loader
//为karma-sourcemap加载器使用内联sourcemap
  module: {
    rules: utils.styleLoaders()
  },
  devtool: '#inline-source-map',
  resolveLoader: {
    alias: {
      // necessary to to make lang="scss" work in test when using vue-loader's ?inject option
      // see discussion at https://github.com/vuejs/vue-loader/issues/724
//  在使用vuloader的时候,需要使lang=“scss”在测试中工作吗?请参阅[https://github.com/vuejs/vue-loader/issues/724]的讨论注入选项
      'scss-loader': 'sass-loader'
    }
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': require('../config/test.env')
    })
  ]
})

// no need for app entry during tests
//在测试中不需要应用程序条目
delete webpackConfig.entry

module.exports = webpackConfig
上一篇 下一篇

猜你喜欢

热点阅读