webpack优化配置

一 HMR

1. webpack.config.js

const {resolve} = require('path')
const htmlPlugin = require('html-webpack-plugin')
const cssPlugin = require('mini-css-extract-plugin')
const cssCompress = require('optimize-css-assets-webpack-plugin')

/*
* HMR: hot module replacement 热模块替换
* 样式文件:可以使用HMR,因为style-loader内部实现了
* JS文件:默认不使用HMR,需要修改入口文件JS代码来监听其他JS文件的变化
*   且入口文件没有HMR功能,当入口文件改变,所有文件会被重新编译
* html文件:当开启HMR功能后,html文件改变不会进行重新编译
*   需在entry中加入html文件
*
* */

//设置nodejs环境变量
process.env.NODE_ENV = 'development'

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'js/build.js',
    path: resolve(__dirname, 'build')
  },
  module: {

    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
//优先执行
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
          fix: true
        }
      },
      {
        oneOf: [
          {
            test: /\.less$/,
            use: ['style-loader', 'css-loader', 'less-loader']
          },
          {
            test: /\.css$/,
            use: [cssPlugin.loader,
              'css-loader',
              {
                loader: 'postcss-loader',
                options: {
                  ident: 'postcss',
                  plugins: () => [
                    require('postcss-preset-env')()
                  ]
                }
              }
            ]
          },
          {
            test: /\.(jpg|png|gif)$/,
            loader: 'url-loader',
            options: {
              limit: 8 * 1024,
              name: '[hash:10].[ext]',
              esModule: false,
              outputPath: 'imgs'
            }
          },
          {
            test: /\.html$/,
            loader: 'html-loader',
          },
          {
            exclude: /\.(html|js|css|less|png|jpg|gif)$/,
            loader: 'file-loader',
            options: {
              name: '[hash:10].[ext]',
              outputPath: 'media'
            }
          },

          {
            test: /\.js$/,
            loader: 'babel-loader',
            exclude: /node_modules/,
            options: {
              presets: [
                [
                  '@babel/preset-env',
                  {
                    useBuiltIns: 'usage',
                    corejs: {
                      version: 3
                    },
                    targets: {
                      chrome: '60',
                      firefox: '60',
                      ie: '9',
                      safari: '10',
                      edge: '17'
                    }
                  }
                ]
              ]
            }
          }
        ]
      }

    ]
  },
  plugins: [
    new htmlPlugin({
      template: "./src/index.html",
//html压缩
      minify: {
        collapseWhitespace: true, //移除空格
        removeComments: true      //移除注释
      }
    }),
    new cssPlugin({
      filename: 'css/build.css'
    }),
    new cssCompress()
  ],
//生产环境下自动压缩js代码
  mode: 'production',
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true,
    port: 3000,
    open: true,
    hot: true,
    devtool: 'source-map'
  }
}



2. index.js

import './base.less';
import './index.css';

if(module.hot){ //module.hot为true说明开启了HMR功能
  module.hot.accept('./print.js', function(){
    //监听print.js文件的变化 一旦发生变化,其他模块不会重新打包,且执行后面的回调函数
    print()
  })
}

二 source-map

const {resolve} = require('path')
const htmlPlugin = require('html-webpack-plugin')
const cssPlugin = require('mini-css-extract-plugin')
const cssCompress = require('optimize-css-assets-webpack-plugin')

/*
* source-map 一种提供源代码到构建后代码映射技术,如果构建后代码出错了,通过映射可以追踪源代码错误的语句)
* source-map 外部
*   错误代码原因 和 源代码的错误位置
* hidden-source-map 外部
*   错误代码原因 和 不能追踪源代码的错误位置,只提示构建后代码的错误位置
* nosources-source-map 外部
*   错误代码原因 但没有任何源代码信息
* cheap-source-map 外部
*   错误代码原因 和 源代码的错误位置 精确到行
* cheap-module-source-map 外部
*   错误代码原因 和 源代码的错误位置
*   module会将loader的source map 加入
* inline-source-map 内联
*   只生成一个内敛source-map
*   错误代码原因 和 源代码的错误位置
* eval-source-map 内联
*   每个文件生成对面source-map,都在eval函数里
*   错误代码准确信息 和 源代码的错误位置
*
*   内联和外部的区别:1.外部生成了文件,内联没有 2.内联构建速度更快
*
* 开发环境建议用 eval-source-map / eval-cheap-module-source-map
* 生产环境建议用 source-map / cheap-module-source-map
*   如果要隐藏代码可以用 nosources-source-map / hidden-source-map
* * */

