经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » webpack » 查看文章
vue-cli webpack配置文件分析
来源:jb51  时间:2019/5/20 10:49:00  对本文有异议

相信vue使用者对vue-cli都不会陌生,甚至可以说,很熟悉了,但对其webpack的配置可能知之甚少吧。

过完年回来后,我接手了公司的新项目。新项目是一个spa。很自然,我就想到了vue-cli脚手架了,当时研究一下它的webpack配置。于是,就有了其他的内容。

今天这篇文章,是在原来的基础上,增加了一些新版本的内容,但实质上变化不大。

说明

此仓库为vue-cli webpack的配置分析,其实只是在源码中加上注释而已。大家查看详细分析,可以从后面提到的入口文件开始查看。

分析不包括check-versions.js文件,因为check-versions.js是检测npm和node版本,不涉及webpack,所以就没有对check-versions.js进行分析。同时,也不包括测试部分的代码,该分析只是针对开发和生产环境的webpack配置进行分析。

vue-cli 版本

2.8.1

入口

从package.json可以看到开发和生产环境的入口。

  1. "scripts": {
  2. "dev": "node build/dev-server.js",
  3. "build": "node build/build.js"
  4. }

开发环境

开发环境的入口文件是 build/dev-server.js

dev-server.js

该文件中,使用express作为后端框架,结合一些关于webpack的中间件,搭建了一个开发环境。

  1. // 配置文件
  2. var config = require('../config')
  3. // 如果 Node 的环境无法判断当前是 dev / product 环境
  4. // 使用 config.dev.env.NODE_ENV 作为当前的环境
  5. if (!process.env.NODE_ENV) {
  6. process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
  7. }
  8.  
  9. // 可以强制打开浏览器并跳转到指定 url 的插件
  10. // https://github.com/sindresorhus/opn
  11. var opn = require('opn')
  12. // node自带的文件路径工具
  13. var path = require('path')
  14. // express框架
  15. var express = require('express')
  16. var webpack = require('webpack')
  17. // 测试环境,使用的配置与生产环境的配置一样
  18. // 非测试环境,即为开发环境,因为此文件只有测试环境和开发环境使用
  19. var proxyMiddleware = require('http-proxy-middleware')
  20. var webpackConfig = process.env.NODE_ENV === 'testing'
  21. // 生产环境配置文件
  22. ? require('./webpack.prod.conf')
  23. // 开发环境配置文件
  24. : require('./webpack.dev.conf')
  25.  
  26. // 端口号为命令行输入的PORT参数或者配置文件中的默认值
  27. var port = process.env.PORT || config.dev.port
  28. // 配置文件中 是否自动打开浏览器
  29. var autoOpenBrowser = !!config.dev.autoOpenBrowser
  30. // 配置文件中 http代理配置
  31. // https://github.com/chimurai/http-proxy-middleware
  32. var proxyTable = config.dev.proxyTable
  33.  
  34. // 启动 express 服务
  35. var app = express()
  36. // 启动 webpack 编译
  37. var compiler = webpack(webpackConfig)
  38.  
  39. // 可以将编译后的文件暂存到内存中的插件
  40. // https://github.com/webpack/webpack-dev-middleware
  41. var devMiddleware = require('webpack-dev-middleware')(compiler, {
  42. // 公共路径,与webpack的publicPath一样
  43. publicPath: webpackConfig.output.publicPath,
  44. // 不打印
  45. quiet: true
  46. })
  47.  
  48. // Hot-reload 热重载插件
  49. // https://github.com/glenjamin/webpack-hot-middleware
  50. var hotMiddleware = require('webpack-hot-middleware')(compiler, {
  51. log: () => {}
  52. })
  53. // 当tml-webpack-plugin template更改之后,强制刷新浏览器
  54. compiler.plugin('compilation', function (compilation) {
  55. compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
  56. hotMiddleware.publish({ action: 'reload' })
  57. cb()
  58. })
  59. })
  60.  
  61. // 将 proxyTable 中的请求配置挂在到启动的 express 服务上
  62. Object.keys(proxyTable).forEach(function (context) {
  63. var options = proxyTable[context]
  64. // 如果options的数据类型为string,则表示只设置了url,
  65. // 所以需要将url设置为对象中的 target的值
  66. if (typeof options === 'string') {
  67. options = { target: options }
  68. }
  69. app.use(proxyMiddleware(options.filter || context, options))
  70. })
  71.  
  72. // 使用 connect-history-api-fallback 匹配资源
  73. // 如果不匹配就可以重定向到指定地址
  74. // https://github.com/bripkens/connect-history-api-fallback
  75. app.use(require('connect-history-api-fallback')())
  76.  
  77. // 将暂存到内存中的 webpack 编译后的文件挂在到 express 服务上
  78. app.use(devMiddleware)
  79.  
  80. // 将 Hot-reload 挂在到 express 服务上
  81. app.use(hotMiddleware)
  82.  
  83. // 拼接 static 文件夹的静态资源路径
  84. var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
  85. // 静态文件服务
  86. app.use(staticPath, express.static('./static'))
  87.  
  88. var uri = 'http://localhost:' + port
  89.  
  90. // 编译成功后打印网址信息
  91. devMiddleware.waitUntilValid(function () {
  92. console.log('> Listening at ' + uri + '\n')
  93. })
  94.  
  95. module.exports = app.listen(port, function (err) {
  96. if (err) {
  97. console.log(err)
  98. return
  99. }
  100.  
  101. // 如果配置了自动打开浏览器,且不是测试环境,则自动打开浏览器并跳到我们的开发地址
  102. if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
  103. opn(uri)
  104. }
  105. })
  106.  

