webpack.prod.conf.js 6.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
'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 UglifyJsPlugin = require('uglifyjs-webpack-plugin')
yma16's avatar
yma16 已提交
13

yma16's avatar
yma16 已提交
14
const env =
15 16 17
  process.env.NODE_ENV === 'testing'
    ? require('../config/test.env')
    : require('../config/prod.env')
yma16's avatar
yma16 已提交
18 19

// cdn 引入
20
let externalModules = {}
yma16's avatar
yma16 已提交
21
//cdn 配置
22 23
let externalConfig = []
if (process.env.NODE_ENV === 'production') {
yma16's avatar
yma16 已提交
24 25
  //生产环境
  externalModules = {
26 27 28 29 30 31 32 33
    vue: 'Vue',
    'vue-router': 'VueRouter',
    vuex: 'Vuex',
    axios: 'axios',
    'element-ui': 'element-ui',
    echarts: 'echarts',
    highlight: 'hljs',
  }
yma16's avatar
yma16 已提交
34
  externalConfig = [
35
    {js: 'https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js', css: ''},
yma16's avatar
yma16 已提交
36
    {
37 38
      js: 'https://cdn.bootcdn.net/ajax/libs/vue-router/3.0.1/vue-router.min.js',
      css: '',
yma16's avatar
yma16 已提交
39
    },
40 41
    {js: 'https://unpkg.com/axios/dist/axios.min.js', css: ''},
    {js: 'https://cdn.bootcss.com/vuex/3.6.2/vuex.min.js', css: ''},
yma16's avatar
yma16 已提交
42
    {
43 44
      js: 'https://unpkg.com/element-ui/lib/index.js',
      css: 'https://unpkg.com/element-ui/lib/theme-chalk/index.css',
yma16's avatar
yma16 已提交
45 46
    },
    {
47 48
      js: 'https://cdn.jsdelivr.net/npm/echarts@5.3.3/dist/echarts.min.js',
      css: '',
yma16's avatar
yma16 已提交
49 50
    },
    {
51 52
      js: 'https://cdn.bootcdn.net/ajax/libs/highlight.js/11.6.0/highlight.min.js',
      css: '',
yma16's avatar
yma16 已提交
53 54
    },
    {
55 56
      js: '',
      css: 'https://cdn.bootcdn.net/ajax/libs/github-markdown-css/5.1.0/github-markdown-light.min.css',
yma16's avatar
yma16 已提交
57
    },
58 59 60 61 62
    {
      js: '',
      css: 'https://cdn.bootcdn.net/ajax/libs/nprogress/0.2.0/nprogress.css',
    },
  ]
yma16's avatar
yma16 已提交
63
}
yma16's avatar
yma16 已提交
64 65

const webpackConfig = merge(baseWebpackConfig, {
yma16's avatar
yma16 已提交
66
  externals: externalModules, //打包忽略
yma16's avatar
yma16 已提交
67 68 69 70
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true,
yma16's avatar
yma16 已提交
71 72
      usePostCSS: true,
    }),
yma16's avatar
yma16 已提交
73 74 75 76
  },
  devtool: config.build.productionSourceMap ? config.build.devtool : false,
  output: {
    path: config.build.assetsRoot,
77 78
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js'),
yma16's avatar
yma16 已提交
79 80 81 82
  },
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
83
      'process.env': env,