//设置nodejs环境变量
process.env.NODE_ENV = 'development'

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'js/build.js',
    path: resolve(__dirname, 'build')
  },
  module: {

    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
//优先执行
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
          fix: true
        }
      },
      {
        oneOf: [
          {
            test: /\.less$/,
            use: ['style-loader', 'css-loader', 'less-loader']
          },
          {
            test: /\.css$/,
            use: [cssPlugin.loader,
              'css-loader',
              {
                loader: 'postcss-loader',
                options: {
                  ident: 'postcss',
                  plugins: () => [
                    require('postcss-preset-env')()
                  ]
                }
              }
            ]
          },
          {
            test: /\.(jpg|png|gif)$/,
            loader: 'url-loader',
            options: {
              limit: 8 * 1024,
              name: '[hash:10].[ext]',
              esModule: false,
              outputPath: 'imgs'
            }
          },
          {
            test: /\.html$/,
            loader: 'html-loader',
          },
          {
            exclude: /\.(html|js|css|less|png|jpg|gif)$/,
            loader: 'file-loader',
            options: {
              name: '[hash:10].[ext]',
              outputPath: 'media'
            }
          },

          {
            test: /\.js$/,
            loader: 'babel-loader',
            exclude: /node_modules/,
            options: {
              presets: [
                [
                  '@babel/preset-env',
                  {
                    useBuiltIns: 'usage',
                    corejs: {
                      version: 3
                    },
                    targets: {
                      chrome: '60',
                      firefox: '60',
                      ie: '9',
                      safari: '10',
                      edge: '17'
                    }
                  }
                ]
              ]
            }
          }
        ]
      }

    ]
  },
  plugins: [
    new htmlPlugin({
      template: "./src/index.html",
//html压缩
      minify: {
        collapseWhitespace: true, //移除空格
        removeComments: true      //移除注释
      }
    }),
    new cssPlugin({
      filename: 'css/build.css'
    }),
    new cssCompress()
  ],
//生产环境下自动压缩js代码
  mode: 'production',
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true,
    port: 3000,
    open: true,
    hot: true,
    devtool: 'source-map'
  }
}



三 oneOf

const {resolve} = require('path')
const htmlPlugin = require('html-webpack-plugin')
const cssPlugin = require('mini-css-extract-plugin')
const cssCompress = require('optimize-css-assets-webpack-plugin')

//设置nodejs环境变量
process.env.NODE_ENV = 'development'

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'js/build.js',
    path: resolve(__dirname, 'build')
  },
  module: {

    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
//优先执行
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
          fix: true
        }
      },
      {
        //oneOf: 若多个配置有用到相同的loader,则只加载一个,减少资源消耗
        //但是oneOf中不能有两个配置处理同一种类型文件
        oneOf: [
          {
            test: /\.less$/,
            use: ['style-loader', 'css-loader', 'less-loader']
          },
          {
            test: /\.css$/,
            use: [cssPlugin.loader,
              'css-loader',
              {
                loader: 'postcss-loader',
                options: {
                  ident: 'postcss',
                  plugins: () => [
                    require('postcss-preset-env')()
                  ]
                }
              }
            ]
          },
          {
            test: /\.(jpg|png|gif)$/,
            loader: 'url-loader',
            options: {
              limit: 8 * 1024,
              name: '[hash:10].[ext]',
              esModule: false,
              outputPath: 'imgs'
            }
          },
          {
            test: /\.html$/,
            loader: 'html-loader',
          },
          {
            exclude: /\.(html|js|css|less|png|jpg|gif)$/,
            loader: 'file-loader',
            options: {
              name: '[hash:10].[ext]',
              outputPath: 'media'
            }
          },

          {
            test: /\.js$/,
            loader: 'babel-loader',
            exclude: /node_modules/,
            options: {
              presets: [
                [
                  '@babel/preset-env',
                  {
                    useBuiltIns: 'usage',
                    corejs: {
                      version: 3
                    },
                    targets: {
                      chrome: '60',
                      firefox: '60',
                      ie: '9',
                      safari: '10',
                      edge: '17'
                    }
                  }
                ]
              ]
            }
          }
        ]
      }

    ]
  },
  plugins: [
    new htmlPlugin({
      template: "./src/index.html",
//html压缩
      minify: {
        collapseWhitespace: true, //移除空格
        removeComments: true      //移除注释
      }
    }),
    new cssPlugin({
      filename: 'css/build.css'
    }),
    new cssCompress()
  ],