webpack.dev.conf.js

dev-server.js中使用了webpack.dev.conf.js文件,该文件是开发环境中webpack的配置入口。

  1. // 工具函数集合
  2. var utils = require('./utils')
  3. var webpack = require('webpack')
  4. // 配置文件
  5. var config = require('../config')
  6. // webpack 配置合并插件
  7. var merge = require('webpack-merge')
  8. // webpac基本配置
  9. var baseWebpackConfig = require('./webpack.base.conf')
  10. // 自动生成 html 并且注入到 .html 文件中的插件
  11. // https://github.com/ampedandwired/html-webpack-plugin
  12. var HtmlWebpackPlugin = require('html-webpack-plugin')
  13. // webpack错误信息提示插件
  14. // https://github.com/geowarin/friendly-errors-webpack-plugin
  15. var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
  16.  
  17. // 将 Hol-reload 热重载的客户端代码添加到 webpack.base.conf 的 对应 entry 中,一起打包
  18. Object.keys(baseWebpackConfig.entry).forEach(function(name) {
  19. baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
  20. })
  21.  
  22. module.exports = merge(baseWebpackConfig, {
  23. module: {
  24. // styleLoaders
  25. rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
  26. },
  27. // 最新的配置为 cheap-module-eval-source-map,虽然 cheap-module-eval-source-map更快,但它的定位不准确
  28. // 所以,换成 eval-source-map
  29. devtool: '#eval-source-map',
  30. plugins: [
  31. // definePlugin 接收字符串插入到代码当中, 所以你需要的话可以写上 JS 的字符串
  32. // 此处,插入适当的环境
  33. // https://webpack.js.org/plugins/define-plugin/
  34. new webpack.DefinePlugin({
  35. 'process.env': config.dev.env
  36. }),
  37. // HotModule 插件在页面进行变更的时候只会重绘对应的页面模块,不会重绘整个 html 文件
  38. // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
  39. new webpack.HotModuleReplacementPlugin(),
  40. new webpack.NoEmitOnErrorsPlugin(),
  41. // 将 index.html 作为入口,注入 html 代码后生成 index.html文件
  42. // https://github.com/ampedandwired/html-webpack-plugin
  43. new HtmlWebpackPlugin({
  44. filename: 'index.html',
  45. template: 'index.html',
  46. inject: true
  47. }),
  48. // webpack错误信息提示插件
  49. new FriendlyErrorsPlugin()
  50. ]
  51. })
  52.  

webpack.base.conf.js

