vue-cli 비계 의 웹 팩 설정 방법 을 자세히 설명 합 니 다.

웹 팩 이란 무엇 입 니까?
웹 팩 은 module bundler(모듈 패키지 도구)입 니 다.모듈 이란 일반적인 전단 개발 에서 자바 스 크 립 트,CSS,이미지 등 정적 자원 을 사용 하 는 것 입 니 다.웹 팩 은 이러한 정적 자원 파일 을 모듈 이 라 고 부 릅 니 다.
웹 팩 은 AMD 와 CommonJS,그리고 다른 일부 모듈 시스템 을 지원 하고 다양한 JS 쓰기 규범 을 호 환 하여 모듈 간 의 관 계 를 처리 할 수 있 기 때문에 더욱 강력 한 JS 모듈 화 기능 을 가지 고 정적 자원 에 대해 통일 적 인 관리 와 포장 을 할 수 있 습 니 다.홈 페이지 에서 이 사진 으로 소개 합 니 다.

이 는 많은 곳 에서 Grunt 와 Gulp 를 대체 할 수 있 습 니 다.포장 CSS 를 컴 파일 하고 CSS 예비 처 리 를 하 며 JS 의 방언 을 컴 파일 하고 그림 을 포장 하 며 코드 압축 등 을 할 수 있 기 때 문 입 니 다.그래서 제 가 웹 팩 을 접 하고 나 서 gulp 를 별로 쓰 고 싶 지 않 았 어 요.
웹 팩 을 왜 사용 합 니까?
총 결 은 다음 과 같다.
  • CommonJS,AMD,ES6 의 문법 을 호 환 했다
  • js,css,이미지 등 자원 파일 에 대해 모두 포장 을 지원 합 니 다
  • 4.567917.직렬 식 모듈 로 더 와 플러그 인 체 제 는 더욱 유연성 과 확장 성 을 가지 게 한다.예 를 들 어 CoffeeScript,ES6 에 대한 지원 을 제공한다
  • 독립 된 프로필 webpack.config.js 가 있 습 니 다
  • 4.567917.코드 를 서로 다른 chunk 로 절단 하여 필요 에 따라 로드 를 실현 하고 초기 화 시간 을 낮 출 수 있 습 니 다
  • SourceUrls 와 SourceMaps 를 지원 하여 디 버 깅 하기 쉽다
  • 4.567917.강력 한 Plugin 인 터 페 이 스 를 가지 고 대부분 내부 플러그 인 으로 사용 하기에 비교적 유연 하 다웹 팩 은 비동기 IO 를 사용 하고 다단 계 캐 시 를 가지 고 있 습 니 다.이것 은 웹 팩 이 빠 르 고 증분 컴 파일 에 있어 서 더욱 빨 라 집 니 다.
    웹 팩 은 주로 vue 와 React 에 많이 사용 되 는데 사실은 Browserify 와 매우 비슷 하지만 응용 프로그램 을 여러 파일 로 포장 합 니 다.한 페이지 에 여러 페이지 가 적용 된다 면 사용 자 는 해당 페이지 의 코드 만 다운로드 할 수 있 습 니 다.다른 페이지 에 접근 할 때 일반적인 코드 를 다시 다운로드 할 필요 가 없습니다.
    본인 프로젝트 기반 사용
    vue webpack 의 프로필 의 기본 디 렉 터 리 구 조 는 다음 과 같 습 니 다.
    
    config
    ├── dev.env.js //dev      
    ├── index.js // dev prod         
    └── prod.env.js // prod      
    build
    ├── build.js // npm run build      
    ├── check-versions.js //   npm node   
    ├── logo.png
    ├── utils.js //       ,      cssLoader styleLoader  
    ├── vue-loader.conf.js // vueloader     
    ├── webpack.base.conf.js // dev prod     
    ├── webpack.dev.conf.js // dev     
    └── webpack.prod.conf.js // prod     
    
    Config 폴 더 아래 파일 설명
    dev.env.js
    config 내 파일 은 build 에 서 비 스 를 제공 합 니 다.대부분 변 수 를 정의 합 니 다 export
    
    use strict //[      ]
    /**
    * [webpack-merge         ,                
    ] 
    */
    const merge = require('webpack-merge')
    const prodEnv = require('./prod.env')
    
    module.exports = merge(prodEnv, {
     NODE_ENV: '"development"'
    })
    prod.env.js
    개발 시 dev.env.js 의 개발 환경 설정 을 가 져 오고 발표 시 prod.env.js 의 생산 환경 설정 을 호출 합 니 다.
    
    use strict
    module.exports = {
    NODE_ENV: '"production"'
    }
    index.js
    
    const path = require('path')
    module.exports = {
     /**
      * [      ]
      */
    dev: {
      assetsSubDirectory: 'static', // [   ,    css,js,image   ]
    assetsPublicPath: '/', // [   ]
    /**
    * [      ] 
    */
      proxyTable: {
       '/hcm': {
        target: 'https://127.0.0.1:8448',
        changeOrigin: true,
        secure: false
       },
       headers: {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
        "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
       }
      },
      host: '127.0.0.1', // [       ]
      port: 8083, // [     ,               ]
      autoOpenBrowser: true, // [     (     npm run dev)   http://127.0.0.1:8083/  ]
      errorOverlay: true, // [       ]
      notifyOnErrors: true, // [       ]
      poll:false, // [      (file system)         devServer.watchOptions] 
      useEslint: true, // [          ]
      showEslintErrorsInOverlay: false, // [    eslint     ]
      devtool: 'eval-source-map', // [    ,         ]
      cacheBusting: true, // [     ]
      cssSourceMap: false // [        bug       ,    sourcemap             ,                  ,          ]
     },
    /**
    * [      ] 
    */
     build: {
     /**
    * [index、login、license、forbidden、notfound、Internal.licenses           ,        ] 
    */
      index: path.resolve(__dirname, '../../hcm-modules/hcm-web/src/main/resources/META-INF/resources/index.html'),
      login: path.resolve(__dirname, '../../hcm-modules/hcm-web/src/main/resources/META-INF/resources/login.html'),
      license: path.resolve(__dirname, '../../hcm-modules/hcm-web/src/main/resources/META-INF/resources/license.html'),
      forbidden: path.resolve(__dirname, '../../hcm-modules/hcm-web/src/main/resources/META-INF/resources/error/403.html'),
      notfound: path.resolve(__dirname, '../../hcm-modules/hcm-web/src/main/resources/META-INF/resources/error/404.html'),
      internal: path.resolve(__dirname, '../../hcm-modules/hcm-web/src/main/resources/META-INF/resources/error/500.html'),
      licenses: path.resolve(__dirname, '../../hcm-modules/hcm-web/src/main/resources/META-INF/resources/docs/licenses.html'),
    /**
    * [              ] 
    */
      assetsRoot: path.resolve(__dirname, '../../hcm-modules/hcm-web/src/main/resources/META-INF/resources'),
      assetsSubDirectory: 'static', //js、css、images      
      assetsPublicPath: './', //      ,      dist        ,     ./。        ,               
      productionSourceMap: true,
      devtool: '#source-map',
      productionGzip: false, //unit gzip        ,gzip               js css
      productionGzipExtensions: ['js', 'css'],
      bundleAnalyzerReport: process.env.npm_config_report //    
     }
    }
    build 폴 더 아래 파일 설명
    build.js
    이 파일 은 생산 버 전 을 구축 하 는 역할 을 합 니 다.package.json 의 scripts build 는 node build/build.js 입 니 다.명령 행 npm run build 를 입력 하여 이 파일 을 컴 파일 하여 생산 환경 을 만 드 는 코드 입 니 다.
    
    require('./check-versions')() //check-versions:         。 ()         
    process.env.NODE_ENV = 'production' //         
    /**
    *          
    */
    const ora = require('ora') //    
    const rm = require('rimraf') //    
    const path = require('path')
    const chalk = require('chalk') //            
    const webpack = require('webpack')
    const config = require('../config') //       index.js  
    const webpackConfig = require('./webpack.prod.conf')
    const spinner = ora('building for production...') //  start         ,      
    spinner.start()
    //   dist        ,        hash   ,           
    rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
     if (err) throw err
     webpack(webpackConfig, (err, stats) => {
      spinner.stop()
      if (err) throw err
      process.stdout.write(stats.toString({
       colors: true,
       modules: false,
       children: false,
       chunks: false,
       chunkModules: false
      }) + '

    ') if (stats.hasErrors()) { console.log(chalk.red(' Build failed with errors.
    ')) process.exit(1) } console.log(chalk.cyan(' Build complete.
    ')) console.log(chalk.yellow( ' Tip: built files are meant to be served over an HTTP server.
    ' + ' Opening index.html over file:// won\'t work.
    ' )) }) })
    check-versions.js
    이 파일 은 node 와 npm 버 전 을 검사 하 는 데 사용 되 며 버 전 의존 도 를 실현 합 니 다.
    
    const chalk = require('chalk') 
    const semver = require('semver') //       
    const packageConfig = require('../package.json')
    const shell = require('shelljs')
    function exec (cmd) {
     //    child_process        ,   Unix                
     return require('child_process').execSync(cmd).toString().trim()
    }
    const versionRequirements = [
     {
      name: 'node',
      currentVersion: semver.clean(process.version), //  semver     
      versionRequirement: packageConfig.engines.node //  package.json    node  
     }
    ]
    if (shell.which('npm')) {
     versionRequirements.push({
      name: 'npm',
      currentVersion: exec('npm --version'), //     npm --version  ,        exec  ,          
      versionRequirement: packageConfig.engines.npm
     })
    }
    module.exports = function () {
     const warnings = []
     for (let i = 0; i < versionRequirements.length; i++) {
      const mod = versionRequirements[i]
      if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
       //                package.json         ,            
    warnings.push(mod.name + ': ' +
        chalk.red(mod.currentVersion) + ' should be ' +
        chalk.green(mod.versionRequirement)
       )
      }
     }
     if (warnings.length) {
      console.log('')
      console.log(chalk.yellow('To use this template, you must update following to modules:'))
      console.log()
      for (let i = 0; i < warnings.length; i++) {
       const warning = warnings[i]
       console.log(' ' + warning)
      }
      console.log()
      process.exit(1)
     }
    }
    utils.js
    utils 는 도구 라 는 뜻 으로 css 를 처리 하 는 파일 입 니 다.
    
    const path = require('path')
    const config = require('../config')
    const ExtractTextPlugin = require('extract-text-webpack-plugin')
    const packageConfig = require('../package.json')
    exports.assetsPath = function (_path) {
     const assetsSubDirectory = process.env.NODE_ENV === 'production'
      ? config.build.assetsSubDirectory
      : config.dev.assetsSubDirectory
     return path.posix.join(assetsSubDirectory, _path)
    }
    exports.cssLoaders = function (options) {
     options = options || {}
    //   css-loader postcssLoader,  options.usePostCSS         postcssLoader      
    
     const cssLoader = {
      loader: 'css-loader',
      options: {
       sourceMap: options.sourceMap
      }
     }
     const postcssLoader = {
      loader: 'postcss-loader',
      options: {
       sourceMap: options.sourceMap
      }
     }
     // generate loader string to be used with extract text plugin
     function generateLoaders (loader, loaderOptions) {
      const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
      if (loader) {
       loaders.push({
        loader: loader + '-loader',
      //Object.assign es6      ,            
        options: Object.assign({}, loaderOptions, {
         sourceMap: options.sourceMap
        })
       })
      }
      // Extract CSS when that option is specified
      // (which is the case during production build)
    if (options.extract) {
    //ExtractTextPlugin      ,           loaders,          vue-style-loader
       return ExtractTextPlugin.extract({
        use: loaders,
        fallback: 'vue-style-loader',
        publicPath: '../../'
       })
    } else {
    //  vue-style-loader  loaders    
       return ['vue-style-loader'].concat(loaders)
      }
     }
     // https://vue-loader.vuejs.org/en/configurations/extract-css.html
     return {
      css: generateLoaders(),//  css-loader   vue-style-loader
      postcss: generateLoaders(),//  css-loader postcssLoader   vue-style-loader
      less: generateLoaders('less'), //  less-loader   vue-style-loader
      sass: generateLoaders('sass', { indentedSyntax: true }), //  sass-loader   vue-style-loader
      scss: generateLoaders('sass'), //  sass-loader   vue-style-loader
      stylus: generateLoaders('stylus'), //  stylus-loader   vue-style-loader
      styl: generateLoaders('stylus') //  stylus-loader   vue-style-loader
     }
    }
    // Generate loaders for standalone style files (outside of .vue)
    exports.styleLoaders = function (options) {
     const output = []
     const loaders = exports.cssLoaders(options)
    //   css,less,sass            output
     for (const extension in loaders) {
      const loader = loaders[extension]
      output.push({
       test: new RegExp('\\.' + extension + '$'),
       use: loader
      })
     }
     return output
    }
    exports.createNotifierCallback = () => {
    //         
     const notifier = require('node-notifier')
     return (severity, errors) => {
    if (severity !== 'error') return
    //             ,      ,       
      const error = errors[0]
      const filename = error.file && error.file.split('!').pop()
      notifier.notify({
       title: packageConfig.name,
       message: severity + ': ' + error.name,
       subtitle: filename || '',
       icon: path.join(__dirname, 'logo.png')
      })
     }
    }
    vue-loader.conf.js
    이 파일 의 주요 역할 은.vue 파일 을 처리 하고 이 파일 의 모든 언어 블록(template,script,style)을 분석 하여 js 가 사용 할 수 있 는 js 모듈 로 변환 하 는 것 입 니 다.
    
    const utils = require('./utils')
    const config = require('../config')
    const isProduction = process.env.NODE_ENV === 'production'
    const sourceMapEnabled = isProduction
     ? config.build.productionSourceMap
     : config.dev.cssSourceMap
    //      css  ,              sourceMap, extract                      
    module.exports = {
     loaders: utils.cssLoaders({
      sourceMap: sourceMapEnabled,
      extract: isProduction
     }),
     cssSourceMap: sourceMapEnabled,
     cacheBusting: config.dev.cacheBusting,
    //         ,          ,  src   ,   require  ,          webpack   
     transformToRequire: {
      video: ['src', 'poster'],
      source: 'src',
      img: 'src',
      image: 'xlink:href'
     }
    }
    webpack.base.conf.js
    웹 팩.base.conf.js 는 개발 과 생산 이 공동으로 사용 하 는 기본 설정 파일 로 주로 배합 입구,출력 환경 설정,모듈 resolve 와 플러그 인 설정 등 을 실현 합 니 다.
    
    const path = require('path')
    const utils = require('./utils')
    /**
    * [  index.js    ] 
    */
    const config = require('../config')
    const vueLoaderConfig = require('./vue-loader.conf')
    
    /**
     * [      ]
     * @param dir [    ]
     *_dirname                * 
     *@return       
    */
    function resolve (dir) {
     return path.join(__dirname, '..', dir)
    }
    const createLintingRule = () => ({
     test: /\.(js|vue)$/,
     loader: 'eslint-loader',
     enforce: 'pre',
     include: [resolve('src'), resolve('test')],
     options: {
      formatter: require('eslint-friendly-formatter'),
      emitWarning: !config.dev.showEslintErrorsInOverlay
     }
    })
    
    module.exports = {
     context: path.resolve(__dirname, '../'),
      /**
        * [      ]
       */
     entry: {
    /**
        * [      , babel-polyfill  es6     ]
       */
      app: ['babel-polyfill', './src/main.js'],
      login: ['babel-polyfill', './src/loginMain.js'],
      license: ['babel-polyfill', './src/licenseMain.js']
     },
    /**
      * [      ]
    */
     output: {
      path: config.build.assetsRoot,
      filename: '[name].js',
      publicPath: process.env.NODE_ENV === 'production'
       ? config.build.assetsPublicPath
       : config.dev.assetsPublicPath //      
     },
     resolve: {
      /**
        * [extensions:         ,  important   ,         ]
       */
    extensions: ['.js', '.vue', '.json'],
    /**
        * [alias        ]
    */
      alias: {
       'vue$': 'vue/dist/vue.esm.js',
       '@': resolve('src')
      }
     },
    /**
    *               
    */
     module: {
    rules: [
       ...(config.dev.useEslint ? [createLintingRule()] : []),
    /**
       * [  vue-loader vue     js   ]
    */
       {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
       },
    /**
        * [  babel-loader js     es5/es6   ]
    */
       {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test')]
       },
    /**
       * [  、  、     url-loader    ,  10000    base64]
    */
       {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
         limit: 10000,
         name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
       },
       {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
         limit: 10000,
         name: utils.assetsPath('media/[name].[hash:7].[ext]')
        }
       },
       {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        options: {
         limit: 10000,
         name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
       },
    /**
        * [canvas   ]
    */
       {
        test: path.resolve(`${resolve('src')}/lib/jtopo.js`),
        loader: ['exports-loader?window.JTopo', 'script-loader']
       }
      ]
     },
    //     Node.js       ,       webpack    Node.js    vue  
     node: {
      setImmediate: false,
      dgram: 'empty',
      fs: 'empty',
      net: 'empty',                           
      tls: 'empty',
      child_process: 'empty'
     }
    }
    webpack.dev.conf.js
    
    const path = require('path')
    const utils = require('./utils')
    const webpack = require('webpack')
    const config = require('../config')
    //  webpack-merge  webpack.dev.conf.js wepack.base.config.js   
    const merge = require('webpack-merge')
    const baseWebpackConfig = require('./webpack.base.conf')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    //  webpack           
    const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
    //         ,       8000    
    const portfinder = require('portfinder')
    // processs node                  , host
    const HOST = process.env.HOST
    const PORT = process.env.PORT && Number(process.env.PORT)
    function resolveApp(relativePath) {
     return path.resolve(relativePath);
    }
    const devWebpackConfig = merge(baseWebpackConfig, {
     module: {
    //     utils      styleLoaders,   css,less,postcss   
      rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
     },
    //     
     devtool: config.dev.devtool,
    //         config index.js     
     devServer: {
    //         none, error, warning    info
    clientLogLevel: 'warning',
    //   HTML5 History API
    historyApiFallback: true,
    hot: true, //   
    compress: true, //  
      host: HOST || config.dev.host,
    port: PORT || config.dev.port,
    open: config.dev.autoOpenBrowser, //          
      overlay: config.dev.errorOverlay
       ? { warnings: false, errors: true }
       : false,
      publicPath: config.dev.assetsPublicPath,
    proxy: config.dev.proxyTable,//    
    quiet: true, //              ,  FriendlyErrorsPlugin     true  watchOptions: {
       poll: config.dev.poll, //         
      }
     },
     plugins: [
      new webpack.DefinePlugin({
       'process.env': require('../config/dev.env')
      }),
    new webpack.HotModuleReplacementPlugin(),//       ,            
    new webpack.NamedModulesPlugin(), //          
    new webpack.NoEmitOnErrorsPlugin(), // webpack       ,       ,            
    // https://github.com/ampedandwired/html-webpack-plugin
    //            html5                      
    new HtmlWebpackPlugin({
       filename: 'index.html',
       template: 'index.html',
       inject: true,
       chunks: ['app']
      }),
      new HtmlWebpackPlugin({
       filename: 'login.html',
       template: 'login.html',
       inject: true,
       chunks: ['login']
      }),
      new HtmlWebpackPlugin({
       filename: 'license.html',
       template: 'license.html',
       inject: true,
       chunks: ['license']
      }),
      new HtmlWebpackPlugin({
       filename: 'licenses.html',
       template: 'licenses.html',
       inject: true,
       chunks: []
      }),
      new HtmlWebpackPlugin({
       filename: '404.html',
       template: path.resolve(__dirname, '../errors/404.html'),
       favicon: resolveApp('favicon.ico'),
       inject: true,
       chunks: []
      }),
      new HtmlWebpackPlugin({
       filename: '403.html',
       template: path.resolve(__dirname, '../errors/403.html'),
       favicon: resolveApp('favicon.ico'),
       inject: true,
       chunks: []
      }),
      new HtmlWebpackPlugin({
       filename: '500.html',
       template: path.resolve(__dirname, '../errors/500.html'),
       favicon: resolveApp('favicon.ico'),
       inject: true,
       chunks: []
      })
     ]
    })
    
    module.exports = new Promise((resolve, reject) => {
     portfinder.basePort = process.env.PORT || config.dev.port
    //     
     portfinder.getPort((err, port) => {
      if (err) {
       reject(err)
    } else {
    //           evn devServer   
       process.env.PORT = port
       // add port to devServer config
       devWebpackConfig.devServer.port = port
    //       
       devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
        compilationSuccessInfo: {
         messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
        },
        onErrors: config.dev.notifyOnErrors
        ? utils.createNotifierCallback()
        : undefined
       }))
       resolve(devWebpackConfig)
      }
     })
    })
    webpack.prod.conf.js
    
    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')
    
    const env = require('../config/prod.env')
    function resolveApp(relativePath) {
     return path.resolve(relativePath);
    }
    const webpackConfig = merge(baseWebpackConfig, {
     module: {
      rules: utils.styleLoaders({
       sourceMap: config.build.productionSourceMap,//       。   true
       extract: true,
       usePostCSS: true
      })
     },
     devtool: config.build.productionSourceMap ? config.build.devtool : 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
      }),
      new UglifyJsPlugin({
       uglifyOptions: {
        compress: {
         warnings: false //  :true    ,false   
        }
       },
       sourceMap: config.build.productionSourceMap,
       parallel: true
      }),
    // extract css into its own file
    //    。       index   style  ,           ,    
    new ExtractTextPlugin({
       filename: utils.assetsPath('css/[name].[contenthash].css'),
       allChunks: true,
    }),
    //  css   
      new OptimizeCSSPlugin({
       cssProcessorOptions: config.build.productionSourceMap
        ? { safe: true, map: { inline: false } }
        : { safe: true }
      }),
      //html  
      new HtmlWebpackPlugin({
       filename: config.build.index,
       template: 'index.html',
       inject: true,
    //  
       minify: {
        removeComments: true, //    
        collapseWhitespace: true, //    
        removeAttributeQuotes: true //       
       },
       chunks: ['vendor', 'manifest', 'app'],
       // necessary to consistently work with multiple chunks via CommonsChunkPlugin
       chunksSortMode: 'dependency'
      }),
      new HtmlWebpackPlugin({
       filename: config.build.login,
       template: 'login.html',
       inject: true,
       minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
       },
       chunks: ['vendor', 'manifest', 'login'],
       // necessary to consistently work with multiple chunks via CommonsChunkPlugin
       chunksSortMode: 'dependency'
      }),
      new HtmlWebpackPlugin({
       filename: config.build.license,
       template: 'license.html',
       inject: true,
       minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
       },
       chunks: ['vendor', 'manifest', 'license'],
       // necessary to consistently work with multiple chunks via CommonsChunkPlugin
       chunksSortMode: 'dependency'
      }),
      new HtmlWebpackPlugin({
       filename: config.build.notfound,
       template: path.resolve(__dirname, '../errors/404.html'),
       inject: true,
       favicon: resolveApp('favicon.ico'),
       minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
       },
       chunks: [],
       // necessary to consistently work with multiple chunks via CommonsChunkPlugin
       chunksSortMode: 'dependency'
      }),
      new HtmlWebpackPlugin({
       filename: config.build.forbidden,
       template: path.resolve(__dirname, '../errors/403.html'),
       inject: true,
       favicon: resolveApp('favicon.ico'),
       minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
       },
       chunks: [],
       // necessary to consistently work with multiple chunks via CommonsChunkPlugin
       chunksSortMode: 'dependency'
      }),
      new HtmlWebpackPlugin({
       filename: config.build.internal,
       template: path.resolve(__dirname, '../errors/500.html'),
       inject: true,
       favicon: resolveApp('favicon.ico'),
       minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
       },
       chunks: [],
       // necessary to consistently work with multiple chunks via CommonsChunkPlugin
       chunksSortMode: 'dependency'
      }),
      new HtmlWebpackPlugin({
       filename: config.build.licenses,
       template: 'licenses.html',
       inject: true,
       minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
       },
       chunks: [],
       // necessary to consistently work with multiple chunks via CommonsChunkPlugin
       chunksSortMode: 'dependency'
      }),
      // keep module.id stable when vender modules does not change
      new webpack.HashedModuleIdsPlugin(),
      // enable scope hoisting
    new webpack.optimize.ModuleConcatenationPlugin(),
    //       ,                 。
      new webpack.optimize.CommonsChunkPlugin({
       name: 'vendor',
       minChunks (module) {
        // 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
      new webpack.optimize.CommonsChunkPlugin({
       name: 'manifest',
       minChunks: Infinity
    }),
    //              , 
     new webpack.optimize.CommonsChunkPlugin({
       name: 'app',
       async: 'vendor-async',
       children: true,
       minChunks: 3
      }),
    //  ,                  dist  
      new CopyWebpackPlugin([
       {
        from: path.resolve(__dirname, '../static'),
        to: config.build.assetsSubDirectory,
        ignore: ['.*']
       }
      ])
     ]
    })
    
    if (config.build.productionGzip) {
     const CompressionWebpackPlugin = require('compression-webpack-plugin')
    
     webpackConfig.plugins.push(
      new CompressionWebpackPlugin({
       asset: '[path].gz[query]',
       algorithm: 'gzip',
       test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
       ),
       threshold: 10240,
       minRatio: 0.8
      })
     )
    }
    //     Content-Encoding          
    if (config.build.bundleAnalyzerReport) {
     const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
     webpackConfig.plugins.push(new BundleAnalyzerPlugin())
    }
    module.exports = webpackConfig
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기