//生产环境下自动压缩js代码
  mode: 'production',
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true,
    port: 3000,
    open: true,
    hot: true,
    devtool: 'source-map'
  }
}

四 缓存

const {resolve} = require('path')
const htmlPlugin = require('html-webpack-plugin')
const cssPlugin = require('mini-css-extract-plugin')
const cssCompress = require('optimize-css-assets-webpack-plugin')

/*
* babel缓存 文件再次编译的时候会优先从缓存中取
*   cacheDirectory: true
* 文件资源缓存
*   hash: 每次webpack构建时会生成一个唯一的hash值
*     问题:js和css会同时使用同一个hash值,当只改变一个文件时,重新打包会使缓存失效
*   chunkhash:根据chunk生成的hash值,如果打包来源于同一个chunk,那么hash值就一样
*     问题:js和css的值还是一样的,因为css是在js中被引入的,所以同属于一个chunk
*   contenthash:根据文件内容生成hash值,不同文件hash值一定不一样
* */

//设置nodejs环境变量
process.env.NODE_ENV = 'development'

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'js/build.[contenthash:10].js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
//优先执行
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
          fix: true
        }
      },
      {
        oneOf: [
          {
            test: /\.less$/,
            use: ['style-loader', 'css-loader', 'less-loader']
          },
          {
            test: /\.css$/,
            use: [cssPlugin.loader,
              'css-loader',
              {
                loader: 'postcss-loader',
                options: {
                  ident: 'postcss',
                  plugins: () => [
                    require('postcss-preset-env')()
                  ]
                }
              }
            ]
          },
          {
            test: /\.(jpg|png|gif)$/,
            loader: 'url-loader',
            options: {
              limit: 8 * 1024,
              name: '[hash:10].[ext]',
              esModule: false,
              outputPath: 'imgs'
            }
          },
          {
            test: /\.html$/,
            loader: 'html-loader',
          },
          {
            exclude: /\.(html|js|css|less|png|jpg|gif)$/,
            loader: 'file-loader',
            options: {
              name: '[hash:10].[ext]',
              outputPath: 'media'
            }
          },

          {
            test: /\.js$/,
            loader: 'babel-loader',
            exclude: /node_modules/,
            options: {
              presets: [
                [
                  '@babel/preset-env',
                  {
                    useBuiltIns: 'usage',
                    corejs: {
                      version: 3
                    },
                    targets: {
                      chrome: '60',
                      firefox: '60',
                      ie: '9',
                      safari: '10',
                      edge: '17'
                    }
                  }
                ]
              ],
              cacheDirectory: true
            }
          }
        ]
      }

    ]
  },
  plugins: [
    new htmlPlugin({
      template: "./src/index.html",
//html压缩
      minify: {
        collapseWhitespace: true, //移除空格
        removeComments: true      //移除注释
      }
    }),
    new cssPlugin({
      filename: 'css/build.[contenthash:10].css'
    }),
    new cssCompress()
  ],
//生产环境下自动压缩js代码
  mode: 'production',
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true,
    port: 3000,
    open: true,
    hot: true,
    devtool: 'source-map'
  }
}

五 tree shaking

1. webpack.config.js配置

const {resolve} = require('path')
const htmlPlugin = require('html-webpack-plugin')
const cssPlugin = require('mini-css-extract-plugin')
const cssCompress = require('optimize-css-assets-webpack-plugin')

/*
* tree shaking: 去除无用代码
*   前提:1. 使用es6模块化 2.开启production环境
* package.json中的配置
*   "sideEffects": false 所有代码没有副作用
*     问题:可能会把css等直接引入但在js文件中没有使用的文件给抹去
*   "sideEffects": ["*.css"]    //css不被优化
* */

