• webpack五探-tree shaking、模式、代码分割


    Tree Shaking:
    当我们写了好几个方法,但是实际上只用到了一个,那么我们需要在打包的时候剔除没有用到的代码,这就是tree shaking的作用,tree shaking只支持ES module的语法,即import、export这种,而不支持require这种commonJS的语法。
    在webpack.config.js中与entry、plugins等同级:

    optimization:{
        usedExports:true
    }

    以上配置在开发环境下需要配置,在生产环境下默认已经存在,不需要配置。
    package.json增加配置:意思是对所有模块都进行tree shaking

    "sideEffects":false

    但是有时候我们引入了一些类似css文件,如:
    import './style.css';
    虽然它没有导出任何内容,但是我们也不希望被剔除,所以需要排除:

    "sideEffects":["*.css"]

    development和production模式:
    在开发环境中sourceMap是非常全的,代码不需要压缩
    我们可以分成两个文件:webpack.dev.jswebpack.prod.js,分别指代开发模式和生产模式,在生产模式下需要修改配置:

    mode:'production',
    devtool: 'cheap-module-source-map'

    删除:

    new webpack.HotModuleReplacementPlugin(),
    optimization:{
        usedExports:true
    },
    devServer: {
        contentBase: './dist',
        open: true,
        hot: true,
        hotOnly: true
    }

    这个时候两个文件会存在很多相同的内容,所以我们可以在创建一个webpack.common.js放置相同代码。
    拆分以后需要在两个文件中引入webpack.common.js才能正常使用,需要安装:
    npm install webpack-merge -D
    在两个文件中引入:

    const merge=require('webpack-merge');
    const commonConfig=require('./webpack.common');

    最后导出:

    module.exports=merge(commonConfig,devConfig);

    生产环境同理

    Code Splitting(代码分割):
    假设我们要引入lodash:
    npm install lodash --save
    当我们直接在业务中引入loadash时(import _ from 'lodash');会打包在同一个js中,假设loadsh大小为1M,我们的业务代码也是1M,那么我们打包生成的代码就是2M,而当我们修改代码时又会重新生成2M的js文件
    // 旧
    // 首次访问页面需要加载main.js(2M)
    // 修改业务代码又要加载main.js(2M)

    import _ from 'lodash';
    console.log(_.join(['a','b','c']));

    // 新
    // 增加一个入口文件,将公共组件lodash.js(1M)分割出来,
    // 当业务代码发生改变时,只需要重新加载main.js(1M)即可
    lodash.js:

    import _ from 'lodash';
    window._=_;

    webpack.common.js:

    entry: {
        lodash:'./src/lodash.js',
        main: './src/index.js'
    },

    以上的代码分割是人为的,不够智能,webpack中有一些配置、插件可以让代码分割变得更加简单

    optimization:{
        splitChunks:{
            chunks:'all'
        }
    },

    // 以上为同步代码分割
    // 下面是异步代码分割:
    安装:
    npm install babel-plugin-dynamic-import-webpack -D
    在.babelrc中:

    "plugins":["dynamic-import-webpack"]

    就可以以异步形式引入:

    import('lodash').then(({default:_})=>{})

    // 总结:代码分割与webpack无关,webpack中实现代码分割有2中方式
    // 1.同步分割:只需要在webpack.common.js中做optimization配置即可
    // 2.异步分割(import):无需要任何配置,会自动进行代码分割

    摘要:以上 babel-plugin-dynamic-import-webpack 这个插件不是官方提供的插件,官方提供有一个代码分割的插件

    需要删除:
    .babelrc中:"plugins":["dynamic-import-webpack"]
    package.json中:"babel-plugin-dynamic-import-webpack": "^1.1.0",
    安装:
    npm install --save-dev @babel/plugin-syntax-dynamic-import
    在.babelrc中使用该插件:"plugins": ["@babel/plugin-syntax-dynamic-import"]
    重新打包会发现生成0.js,那么我们要如何使文件名为指定名字呢?以lodash为例:
    import(/* webpackChunkName:"lodash" */'lodash').then(({default:_})=>{});
    只需在前面加上注释即可,会生成名为vendors~lodash.js的文件,而不是原来的0.js

    如果想要生成lodash.js,需要修改webpack.common.js:

    optimization:{
        splitChunks:{
            chunks:'all',
            cacheGroups: {
                vendors: false,
                default: false
            }
        }
    },

    重新打包就会看到生成的事lodash.js。
    由此可以得出:无论是同步还是异步的代码分割,都需要使用SplitChunksPlugin这个插件

    讲解splitChunks,默认为:

    splitChunks: {
        chunks: "async", // 只适用于异步,如果只对同步的也进行分割,需要设置为"initial",若需要对两者都进行分割,需要设置为'all'
        minSize: 30000, // 如果代码大于30000B(30KB)才做代码分割,小于此则不做代码分割
        // maxSize:0,  // 一般不配置,假如设置成50000(50kb),而引入的库为1MB,则会尝试分成20个,一般也不会成功,所以不配置
        minChunks: 1,   // 被引用多少次的时候才进行分割
        maxAsyncRequests: 5,    // 默认就好
        maxInitialRequests: 3,  // 默认就好
        automaticNameDelimiter: '~',    // 文件生成连接符
        name: true,
        cacheGroups: {  // 缓存组-同步会走到这里,假设我们同时引入lodash和jquery,则会先缓存,然后打包到一起
            vendors: {
                test: /[\/]node_modules[\/]/, // 如果是node_modules下面的库,则统一分割到vendors.js
                priority: -10,  // 优先级,值越大,优先级越高
                filename:'vendors.js'
            },
        default: {
                minChunks: 2,
                priority: -20,
                reuseExistingChunk: true    // 如果一个模块已经被打包过了,再次发现需要打包的时候就会忽略这个模块
            }
        }
    }
  • 相关阅读:
    函数式编程
    橡皮筋功能
    socket
    git命令补充说明
    参考接口文档完成的json数据
    接口文档怎么写
    使用json-server创建mock数据
    proxy服务器代理
    Cannot read property 'setState' of undefined错误分析
    使用ref报错,addComponentAsRefTo(...): Only a ReactOwner can have refs.
  • 原文地址:https://www.cnblogs.com/jingouli/p/12255825.html
Copyright © 2020-2023  润新知