在webpack.dev.conf.js中出现webpack.base.conf.js,这个文件是开发环境和生产环境,甚至测试环境,这些环境的公共webpack配置。可以说,这个文件相当重要。

  1. // node自带的文件路径工具
  2. var path = require('path')
  3. // 工具函数集合
  4. var utils = require('./utils')
  5. // 配置文件
  6. var config = require('../config')
  7. // 工具函数集合
  8. var vueLoaderConfig = require('./vue-loader.conf')
  9.  
  10. /**
  11. * 获得绝对路径
  12. * @method resolve
  13. * @param {String} dir 相对于本文件的路径
  14. * @return {String} 绝对路径
  15. */
  16. function resolve(dir) {
  17. return path.join(__dirname, '..', dir)
  18. }
  19.  
  20. module.exports = {
  21. entry: {
  22. app: './src/main.js'
  23. },
  24. output: {
  25. // 编译输出的静态资源根路径
  26. path: config.build.assetsRoot,
  27. // 编译输出的文件名
  28. filename: '[name].js',
  29. // 正式发布环境下编译输出的上线路径的根路径
  30. publicPath: process.env.NODE_ENV === 'production' ?
  31. config.build.assetsPublicPath : config.dev.assetsPublicPath
  32. },
  33. resolve: {
  34. // 自动补全的扩展名
  35. extensions: ['.js', '.vue', '.json'],
  36. // 路径别名
  37. alias: {
  38. // 例如 import Vue from 'vue',会自动到 'vue/dist/vue.common.js'中寻找
  39. 'vue$': 'vue/dist/vue.esm.js',
  40. '@': resolve('src'),
  41. }
  42. },
  43. module: {
  44. rules: [{
  45. // 审查 js 和 vue 文件
  46. // https://github.com/MoOx/eslint-loader
  47. test: /\.(js|vue)$/,
  48. loader: 'eslint-loader',
  49. // 表示预先处理
  50. enforce: "pre",
  51. include: [resolve('src'), resolve('test')],
  52. options: {
  53. formatter: require('eslint-friendly-formatter')
  54. }
  55. },
  56. {
  57. // 处理 vue文件
  58. // https://github.com/vuejs/vue-loader
  59. test: /\.vue$/,
  60. loader: 'vue-loader',
  61. options: vueLoaderConfig
  62. },
  63. {
  64. // 编译 js
  65. // https://github.com/babel/babel-loader
  66. test: /\.js$/,
  67. loader: 'babel-loader',
  68. include: [resolve('src'), resolve('test')]
  69. },
  70. {
  71. // 处理图片文件
  72. // https://github.com/webpack-contrib/url-loader
  73. test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
  74. loader: 'url-loader',
  75. query: {
  76. limit: 10000,
  77. name: utils.assetsPath('img/[name].[hash:7].[ext]')
  78. }
  79. },
  80. {
  81. // 处理字体文件
  82. test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
  83. loader: 'url-loader',
  84. query: {
  85. limit: 10000,
  86. name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
  87. }
  88. }
  89. ]
  90. }
  91. }

config/index.js

该文件在很多文件中都用到,是主要的配置文件,包含静态文件的路径、是否开启sourceMap等。其中,分为两个部分dev(开发环境的配置)和build(生产环境的配置)。

  1. // 详情见文档:https://vuejs-templates.github.io/webpack/env.html
  2. var path = require('path')
  3.  
  4. module.exports = {
  5. // production 生产环境
  6. build: {
  7. // 构建环境
  8. env: require('./prod.env'),
  9. // 构建输出的index.html文件
  10. index: path.resolve(__dirname, '../dist/index.html'),
  11. // 构建输出的静态资源路径
  12. assetsRoot: path.resolve(__dirname, '../dist'),
  13. // 构建输出的二级目录
  14. assetsSubDirectory: 'static',
  15. // 构建发布的根目录,可配置为资源服务器域名或 CDN 域名
  16. assetsPublicPath: '/',
  17. // 是否开启 cssSourceMap
  18. productionSourceMap: true,
  19. // Gzip off by default as many popular static hosts such as
  20. // Surge or Netlify already gzip all static assets for you.
  21. // Before setting to `true`, make sure to:
  22. // npm install --save-dev compression-webpack-plugin
  23. // 默认关闭 gzip,因为很多流行的静态资源主机,例如 Surge、Netlify,已经为所有静态资源开启gzip
  24. productionGzip: false,
  25. // 需要使用 gzip 压缩的文件扩展名
  26. productionGzipExtensions: ['js', 'css'],
  27. // Run the build command with an extra argument to
  28. // View the bundle analyzer report after build finishes:
  29. // `npm run build --report`
  30. // Set to `true` or `false` to always turn it on or off
  31. // 运行“build”命令行时,加上一个参数,可以在构建完成后参看包分析报告
  32. // true为开启,false为关闭
  33. bundleAnalyzerReport: process.env.npm_config_report
  34. },
  35. // dev 开发环境
  36. dev: {
  37. // 构建环境
  38. env: require('./dev.env'),
  39. // 端口号
  40. port: 3333,
  41. // 是否自动打开浏览器
  42. autoOpenBrowser: true,
  43. assetsSubDirectory: 'static',
  44. // 编译发布的根目录,可配置为资源服务器域名或 CDN 域名
  45. assetsPublicPath: '/',
  46. // proxyTable 代理的接口(可跨域)
  47. // 使用方法:https://vuejs-templates.github.io/webpack/proxy.html
  48. proxyTable: {},
  49. // CSS Sourcemaps off by default because relative paths are "buggy"
  50. // with this option, according to the CSS-Loader README
  51. // (https://github.com/webpack/css-loader#sourcemaps)
  52. // In our experience, they generally work as expected,
  53. // just be aware of this issue when enabling this option.
  54. // 默认情况下,关闭 CSS Sourcemaps,因为使用相对路径会报错。
  55. // CSS-Loader README:https://github.com/webpack/css-loader#sourcemaps
  56. cssSourceMap: false
  57. }
  58. }
  59.  