//设置nodejs环境变量
process.env.NODE_ENV = 'development'

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'js/build.[contenthash:10].js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
//优先执行
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
          fix: true
        }
      },
      {
        oneOf: [
          {
            test: /\.less$/,
            use: ['style-loader', 'css-loader', 'less-loader']
          },
          {
            test: /\.css$/,
            use: [cssPlugin.loader,
              'css-loader',
              {
                loader: 'postcss-loader',
                options: {
                  ident: 'postcss',
                  plugins: () => [
                    require('postcss-preset-env')()
                  ]
                }
              }
            ]
          },
          {
            test: /\.(jpg|png|gif)$/,
            loader: 'url-loader',
            options: {
              limit: 8 * 1024,
              name: '[hash:10].[ext]',
              esModule: false,
              outputPath: 'imgs'
            }
          },
          {
            test: /\.html$/,
            loader: 'html-loader',
          },
          {
            exclude: /\.(html|js|css|less|png|jpg|gif)$/,
            loader: 'file-loader',
            options: {
              name: '[hash:10].[ext]',
              outputPath: 'media'
            }
          },
          {
            test: /\.js$/,
            loader: 'babel-loader',
            exclude: /node_modules/,
            options: {
              presets: [
                [
                  '@babel/preset-env',
                  {
                    useBuiltIns: 'usage',
                    corejs: {
                      version: 3
                    },
                    targets: {
                      chrome: '60',
                      firefox: '60',
                      ie: '9',
                      safari: '10',
                      edge: '17'
                    }
                  }
                ]
              ],
              cacheDirectory: true
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new htmlPlugin({
      template: "./src/index.html",
//html压缩
      minify: {
        collapseWhitespace: true, //移除空格
        removeComments: true      //移除注释
      }
    }),
    new cssPlugin({
      filename: 'css/build.[contenthash:10].css'
    }),
    new cssCompress()
  ],
//生产环境下自动压缩js代码
  mode: 'production',
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true,
    port: 3000,
    open: true,
    hot: true,
    devtool: 'source-map'
  }
}

2. package.json配置

{
  "name": "web-pack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.8.7",
    "@babel/preset-env": "^7.8.7",
    "babel-loader": "^8.0.6",
    "core-js": "^3.6.4",
    "css-loader": "^3.4.2",
    "eslint": "^6.8.0",
    "eslint-config-airbnb-base": "^14.1.0",
    "eslint-loader": "^3.0.3",
    "eslint-plugin-import": "^2.20.1",
    "html-webpack-plugin": "^3.2.0",
    "less": "^3.11.1",
    "less-loader": "^5.0.0",
    "mini-css-extract-plugin": "^0.9.0",
    "optimize-css-assets-webpack-plugin": "^5.0.3",
    "postcss-loader": "^3.0.0",
    "postcss-preset-env": "^6.7.0",
    "style-loader": "^1.1.3",
    "webpack": "^4.42.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.10.3"
  },
  "dependencies": {
    "file-loader": "^6.0.0",
    "html-loader": "^0.5.5",
    "url-loader": "^4.0.0"
  },
  "browserslist": {
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  },
  "eslintConfig": {
    "extends": "airbnb-base"
  },
  "sideEffects": ["*.css"]
}

六 PWA

1. 安装workbox-webpack-plugin

npm i workbox-webpack-plugin -D

2. webpack.config.js

const {resolve} = require('path')
const htmlPlugin = require('html-webpack-plugin')
const cssPlugin = require('mini-css-extract-plugin')
const cssCompress = require('optimize-css-assets-webpack-plugin')
const workBox = require('workbox-webpack-plugin')

