webpack学习笔记(六)--source map、提取公共资源、tree shaking(摇树优化)

1,658 阅读3分钟

使用source map

关键字

  • eval:打包时,使用eval包裹模块代码
  • source map:产生.map文件,source map文件是分离开的
  • cheap:报错不能定位到列,不包含列信息
  • inline:将.map作为DataURI嵌入,不单独生成.map文件,内联进文件中
  • module:包含loader的sourcemap
  • webpack的配置:
module.exports = {
  ...
  mode:'none'//production:不生成source map
  devtool:'source-map'//eval,source-map,inline-source-map
}

source map 类型

不适合生产环境
  • eval:webpack生成的代码
  • cheap-eval-source-map: 经过loader转换后的代码(只能看到行)
  • cheap-module-eval-source-map:源代码(只能看到行)
  • eval-source-map: 源代码
  • inline-cheap-source-map:经过loader转换后的代码(只能看到行)
  • inline-cheap-module-source-map: 源代码(只能看到行)
  • inline-source-map: 源代码
适合生产环境
  • (none): 最终输出代码
  • cheap-source-map: 经过loader转换后的代码
  • cheap-module-source-map: 源代码
  • source-map:源代码
  • hidden-source-map: 源代码

提取公共资源

基础库分离

将react、react-dom基础包通过cdn(内容分发网络)引入,不打入bundle中

  • 1、安装:npm i html-webpack-externals-plugin -D
  • 2、webpack中添加配置
const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin')
module.exports = {
  plugins:[
    new HtmlWebpackExternalsPlugin({
          externals:[
            {
              module:'react',
              entry:'https://unpkg.com/react@16/umd/react.production.min.js',
              global:'React'
            },
            {
              module:'react-dom',
              entry:'https://unpkg.com/react-dom@16/umd/react-dom.production.min.js',
              global:'ReactDOM'
            }
          ]
        })
  ]
}
  • 3、页面中引用cdn的链接
      <script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
      <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script> 
    
  • 4、npm run build

    可以查看生成的js文件大小小很多

利用SplitChunksPlugin分割代码

webpack 默认会自动拆分代码块,条件:

  • 1、会被共享的代码或者来自node_modules文件夹中的modules
  • 2、大于30kb的代码块(压缩gz之前)
  • 3、加载chunks是的并行请求数量不超过5个
  • 4、加载初始页面时的并行请求数量不超过3个
默认配置
module.exports = {
  ...
  optimiztion: {
    splitChunks: {
      chunks:'async',//用来选择分割哪些代码块,可选值有:'all'(所有代码块),'async'(异步代码),'initial'(同步代码)
      minSize: 30000,//模块的最小体积
      maxSize: 0,
      minChunks: 1,//模块的最小被引用的次数
      maxAsyncRequests:5,//按需加载的最大并行请求数
      maxInitialRequests:3,//一个入口最大并行请求数
      automaticNameDelimiter:'~',//文件名的连接符
      automaticNameMaxLength: 30,
      name:true,
      cacheGroups: {//缓存组
        vendors:{
          test:/[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk:true
        }
      }
    }
  }
}
分离基础包
  • 1、先删除HtmlWebpackExternalsPlugin的配置和html中的引用
  • 2、webpack中添加配置
    module.exports = {
      //...
      optimization: {
        splitChunks: {
          cacheGroups: {
            commons: {
              test: /(react|react-dom)/,
              name: 'vendors',
              chunks: 'all'
            }
          }
        }
      },
    }
    
  • 3、HtmlWebpackPlugin中的chunks增加提取的jschunks:['vendors',name]
  • 4、npm run build
分离公共文件
  • 1、创建common公共文件index.js
  • 2、import common from '../../common'
  • 3、webpack中的添加配置
    module.exports = {
      //分离页面公共文件
      optimization: {
        splitChunks: {
          minSize:0,//引用模块大小 0:只要有引用符合要求就提取到commons文件中
          cacheGroups: {
            commons: {
              name: 'commons',
              chunks: 'all',
              minChunks: 2//最小引用次数为2次
            }
          }
        }
      },
    }
    
  • 4、npm run build

tree shaking(摇树优化)

  • webpack4中production :默认开启

没用的代码,构建时将删除掉(必须是es6的写法,commonjs不支持require不支持)

  • DCE

1、代码不会被执行,不可到达,如:

if(false){
  console.log('将不会被执行')
}

2、代码执行结果不会被用到

function aa(){
  return '结果没有别赋值给变量'
}

3、代码只会影响死变量(只写不读)