yma16's avatar
yma16 已提交
84 85 86 87
    }),
    new UglifyJsPlugin({
      uglifyOptions: {
        compress: {
yma16's avatar
yma16 已提交
88 89
          warnings: false,
        },
yma16's avatar
yma16 已提交
90 91
      },
      sourceMap: config.build.productionSourceMap,
yma16's avatar
yma16 已提交
92
      parallel: true,
yma16's avatar
yma16 已提交
93 94 95
    }),
    // extract css into its own file
    new ExtractTextPlugin({
96
      filename: utils.assetsPath('css/[name].[contenthash].css'),
yma16's avatar
yma16 已提交
97 98
      // Setting the following option to `false` will not extract CSS from codesplit chunks.
      // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
yma16's avatar
yma16 已提交
99
      // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
yma16's avatar
yma16 已提交
100 101 102 103 104 105 106
      // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
      allChunks: true,
    }),
    // Compress extracted CSS. We are using this plugin so that possible
    // duplicated CSS from different components can be deduped.
    new OptimizeCSSPlugin({
      cssProcessorOptions: config.build.productionSourceMap
107 108
        ? {safe: true, map: {inline: false}}
        : {safe: true},
yma16's avatar
yma16 已提交
109 110 111 112 113
    }),
    // 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
    new HtmlWebpackPlugin({
yma16's avatar
yma16 已提交
114
      filename:
115 116
        process.env.NODE_ENV === 'testing' ? 'index.html' : config.build.index,
      template: 'index.html',
yma16's avatar
yma16 已提交
117 118 119 120
      inject: true,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
yma16's avatar
yma16 已提交
121
        removeAttributeQuotes: true,
yma16's avatar
yma16 已提交
122 123 124 125
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
126
      chunksSortMode: 'dependency',
yma16's avatar
yma16 已提交
127 128
      cdnConfig: externalConfig, // cdn配置
      onlyCss: true, //dev下只加载css
yma16's avatar
yma16 已提交
129 130 131 132 133 134 135
    }),
    // keep module.id stable when vendor modules does not change
    new webpack.HashedModuleIdsPlugin(),
    // enable scope hoisting
    new webpack.optimize.ModuleConcatenationPlugin(),
    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
136 137
      name: 'vendor',
      minChunks (module) {
yma16's avatar
yma16 已提交
138 139 140 141
        // any required modules inside node_modules are extracted to vendor
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
142 143
          module.resource.indexOf(path.join(__dirname, '../node_modules')) === 0
        )
yma16's avatar
yma16 已提交
144
      },
yma16's avatar
yma16 已提交
145 146 147 148
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
149
      name: 'manifest',
yma16's avatar
yma16 已提交
150
      minChunks: Infinity,
yma16's avatar
yma16 已提交
151 152 153 154 155
    }),
    // 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({
156 157
      name: 'app',
      async: 'vendor-async',
yma16's avatar
yma16 已提交
158
      children: true,
yma16's avatar
yma16 已提交
159
      minChunks: 3,
yma16's avatar
yma16 已提交
160 161
    }),

yma16's avatar
yma16 已提交
162
    // copy custom myblog_static assets
yma16's avatar
yma16 已提交
163 164
    new CopyWebpackPlugin([
      {
165
        from: path.resolve(__dirname, '../myblog_static'),
yma16's avatar
yma16 已提交
166
        to: config.build.assetsSubDirectory,
167
        ignore: ['.*'],
yma16's avatar
yma16 已提交
168 169 170
      },
    ]),
  ],
171
})
yma16's avatar
yma16 已提交
172 173

if (config.build.productionGzip) {
174
  const CompressionWebpackPlugin = require('compression-webpack-plugin')
yma16's avatar
yma16 已提交
175 176
  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
177 178
      filename: '[path].gz[query]',
      algorithm: 'gzip',
yma16's avatar
yma16 已提交
179
      test: new RegExp(
180
        '\\.(' + config.build.productionGzipExtensions.join('|') + ')$'
yma16's avatar
yma16 已提交
181 182
      ),
      threshold: 10240,
yma16's avatar
yma16 已提交
183
      minRatio: 0.8,
yma16's avatar
yma16 已提交
184
    })
185
  )
yma16's avatar
yma16 已提交
186 187 188
}

if (config.build.bundleAnalyzerReport) {
yma16's avatar
yma16 已提交
189
  const BundleAnalyzerPlugin =
190 191
    require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
yma16's avatar
yma16 已提交
192 193 194
}

if (config.build.isIgnoreLogs) {
195
  const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
yma16's avatar
yma16 已提交
196 197 198 199 200 201 202
  let optimization = [
    new UglifyJsPlugin({
      uglifyOptions: {
        compress: {
          warnings: false,
          drop_debugger: true, //去掉debugger
          drop_console: true, // 去掉console
203
          pure_funcs: ['console.log'], // 移除console
yma16's avatar
yma16 已提交
204 205 206 207 208
        },
      },
      sourceMap: config.build.productionSourceMap,
      parallel: true,
    }),
209 210
  ]
  webpackConfig.plugins.push(...optimization)
yma16's avatar
yma16 已提交
211 212
}

213
module.exports = webpackConfig