//设置nodejs环境变量
process.env.NODE_ENV = 'development'

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'js/build.[contenthash:10].js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
//优先执行
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
          fix: true
        }
      },
      {
        oneOf: [
          {
            test: /\.less$/,
            use: ['style-loader', 'css-loader', 'less-loader']
          },
          {
            test: /\.css$/,
            use: [cssPlugin.loader,
              'css-loader',
              {
                loader: 'postcss-loader',
                options: {
                  ident: 'postcss',
                  plugins: () => [
                    require('postcss-preset-env')()
                  ]
                }
              }
            ]
          },
          {
            test: /\.(jpg|png|gif)$/,
            loader: 'url-loader',
            options: {
              limit: 8 * 1024,
              name: '[hash:10].[ext]',
              esModule: false,
              outputPath: 'imgs'
            }
          },
          {
            test: /\.html$/,
            loader: 'html-loader',
          },
          {
            exclude: /\.(html|js|css|less|png|jpg|gif)$/,
            loader: 'file-loader',
            options: {
              name: '[hash:10].[ext]',
              outputPath: 'media'
            }
          },
          {
            test: /\.js$/,
            loader: 'babel-loader',
            exclude: /node_modules/,
            options: {
              presets: [
                [
                  '@babel/preset-env',
                  {
                    useBuiltIns: 'usage',
                    corejs: {
                      version: 3
                    },
                    targets: {
                      chrome: '60',
                      firefox: '60',
                      ie: '9',
                      safari: '10',
                      edge: '17'
                    }
                  }
                ]
              ],
              cacheDirectory: true
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new htmlPlugin({
      template: "./src/index.html",
//html压缩
      minify: {
        collapseWhitespace: true, //移除空格
        removeComments: true      //移除注释
      }
    }),
    new cssPlugin({
      filename: 'css/build.[contenthash:10].css'
    }),
    new cssCompress(),
    new workBox.GenerateSW({
      /*
      * 1. 帮助serviceworker快速启动
      * 2. 删除旧的 serviceworker
      * */
      clientsClaim: true,
      skipWaiting: true
    })
  ],
//生产环境下自动压缩js代码
  mode: 'production',
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true,
    port: 3000,
    open: true,
    hot: true,
    devtool: 'source-map'
  }
}

3. index.js

import './base.less';
import './index.css';

/* 1. eslint不认识 window navigator全局变量
      解决:在package.json中eslintConfig配置
   2. sw代码必须运行在服务器上
      npm i serve -g
      serve -s build 启动服务器,将build目录下所有资源作为静态资源暴露出去
*/
// 注册 serviceWorker 处理兼容性问题
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker
      .register('/service-worker.js')
      .then(() => {
        console.log('注册成功');
      })
      .catch(() => {
        console.log('注册失败');
      });
  });
}

4. package.json

{
  "name": "web-pack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.8.7",
    "@babel/preset-env": "^7.8.7",
    "babel-loader": "^8.0.6",
    "core-js": "^3.6.4",
    "css-loader": "^3.4.2",
    "eslint": "^6.8.0",
    "eslint-config-airbnb-base": "^14.1.0",
    "eslint-loader": "^3.0.3",
    "eslint-plugin-import": "^2.20.1",
    "html-webpack-plugin": "^3.2.0",
    "less": "^3.11.1",
    "less-loader": "^5.0.0",
    "mini-css-extract-plugin": "^0.9.0",
    "optimize-css-assets-webpack-plugin": "^5.0.3",
    "postcss-loader": "^3.0.0",
    "postcss-preset-env": "^6.7.0",
    "style-loader": "^1.1.3",
    "webpack": "^4.42.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.10.3",
    "workbox-webpack-plugin": "^5.1.1"
  },
  "dependencies": {
    "file-loader": "^6.0.0",
    "html-loader": "^0.5.5",
    "url-loader": "^4.0.0"
  },
  "browserslist": {
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  },
  "eslintConfig": {
    "extends": "airbnb-base",
    "env": {
      "browser": true
    }
  },
  "sideEffects": [
    "*.css"
  ]
}

七 多进程打包

1. 安装thread-loader

npm i thread-loader -D

2. 配置

const {resolve} = require('path')
const htmlPlugin = require('html-webpack-plugin')
const cssPlugin = require('mini-css-extract-plugin')
const cssCompress = require('optimize-css-assets-webpack-plugin')
const workBox = require('workbox-webpack-plugin')


