• 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~~

    (完)

  • 相关阅读:
    JS、LUA都可以开发移动应用
    正在融资中的快速移动应用开发平台
    赶快加入快速移动应用开发吧
    重新诠释移动应用开发
    快速开发移动应用的利器
    报表实施案例:某市利用大数据助力精准扶贫项目开展
    【新手速成】菜鸟如何在三天内完成系统开发
    全新Wijmo5中文学习指南正式上线
    SpreadJS 在 Angular2 中支持绑定哪些属性?
    【报表福利大放送】100余套报表模板免费下
  • 原文地址:https://www.cnblogs.com/zdping/p/13864032.html
Copyright © 2020-2023  润新知