utils.js

utils.js也是一个被使用频率的文件,这个文件包含了三个工具函数:

  • 生成静态资源的路径
  • 生成 ExtractTextPlugin对象或loader字符串
  • 生成 style-loader的配置
  1. // node自带的文件路径工具
  2. var path = require('path')
  3. // 配置文件
  4. var config = require('../config')
  5. // 提取css的插件
  6. // https://github.com/webpack-contrib/extract-text-webpack-plugin
  7. var ExtractTextPlugin = require('extract-text-webpack-plugin')
  8.  
  9. /**
  10. * 生成静态资源的路径
  11. * @method assertsPath
  12. * @param {String} _path 相对于静态资源文件夹的文件路径
  13. * @return {String} 静态资源完整路径
  14. */
  15. exports.assetsPath = function (_path) {
  16. var assetsSubDirectory = process.env.NODE_ENV === 'production'
  17. ? config.build.assetsSubDirectory
  18. : config.dev.assetsSubDirectory
  19. // path.posix.join与path.join一样,不过总是以 posix 兼容的方式交互
  20. return path.posix.join(assetsSubDirectory, _path)
  21. }
  22.  
  23. /**
  24. * 生成处理css的loaders配置
  25. * @method cssLoaders
  26. * @param {Object} options 生成配置
  27. * option = {
  28. * // 是否开启 sourceMap
  29. * sourceMap: true,
  30. * // 是否提取css
  31. * extract: true
  32. * }
  33. * @return {Object} 处理css的loaders配置对象
  34. */
  35. exports.cssLoaders = function (options) {
  36. options = options || {}
  37.  
  38. var cssLoader = {
  39. loader: 'css-loader',
  40. options: {
  41. minimize: process.env.NODE_ENV === 'production',
  42. sourceMap: options.sourceMap
  43. }
  44. }
  45. /**
  46. * 生成 ExtractTextPlugin对象或loader字符串
  47. * @method generateLoaders
  48. * @param {Array} loaders loader名称数组
  49. * @return {String|Object} ExtractTextPlugin对象或loader字符串
  50. */
  51. function generateLoaders (loader, loaderOptions) {
  52. var loaders = [cssLoader]
  53. if (loader) {
  54. loaders.push({
  55. // 例如,sass?indentedSyntax
  56. // 在?号前加上“-loader”
  57. loader: loader + '-loader',
  58. options: Object.assign({}, loaderOptions, {
  59. sourceMap: options.sourceMap
  60. })
  61. })
  62. }
  63.  
  64. // extract为true时,提取css
  65. // 生产环境中,默认为true
  66. if (options.extract) {
  67. return ExtractTextPlugin.extract({
  68. use: loaders,
  69. fallback: 'vue-style-loader'
  70. })
  71. } else {
  72. return ['vue-style-loader'].concat(loaders)
  73. }
  74. }
  75.  
  76. // http://vuejs.github.io/vue-loader/en/configurations/extract-css.html
  77. return {
  78. css: generateLoaders(),
  79. postcss: generateLoaders(),
  80. less: generateLoaders('less'),
  81. sass: generateLoaders('sass', { indentedSyntax: true }),
  82. scss: generateLoaders('sass'),
  83. stylus: generateLoaders('stylus'),
  84. styl: generateLoaders('stylus')
  85. }
  86. }
  87.  
  88. /**
  89. * 生成 style-loader的配置
  90. * style-loader文档:https://github.com/webpack/style-loader
  91. * @method styleLoaders
  92. * @param {Object} options 生成配置
  93. * option = {
  94. * // 是否开启 sourceMap
  95. * sourceMap: true,
  96. * // 是否提取css
  97. * extract: true
  98. * }
  99. * @return {Array} style-loader的配置
  100. */
  101. exports.styleLoaders = function (options) {
  102. var output = []
  103. var loaders = exports.cssLoaders(options)
  104. for (var extension in loaders) {
  105. var loader = loaders[extension]
  106. output.push({
  107. test: new RegExp('\\.' + extension + '$'),
  108. use: loader
  109. })
  110. }
  111. return output
  112. }
  113.  