//设置nodejs环境变量
process.env.NODE_ENV = 'development'

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'js/build.[contenthash:10].js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
//优先执行
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
          fix: true
        }
      },
      {
        oneOf: [
          {
            test: /\.less$/,
            use: ['style-loader', 'css-loader', 'less-loader']
          },
          {
            test: /\.css$/,
            use: [cssPlugin.loader,
              'css-loader',
              {
                loader: 'postcss-loader',
                options: {
                  ident: 'postcss',
                  plugins: () => [
                    require('postcss-preset-env')()
                  ]
                }
              }
            ]
          },
          {
            test: /\.(jpg|png|gif)$/,
            loader: 'url-loader',
            options: {
              limit: 8 * 1024,
              name: '[hash:10].[ext]',
              esModule: false,
              outputPath: 'imgs'
            }
          },
          {
            test: /\.html$/,
            loader: 'html-loader',
          },
          {
            exclude: /\.(html|js|css|less|png|jpg|gif)$/,
            loader: 'file-loader',
            options: {
              name: '[hash:10].[ext]',
              outputPath: 'media'
            }
          },
          {
            test: /\.js$/,
            exclude: /node_modules/,
            /*开启多进程打包,但是要注意,一般给打包时间很长的过程才启用多线程
            * 因为启动进程大概600ms,进程通信也要开销*/
            use:[
              'thread-loader',
              {
                loader: 'babel-loader',
                options: {
                  presets: [
                    [
                      '@babel/preset-env',
                      {
                        useBuiltIns: 'usage',
                        corejs: {
                          version: 3
                        },
                        targets: {
                          chrome: '60',
                          firefox: '60',
                          ie: '9',
                          safari: '10',
                          edge: '17'
                        }
                      }
                    ]
                  ],
                  cacheDirectory: true
                }
              }
            ],
          }
        ]
      }
    ]
  },
  plugins: [
    new htmlPlugin({
      template: "./src/index.html",
//html压缩
      minify: {
        collapseWhitespace: true, //移除空格
        removeComments: true      //移除注释
      }
    }),
    new cssPlugin({
      filename: 'css/build.[contenthash:10].css'
    }),
    new cssCompress(),
    new workBox.GenerateSW({
      clientsClaim: true,
      skipWaiting: true
    })
  ],
//生产环境下自动压缩js代码
  mode: 'production',
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true,
    port: 3000,
    open: true,
    hot: true,
    devtool: 'source-map'
  }
}

八 externals

const {resolve} = require('path')
const htmlPlugin = require('html-webpack-plugin')
const cssPlugin = require('mini-css-extract-plugin')
const cssCompress = require('optimize-css-assets-webpack-plugin')
const workBox = require('workbox-webpack-plugin')


//设置nodejs环境变量
process.env.NODE_ENV = 'development'

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'js/build.[contenthash:10].js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
//优先执行
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
          fix: true
        }
      },
      {
        oneOf: [
          {
            test: /\.less$/,
            use: ['style-loader', 'css-loader', 'less-loader']
          },
          {
            test: /\.css$/,
            use: [cssPlugin.loader,
              'css-loader',
              {
                loader: 'postcss-loader',
                options: {
                  ident: 'postcss',
                  plugins: () => [
                    require('postcss-preset-env')()
                  ]
                }
              }
            ]
          },
          {
            test: /\.(jpg|png|gif)$/,
            loader: 'url-loader',
            options: {
              limit: 8 * 1024,
              name: '[hash:10].[ext]',
              esModule: false,
              outputPath: 'imgs'
            }
          },
          {
            test: /\.html$/,
            loader: 'html-loader',
          },
          {
            exclude: /\.(html|js|css|less|png|jpg|gif)$/,
            loader: 'file-loader',
            options: {
              name: '[hash:10].[ext]',
              outputPath: 'media'
            }
          },
          {
            test: /\.js$/,
            exclude: /node_modules/,
            /*开启多进程打包,但是要注意,一般给打包时间很长的过程才启用多线程
            * 因为启动进程大概600ms,进程通信也要开销*/
            use:[
              'thread-loader',
              {
                loader: 'babel-loader',
                options: {
                  presets: [
                    [
                      '@babel/preset-env',
                      {
                        useBuiltIns: 'usage',
                        corejs: {
                          version: 3
                        },
                        targets: {
                          chrome: '60',
                          firefox: '60',
                          ie: '9',
                          safari: '10',
                          edge: '17'
                        }
                      }
                    ]
                  ],
                  cacheDirectory: true
                }
              }
            ],
          }
        ]
      }
    ]
  },
  plugins: [
    new htmlPlugin({
      template: "./src/index.html",
//html压缩
      minify: {
        collapseWhitespace: true, //移除空格
        removeComments: true      //移除注释
      }
    }),
    new cssPlugin({
      filename: 'css/build.[contenthash:10].css'
    }),
    new cssCompress(),
    new workBox.GenerateSW({
      clientsClaim: true,
      skipWaiting: true
    })
  ],
//生产环境下自动压缩js代码
  mode: 'production',
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true,
    port: 3000,
    open: true,
    hot: true,
    devtool: 'source-map'
  },
  externals: {
//拒绝jQuery被打包进来 但是需要手动在html文件中进行引入
    jquery: 'jQuery'
  }
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值