1. @babel/core
  2. babel-loader
  3. @babel/preset-env
  4. @babel/preset-react
  5. @babel/plugin-proposal-decorators { legacy: true }
  6. @babel/plugin-proposal-class-properties { loose: true }
{
    test: /\.js$/,
  loader: 'eslint-loader',
  enforce: 'pre',
  options:{ fix: true },
  exclude: /node_modules/
}

loader 分为四种:pre normal inline post 优先级从前至后,eslint-loader 使用了 enforce: ‘pre’

.eslint.js

module.exports = {
    // root: true,
  extends: 'airbnb',
  parser: 'babel-eslint',
  parserOptions: {
        sourceType: 'module',
    ecmaVersion: 2015
  },
  env: {
      browser: true,
  },
  rules: {
      indent: 'off',
    quotes: 'off',
    'no-console': 'error',
    'linebreak-style': 'off'
  }
}

eslint规范:eslint-config-airbnb

换行符不同的操作系统不一样:
windows: \r\n
linux: \n
mac: \r

cheap:只包含行不包含列
devtool: ‘cheap-module-source-map’ 行 + babel 映射
devtool: ‘source-map’ 行 + 列 + babel 映射

let a = 1;
let b = 2;
let c = 3;
console.log(a, b, c, d);
source-map 会定义到哪个列出错了,但是 cheap-module-source-map 是定义不到的

console.log('a');
eval('console.log("a")');

这两者有什么区别?
eval 方便缓存,拥有最高的速度。

比如一个模块打包出来的源码是字符串,跟老的一比较是相同的,就直接使用老的 sourcemap 文件了

开发环境用: eval-source-map
测试环境用: source-map-dev-tool-plugin

const FileManagerPlugin = require(filemanager-webpack-plugin');
const webpack = require('webpack');

plugins: [
  new webpack.SourceMapDevToolPlugin({
      filename: '[file].map',
    append: `\n//# sourceMappingURL=http://127.0.0.1:8080/[url]`
  }),
    new FileManagerPlugin({
      events: {
        onEnd: {
          copy: [
          {
              source: './dist/*.map',
            destination: path.resolve('maps')
          }
        ],
        delete: ['./dist/*.map']
      },
    }
  })
]

好处是:本地可以调试,其他环境调试不了,可以防止代码泄漏

线上环境最佳实践:hidden-source-map + FileManagerPlugin
手动映射:

  1. Enables javascript source maps
  2. sources 下找到文件,右键 -> Add source map

提取三方类库

  1. webpack.ProviderPlugin, 缺点:window._ 全局是访问不到的
  2. expose-loader
  3. externals => html-webpack-externals-plugin
{
    test: require.resolve('lodash'),
  loader: 'expose-loader',
  options: {
      exposes: {
        globalName: '_',
      override: true
    } 
  }
}

require('expose-loader?exposes=_!lodash')

只想找模块路径,而不想执行和加载的话,执行 require.resolve('lodash')
html 中放入脚本
<script defer src="jquery.cdn"></script>

// 外部依赖
externals: {
  lodash: '_',
    jquery: 'jQuery'
}

let jQuery = require('jquery');
externals 中有时,就不会打包 jquery 了,而是从 window.jquery 上取

css 提取

new MiniCssExtractPlugin({
    filename: 'style/[name].css'
})

图片等资源加目录
url-loader
outputPath: 'images',
publicPath: './images'
  1. 使用 MiniCssExtractPlugin 提取 css
  2. 修改 css 和图片的输出文件目录

不要在 html 中引入图片,html-with-image 出问题了导致很多线上环境问题,目前只在 js 和 css 中引入图片
**

contentHash 实现思路:
require('crypto').createHash('md5').update('entry1')...update('....').digest('hex')

chunkhash 实现思路:
.update 只关联本条 chunk 上的文件