生产环境

开发环境的入口文件是build/build.js 。

build.js

该文件,为构建打包文件,会将源码进行构建(编译、压缩等)后打包。

  1. // 设置当前环境为生产环境
  2. process.env.NODE_ENV = 'production'
  3.  
  4. // loading 插件
  5. // https://github.com/sindresorhus/ora
  6. var ora = require('ora')
  7. // 可以在 node 中执行`rm -rf`的工具
  8. // https://github.com/isaacs/rimraf
  9. var rm = require('rimraf')
  10. // node自带的文件路径工具
  11. var path = require('path')
  12. // 在终端输出带颜色的文字
  13. // https://github.com/chalk/chalk
  14. var chalk = require('chalk')
  15. var webpack = require('webpack')
  16. // 配置文件
  17. var config = require('../config')
  18. var webpackConfig = require('./webpack.prod.conf')
  19.  
  20. // 在终端显示loading效果,并输出提示
  21. var spinner = ora('building for production...')
  22. spinner.start()
  23.  
  24. // 删除这个文件夹 (递归删除)
  25. rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
  26. if (err) throw err
  27. // 构建
  28. webpack(webpackConfig, function (err, stats) {
  29. // 构建成功
  30.  
  31. // 停止 loading动画
  32. spinner.stop()
  33. if (err) throw err
  34. process.stdout.write(stats.toString({
  35. colors: true,
  36. modules: false,
  37. children: false,
  38. chunks: false,
  39. chunkModules: false
  40. }) + '\n\n')
  41.  
  42. // 打印提示
  43. console.log(chalk.cyan(' Build complete.\n'))
  44. console.log(chalk.yellow(
  45. ' Tip: built files are meant to be served over an HTTP server.\n' +
  46. ' Opening index.html over file:// won\'t work.\n'
  47. ))
  48. })
  49. })
  50.  

webpack.prod.conf

