zoukankan      html  css  js  c++  java
  • webpack5文档解析(下)

    声明:所有的文章demo都在我的仓库

    代码分离

    代码分离的有点在于:

    1. 切割代码,生成不同的打包文件,按需加载这些文件。
    2. 每个bundle的体积更小
    3. 控制外部资源的加载顺序

    常用的方法有:

    1. 入口起点:使用入口entry手动分离
    2. 防止重复:使用SplitChunksPlugin去重和分离chunk
    3. 动态导入:通过模块的内联函数调用分离的代码

    入口起点

    新增另一个文件another-module.js文件,并在webpack.config.js中进行配置。

    entry:{//打包入口
        index:'./src/index.js',
        another:'./src/another-module.js'
    },
    

    进行打包后,结果正常。

    优点:常用常规的写法。

    缺点:1.如果有相同的模块,不会去重,还是会在每个bundle中被重复的引用。2.不能将核心代码进行分割

    防止重复

    入口依赖

    配置dependOn选项,可以在多个chunk之间进行共享模块。

    SplitChunkPlugin

    为了解决多个bundle引入相同模块的问题,引入这个模块进行去重。

    SplitChunkPlugin将公共的模块引入到已有的入口中,或者提取到新的chunk。

    相关配置如下:

    //webpack.config.js
    optimization:{
        splitChunks:{
            chunks:'all'
        }
    },
    

    SplitChunkPlugin创建了新的chunk,如下图所示,shared.bundle.js。将我其他页面所使用的js引入的lodash模块引入这个文件中。

    *** 以上代码在webpack-demo5

    缓存

    通常部署文件是将webpack打包出来的/dist文件,部署到server上,客户端通过访问server的网站及资源。

    由于客户端访问server时,非常耗时和耗流量,于是浏览器采用缓存技术,可以直接从缓存中获取相关的内容,降低了请求的速度和流量。但是这也有一个缺点:如果文件名跟之前的一致,浏览器会认为这个文件没有做修改,还是会从缓存中获取相关内容。

    我们想要的现象是:文件没做修改时,浏览器从缓存中获取,文件修改了,重新获取。

    输出文件的文件名

    webpack提供了一个substitution(可替换的模版字符串)的方式,通过带括号字符串来模版化文件名。其中的[contenthash]是根据资源内容创建唯一的hash。当资源内容变化时,[contenthash]也会发生变化。

    相关配置如下:

    entry:'./src/index.js',
    output:{//打包出口
        filename:"[name].[contenthash].js",//打包后的文件名称
        path:path.resolve(__dirname,'dist')//路径
    }, 
    

    使用contenthash,将内容变化直接反应打包输出文件的变化。

    文件不做修改,再次运行npm run build时,文档描述如下:

    在我的实际操作中,我的打包文件是不变的。

    第一次:

    第二次:

    可能跟webpack版本的关系所致。。。

    模块的概念

    runtime:每个模块的加载和模块的解析逻辑。

    manifest:解析和映射模块之间的联系

    提取引导模版

    runtime代码,提取到一个单独的chunk中。optimization.runtimeChunk:'single'表示为所有的chunk创建一个runtime bundle

    代码如下:

    optimization:{
        runtimeChunk:'single'
    },
    

    将所有的第三方库,如lodash/react等提取到单独的vendor chunk文件中。由于这些第三方库不会去频繁的修改源代码,所以可以让更少的向server发请求。

    配置如下:

    const path=require('path');
    const {CleanWebpackPlugin}=require('clean-webpack-plugin')
    const HtmlWebpackPlugin=require('html-webpack-plugin')
    
    module.exports={
        mode:'development',
        entry:'./src/index.js',
        output:{//打包出口
            filename:"[name].[contenthash].js",//打包后的文件名称
            path:path.resolve(__dirname,'dist')//路径
        }, 
        devtool: 'inline-source-map',
        devServer:{
            contentBase:'./dist'
        },
        optimization:{
            runtimeChunk:'single',
            splitChunks:{
                cacheGroups:{
                    vendor:{
                        test:/[\/]node_modules[\/]/,
                        name:'vendor',
                        chunks:'all'
                    }
                }
            }
        },
        plugins:[
            new CleanWebpackPlugin({
                cleanStaleWebpackAssets:false
            }),
            new HtmlWebpackPlugin({
                title:'管理输出'
            })
        ]
    }
    

    结果会出现一个带有vendor的文件。

    main文件里,不再含有来自node_modulevendor代码,而且体积也减少了。

    模块标识符

    新增print模块,并在index中进行引入,最终打包的结果跟之前比较结果如下:

    我本地打包只有main的文件进行了变化----符合预期

    然而官网上展示的例子是不一样,引出了需要引入optimization.moduleIds:'hashed'---苦笑不得

    *** 以上代码在webpack-demo6

    环境变量

    可以在package.json中配置相关的命令行,可以快速的执行开发环境生产环境

    "scripts": {
        "test": "echo "Error: no test specified" && exit 1",
        "build": "webpack",
        "start": "webpack serve --env development"
    },
    

    表示执行development环境。

    模块热替换(HMR)

    模块热替换(HMR--hot module replacement):在程序运行过程中,若有替换/添加/删除模块,只更新修改的部分,不需要更新整个页面。

    此功能暂不支持生产环境。

    代码配置如下:

    devServer:{
        contentBase:'./dist',
        hot:true
    },
    

    在index页面加入代码

    if(module.hot){
      module.hot.accept('./print.js',function(){
        console.log('update the module1');
        Print()
      })
    }
    

    注意:执行时使用npm run start,启动服务,可查看热更替。

    *** 以上代码在webpack-demo7

    模块热更替跟热更新是两回事。模块热更新是指修改了某个部分代码,不会刷新页面,而是在页面更新这个模块。热更新是指及时刷新页面。

    Tree shaking

    概念

    是指在打包的时候,剔除没有用到的代码。

    但是只支持ES module的import和export用法。

    实践

    打包过程分成3部分:

    1. import会被打包成/* harmony import */做前缀,表明这段是import进来的
    2. export会被打包成/* harmony export */做前缀,表明这段是export
    3. 纯函数,会被打包成/*#__PURE__*/,表明这个函数是纯函数,可以被tree shaking

    代码如下:

    package.json

    "name": "webpack-demo8",
    "sideEffects":false,
    

    webpack.config.js

    optimization:{
        usedExports:true
    }
    

    *** 以上代码在webpack-demo8

    我的仓库地址,github,欢迎star~~

    (完)

  • 相关阅读:
    Why Choose Jetty?
    Jetty 的工作原理以及与 Tomcat 的比较
    Tomcat设计模式
    Servlet 工作原理解析
    Tomcat 系统架构
    spring boot 打包方式 spring boot 整合mybaits REST services
    wireshark udp 序列号 User Datagram Protocol UDP
    Maven 的聚合(多模块)和 Parent 继承
    缓存策略 半自动化就是mybaitis只支持数据库查出的数据映射到pojo类上,而实体到数据库的映射需要自己编写sql语句实现,相较于hibernate这种完全自动化的框架我更喜欢mybatis
    Mybatis解决sql中like通配符模糊匹配 构造方法覆盖 mybits 增删改
  • 原文地址:https://www.cnblogs.com/zdping/p/13864032.html
Copyright © 2011-2022 走看看