该文件,为生产环境中webpack的配置入口。同时,它也依赖于前面提到的webpack.base.conf.js、utils.js和config/index.js。

  1. // node自带的文件路径工具
  2. var path = require('path')
  3. // 工具函数集合
  4. var utils = require('./utils')
  5. var webpack = require('webpack')
  6. // 配置文件
  7. var config = require('../config')
  8. // webpack 配置合并插件
  9. var merge = require('webpack-merge')
  10. // webpack 基本配置
  11. var baseWebpackConfig = require('./webpack.base.conf')
  12. // webpack 复制文件和文件夹的插件
  13. // https://github.com/kevlened/copy-webpack-plugin
  14. var CopyWebpackPlugin = require('copy-webpack-plugin')
  15. // 自动生成 html 并且注入到 .html 文件中的插件
  16. // https://github.com/ampedandwired/html-webpack-plugin
  17. var HtmlWebpackPlugin = require('html-webpack-plugin')
  18. // 提取css的插件
  19. // https://github.com/webpack-contrib/extract-text-webpack-plugin
  20. var ExtractTextPlugin = require('extract-text-webpack-plugin')
  21. // webpack 优化压缩和优化 css 的插件
  22. // https://github.com/NMFR/optimize-css-assets-webpack-plugin
  23. var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
  24.  
  25. // 如果当前环境为测试环境,则使用测试环境
  26. // 否则,使用生产环境
  27. var env = process.env.NODE_ENV === 'testing'
  28. ? require('../config/test.env')
  29. : config.build.env
  30.  
  31. var webpackConfig = merge(baseWebpackConfig, {
  32. module: {
  33. // styleLoaders
  34. rules: utils.styleLoaders({
  35. sourceMap: config.build.productionSourceMap,
  36. extract: true
  37. })
  38. },
  39. // 是否开启 sourceMap
  40. devtool: config.build.productionSourceMap ? '#source-map' : false,
  41. output: {
  42. // 编译输出的静态资源根路径
  43. path: config.build.assetsRoot,
  44. // 编译输出的文件名
  45. filename: utils.assetsPath('js/[name].[chunkhash].js'),
  46. // 没有指定输出名的文件输出的文件名
  47. chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  48. },
  49. plugins: [
  50. // definePlugin 接收字符串插入到代码当中, 所以你需要的话可以写上 JS 的字符串
  51. // 此处,插入适当的环境
  52. // http://vuejs.github.io/vue-loader/en/workflow/production.html
  53. new webpack.DefinePlugin({
  54. 'process.env': env
  55. }),
  56. // 压缩 js
  57. new webpack.optimize.UglifyJsPlugin({
  58. compress: {
  59. warnings: false
  60. },
  61. sourceMap: true
  62. }),
  63. // 提取 css
  64. new ExtractTextPlugin({
  65. filename: utils.assetsPath('css/[name].[contenthash].css')
  66. }),
  67. // 压缩提取出来的 css
  68. // 可以删除来自不同组件的冗余代码
  69. // Compress extracted CSS. We are using this plugin so that possible
  70. // duplicated CSS from different components can be deduped.
  71. new OptimizeCSSPlugin(),
  72. // 将 index.html 作为入口,注入 html 代码后生成 index.html文件
  73. // https://github.com/ampedandwired/html-webpack-plugin
  74. new HtmlWebpackPlugin({
  75. filename: process.env.NODE_ENV === 'testing'
  76. ? 'index.html'
  77. : config.build.index,
  78. template: 'index.html',
  79. inject: true,
  80. minify: {
  81. removeComments: true,
  82. collapseWhitespace: true,
  83. removeAttributeQuotes: true
  84. // 更多选项 https://github.com/kangax/html-minifier#options-quick-reference
  85. },
  86. // 必须通过 CommonsChunkPlugin一致地处理多个 chunks
  87. chunksSortMode: 'dependency'
  88. }),
  89. // 分割公共 js 到独立的文件
  90. // https://webpack.js.org/guides/code-splitting-libraries/#commonschunkplugin
  91. new webpack.optimize.CommonsChunkPlugin({
  92. name: 'vendor',
  93. minChunks: function (module, count) {
  94. // node_modules中的任何所需模块都提取到vendor
  95. return (
  96. module.resource &&
  97. /\.js$/.test(module.resource) &&
  98. module.resource.indexOf(
  99. path.join(__dirname, '../node_modules')
  100. ) === 0
  101. )
  102. }
  103. }),
  104. // 将webpack runtime 和模块清单 提取到独立的文件,以防止当 app包更新时导致公共 jsd hash也更新
  105. // extract webpack runtime and module manifest to its own file in order to
  106. // prevent vendor hash from being updated whenever app bundle is updated
  107. new webpack.optimize.CommonsChunkPlugin({
  108. name: 'manifest',
  109. chunks: ['vendor']
  110. }),
  111. // 复制静态资源
  112. // https://github.com/kevlened/copy-webpack-plugin
  113. new CopyWebpackPlugin([
  114. {
  115. from: path.resolve(__dirname, '../static'),
  116. to: config.build.assetsSubDirectory,
  117. ignore: ['.*']
  118. }
  119. ])
  120. ]
  121. })
  122.  
  123. // 开启 gzip 的情况时,给 webpack plugins添加 compression-webpack-plugin 插件
  124. if (config.build.productionGzip) {
  125. // webpack 压缩插件
  126. // https://github.com/webpack-contrib/compression-webpack-plugin
  127. var CompressionWebpackPlugin = require('compression-webpack-plugin')
  128.  
  129. // 向webpackconfig.plugins中加入下方的插件
  130. webpackConfig.plugins.push(
  131. new CompressionWebpackPlugin({
  132. asset: '[path].gz[query]',
  133. algorithm: 'gzip',
  134. test: new RegExp(
  135. '\\.(' +
  136. config.build.productionGzipExtensions.join('|') +
  137. ')$'
  138. ),
  139. threshold: 10240,
  140. minRatio: 0.8
  141. })
  142. )
  143. }
  144.  
  145. // 开启包分析的情况时, 给 webpack plugins添加 webpack-bundle-analyzer 插件
  146. if (config.build.bundleAnalyzerReport) {
  147. // https://github.com/th0r/webpack-bundle-analyzer
  148. var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  149. webpackConfig.plugins.push(new BundleAnalyzerPlugin())
  150. }
  151.  
  152. module.exports = webpackConfig
  153.  

其他

如果你觉得在segmentfault的代码阅读体验不好,你可以到我github上将代码clone下来看。

vue-cli-webpack-analysis

总结

这次研究webpack配置的时候,我自己跟着源码敲了一遍(很笨的方法),然后,在github和webpack官网上查使用到的插件的作用和用法。经过这一次折腾,加深对webpack的认识。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号