webpack代码分割之import()

webpack 性能优化方案 - 代码分离(分包) 代码分离概念、Optimization、Prefetch & Preload、CDN 阅读详情

简介:代码分割是webpack最大的一个特点,通过这个特点可以将你的代码切割进多个bundles里面,从而从而可以进行按需加载或者并行加载,可以实现更小的bundle和控制资源加载的优先级。

在说代码分割之前,我们先来了解几个概念:

1、bundles:bundles是指webpack打包后文件的统称,单一入口打包出来就只有一个文件,图片,字体文件等其他格式的文件也会被打包进这个bundle文件以base64的形式存在。但是实际开发中我们往往不会这么做,这样会打包出来一个很大的js文件,缺点不必多说,首先是第一次加载时会将所有资源都加载进来,造成首次加载白屏时间过长,第二是无法利用浏览器的并行加载,使加载时间过长,第三是会加载一些可能用不上的资源,造成带宽浪费。

2、chunk:chunk的意思是代码块,一个bundle由一个或者多个chunk组成,一个chunk由一个或多个module组成,chunk是进行代码切割的基础。对于bundle与chunk的之间的关系,webpack打包后的结果拆分成多个代码块,我们称之为chunk,这些chunk是bundles中的一员,因此也可以称之为bundle,就像有一瓶水,我们把它倒进几个杯子,一瓶水就相当于这里的bundles,一杯水就相当于chunk。

3、module:模块,我觉得这与我们项目中架构的模块有所不同,webpack中的模块即文件,每个文件都被看做一个模块。打个比方,假如我们有一个登录模块,里面包含了js,css,img等,在抽象概念中,我们将这些文件抽象地统称为一个模块,即登录模块,而webpack眼中则不同,它是一个文件就是一个模块,即以物理文件的形式划分模块。模块是进行代码分割的最小单位,也就说,我们不能对一个moudle进行更加颗粒化分割,即使这个文件很大。打个比方,现在有一个第三方库,这个库有1M,我们不可能将这个库分割成两个512KB的bundle。当然这得看库的设计者怎么设计打包后的文件了,如果此库被打包成一个文件,我们是无法分割的,比如jquery。如果像是element-ui,库本身对每个组件进行了单独的打包,并不是将所有组件打包进一个文件,所以我们可以进行按需加载。当然对于一些单个较大的文件,我们还有其它优化方式,比如混淆压缩,tree-shaking等。

webpack中代码分割的方式,通常有如下三种:

1、Entry Points:通过配置入口文件来进行分割,这是最简单和最直接的方式,但是这种方式有一定缺点,可能造成代码重复打包,本文讨论的是另一种方式,本文不做讨论。

2、Prevent Duplication: 使用splitChunksPlugin来进行公共代码提取。

3、Dynamic Imports:通过动态代码加载来分割代码,使用import()方法。

调用import() 之处,被作为分离的模块起点,意思是,被请求的模块和它引用的所有子模块,会分离到一个单独的 chunk 中。import方法依赖于Promise,如果需要在低版本浏览器使用,需要进行polyfill。

import的使用

//a.js
import('./b.js').then(b => {
    //doSomething
})

import 规范不允许控制模块的名称或其他属性,因为 "chunks" 只是 webpack 中的一个概念,但是我们可以通过注释接收一些特殊的参数,而无须破坏规定:

webpackChunkName:手动指定模块的名称

webpackMode:指定webpack以什么模式解析动态导入

  • lazy:默认值,为每个import()导入的模块生成一个可延迟加载的chunk
  • lazy-once:生成N个可以延迟加载的chunk,这个模式只能用于部分动态语句中有意义,比如import(`./util/${tool}.js`),webpack会将util下的每个js文件分别打包成一个单独的chunk。
//index.js
let util = 'a'
import(`./util/${util}.js`).then(res => {})


//util/a.js
export function add() {
    console.log('add')
}

//util/b.js
export const arr = [1, 2, 3]

打包后的目录结构如下

我们可以看到,除了生成一个主bundle(index.js),还生成了1.js和2.js,分别对应a.js和b.js的chunk。

  • eager:这种模式不会生成额外的chunk,所有模块都被当前chunk引入,不会有额外的网络请求。和静态导入相对比,在调用模块之前,该模块不会被执行。(静态导入第一回执行模块代码,ES Module属于静态导入,commonjs的require属于动态导入)
  • weak:尝试加载模块,如果该模块函数已经以其他方式加载(即,另一个 chunk 导入过此模块,或包含模块的脚本被加载)。仍然会返回 Promise,但是只有在客户端上已经有该 chunk 时才成功解析。如果该模块不可用,Promise 将会是 rejected 状态,并且网络请求永远不会执行。当需要的 chunks 始终在(嵌入在页面中的)初始请求中手动提供,而不是在应用程序导航在最初没有提供的模块导入的情况触发,这对于通用渲染(SSR)是非常有用的。(这个还不没使用过)

注意事项:

  • import()不支持完全动态语句,例如import(util),因为webpack 至少需要一些文件的路径信息,而util可能是任何一个路径,webpack不可能将所有模块都打包出来一个chunk。
  • 一般我们使用import()动态导入的模块,就不要再在其他模块静态引入此模块了,因为webpack分割chunk时,模块会被打包进静态导入它的chunk中,这样会造成无法分割chunk或者代码重复打包。
//index.js
import('./util/a')
import('./util/b')

//util/a.js
import { arr } from './b'
export function add() {
    console.log('add' + arr)
}

//util/b.js
export const arr = [1, 2, 3]

上面代码打包结果:

乍一看,发现并没问题,但是当我们打开打包后的文件,b模块被打包进了1.js,也就是a模块拆分出来的chunk里面

//1.js
;(window['webpackJsonp'] = window['webpackJsonp'] || []).push([
    [1, 2],
    [
        ,
        function(module, __webpack_exports__, __webpack_require__) {
            'use strict'
            __webpack_require__.r(__webpack_exports__)
            /* harmony export (binding) */
            __webpack_require__.d(__webpack_exports__, 'arr', function() {
                return arr
            })
            const arr = [1, 2, 3]
        },
        function(module, __webpack_exports__, __webpack_require__) {
            'use strict'
            __webpack_require__.r(__webpack_exports__)
            /* harmony export (binding) */

            __webpack_require__.d(__webpack_exports__, 'add', function() {
                return add
            })
            /* harmony import */
            var _b__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1)
            function add() {
                console.log('add' + _b__WEBPACK_IMPORTED_MODULE_0__['arr'])
            }
        }
    ]
])

然后我们查看2.js

//2.js
;(window['webpackJsonp'] = window['webpackJsonp'] || []).push([
    [2],
    [
        ,
        function(module, __webpack_exports__, __webpack_require__) {
            'use strict'
            __webpack_require__.r(__webpack_exports__)
            /* harmony export (binding) */
            __webpack_require__.d(__webpack_exports__, 'arr', function() {
                return arr
            })
            const arr = [1, 2, 3]
        }
    ]
])

然后我们发现2.js就是b模块,这样b模块就被重复打包了。

再来看另一种情况

//index.js
import { add } from './util/a'
import { arr } from './util/b'
add()

//util/a.js
export function add() {
    console.log('add' + arr)
}
import('./b')

//util/b.js
export const arr = [1, 2, 3]

此时打包结果如下,并没有生成额外的chunk。

总结:webpack在处理模块时,从入口文件开始,如果遇到静态导入的模块,则打包进当前chunk,如果遇到动态导入,则判断当前chunk是否已经包含此模块,如果已经包含,则不会生成额外的chunk,如果没有则生成新的chunk。在处理静态导入时,不管有没有此模块的chunk,都会将动态模块打包进当前chunk。

  • 关于webpackChunkName,默认使用自增长得chunkId,如果多个模块使用import()动态引入此模块,其chunk名按照深度遍历优先的module命名来,如果最深的那层没有指定,则为第二深的,依次类推,都没有指定则使用自增id。

 

webpack中分割代码的三种方式 文章目录entry - 配置多入口、多页面splitChunks - 智能抽取公共代码dynamic-import - 按需动态加载tips - 踩坑小提示避免过度优化!结局 官网教程:code-splitting 最近在开发一个新的功能,需要在某一条件下引入新包,而之前的场景则完全不需要。这种情况下,动态加载+代码分割正可以派上用场。在动手之前,先看看官网是怎么说的吧。 entry - 配置多入... 阅读详情

相关推荐

Harmony import和export

Harmony import、export和default的使用

海阔天空 1393

Webpack--动态 import 原理及源码分析

在平时的开发中,我们经常使用 import()实现代码分割和懒加载。在低版本的浏览器中并不支持动态 import(),那 webpack 是如何实现 import() polyfill 的?

欢迎朋友,我是一名十多年开发经验的新手,希望多多指教。 1230

在Kintex-7 FPGA上实现皮秒级时间测量:手把手教你搭建CARRY4进位链TDC(附源码与约束)

本文详细介绍了在Kintex-7 FPGA上利用CARRY4进位链实现皮秒级时间测量(TDC)的完整方案。从CARRY4的物理特性分析到硬件架构设计,再到校准方法与精度提升技巧,手把手教你构建测量精度达53ps的TDC系统,并附源码与约束文件,助力激光雷达、高能物理等精密计时应用开发。

weixin_42550052的博客 444

export default用法_彻底理解JavaScript ES6中的import和export

0、前言前端工程,在最早的时候是没有模块的概念的。随着前端工程的发展,前端开发也越来越规范化,更像是软件工程了。那么随之而来的,为了解决工程化的问题,就引入了模块的概念。但是在早期,因为ecmascript原本是没有模块语法的,所以采用的都是社区的各种版本协议,其中影响最深的,就是nodejs使用的CommonJS规范 。当模块化的概念越来越重要的时候,在es6中,引入了模块的语法:import ...

weixin_39941732的博客 2248

AI工具如何提升产品经理工作效率

AI工具在现代产品管理中扮演着越来越重要的角色,从需求挖掘到原型设计再到交付物制作,AI技术正在重塑产品经理的工作流程。通过自然语言处理(NLP)和机器学习(ML)技术,AI工具能够自动化处理大量重复性任务,如用户访谈转录、竞品分析、原型生成等,显著提升工作效率。以ChatGPT和Notion AI为例,这些工具可以快速生成结构化分析框架和PRD初稿,将传统需要数小时甚至数天的工作压缩到几分钟内完成。在产品设计阶段,工具如Uizard和Galileo AI能够根据文本描述自动生成可交互原型,大幅缩短设计探索

weixin_29194817的博客 241

实战解析:如何通过LTspice仿真优化MOS管缓启动电路,解决上电冲击电流问题

本文详细解析如何通过LTspice仿真优化MOS管缓启动电路,有效解决上电冲击电流问题。文章从问题根源分析入手,介绍LTspice环境搭建、缓启动电路设计原理、参数优化技巧及实际工程问题排查,帮助工程师掌握MOS管电源开关电路的关键设计方法,提升系统可靠性和性能。

weixin_28683689的博客 513

从require.ensure到import():bundle-loader背后的webpack代码分割演进史

当你的应用打包出一个动辄 5MB 的 JS 文件时,首屏加载慢几乎成为必然——这正是 **webpack 代码分割(Code Splitting)** 要解决的经典问题。而在 webpack 生态的早期,**bundle-loader** 正是最流行的代码分割工具之一:它能把一个模块拆成独立 chunk,实现按需加载。今天,我们就沿着「require.ensure → bundle-loader

gitblog_00369的博客 430

深入解析MOSFET结电容与分布参数:Cgd、Cgs、Cds与Ciss、Crss、Coss的关系与应用

本文深入解析了MOSFET结电容Cgd、Cgs、Cds及其等效参数Ciss、Crss、Coss对开关性能的影响。文章详细阐述了米勒电容Cgd如何导致开关损耗与振荡,并提供了基于电容参数的高频电路选型、驱动设计及PCB布局优化等实战指南,帮助工程师解决开关电源与电机驱动中的常见问题。

weixin_29240711的博客 1282

webpack官网文档 :指南 -- 7.代码分割 - 使用import()

原文地址:https://webpack.js.org/guides/code-splitting-import/ 动态引入目前,一个把类函数的模块加载语法import()添加到ECMAScript的提议,正在讨论中。ES2015加载器细则定义import()为一个能在运行时动态加载ES2015模块的方法。webpack把import()当作一个分割点,把需求的模块放到单独的代码块里。import...

weixin_34150503的博客 561

【SpringCloud】5、Spring Cloud Gateway网关路由规则

Spring Cloud Gateway 创建 Route 对象时, 使用 RoutePredicateFactory 创建 Predicate 对象,Predicate 对象可以赋值给 Route。

JACKAL 3万+

VS code 调试显示preLaunchTask“g++“已终止,退出代码为-1。 生成‘... .exe‘文件错误

总结: 以后每个工程都需要按照这样的流程:创建一个.c/.cpp文件 -> F5运行 -> 配置tasks.json文件-> launch.json文件 -> 运行

qq_45151652的博客 2513

[译]webpack官网文档 :指南 -- 7.代码分割 - 使用import()

原创翻译,转载请注明出处。  原文地址:https://webpack.js.org/guides/code-splitting-import/   动态引入 目前,一个把类函数的模块加载语法import()添加到ECMAScript的提议,正在讨论中。 ES2015加载器细则定义import()为一个能在运行时动态加载ES2015模块的方法。 webpack把import()当作一...

iteye_5929的博客 322

MinerU 系列教程 | 第二课:快速上手 -- 安装与第一次解析

本篇教程作为的第二课,将带你从零完成 MinerU 的环境搭建、模型下载,并成功运行第一次文档解析。上一课我们从宏观视角认识了 MinerU,本课开始正式动手实践。

weixin_43674738的博客 300

怎么加载文件_聊聊 webpack 异步加载(二):webpack 如何处理 import()

作者 | vayne转载请注明出处上篇文章解释了webpack 是怎么加载拆包后的代码的,这篇文章解释下 webpack 如何处理 import()。import() 包含的代码被 webpack 当作 chunk 处理,同样也是通过 window["webapckJsonp"] 来进行加载。有了上篇文章的讲解,本篇理解起来会很容易。讲解之前再回顾下 webpack bootstrap 代码中非常...

weixin_35999626的博客 860

量子化学仿真软件:VASP_(9).磁性材料计算

在量子化学仿真软件 VASP 中,磁性材料的计算是一个复杂但重要的过程。通过正确设置磁性状态、分析磁性性质、优化计算参数以及研究磁性相变和磁动力学,可以更准确地描述和预测磁性材料的性能。希望本节的内容能够为研究磁性材料的科研人员提供有用的参考和指导。

kkchenjj的博客 1375

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

18.重学webpack——webpack动态加载原理/webpack异步加载原理/webpack动态解析import()原理

【重学webpack系列——webpack5.0】 1-15节主要讲webpack的使用,当然,建议结合《webpack学完这些就够了》一起学习。 从本节开始,专攻webpack原理,只有深入原理,才能学到webpack设计的精髓,从而将技术点运用到实际项目中。 可以点击上方专栏订阅哦。 以下是本节正文: import()对于webpack来说,是一个天然的分割点,也就是说,webpack碰到import()会对import()进行解析。怎么解析的,过程主要是: 面试题:webpack解析impo

2024路在何方 3622

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

如何在Vue3中实现代码分割和懒加载?

代码分割是指将应用的代码根据不同的功能模块进行分拆,生成多个小的代码块,在需要的时候加载相应的代码块,以替代一次加载所有代码,从而减少初始加载时间。懒加载是一种按需加载的技术,只有在用户真正需要某些内容时才加载对应的资源。这在单页面应用(SPA)中非常有用,可以显著提升应用的响应速度和性能。下面将详细介绍如何在Vue3中实现这两项技术,并给出实际的示例代码。

有我更精彩的博客 1934

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

webpack 代码进行切割实现案例

为了解决性能问题,Webpack 提供了代码分割(Code Splitting)功能,可以将代码切割成多个小块,按需加载,从而减少初始加载时间。下面我将提供一个简单的案例来演示如何在 Webpack 中实现代码分割:

667

webpack如何实现代码分割

webpack如何实现代码分割

weixin_72127453的博客 931

说说webpack中代码分割如何实现?

Webpack会生成多个代码块文件,这些文件包含了拆分出来的模块。你可以使用Webpack的内置功能或第三方库(如。确保在适当的时机异步加载模块,以避免不必要的加载。可以在路由切换、事件触发或其他需要时异步加载模块。这个选项允许你配置哪些模块应该被拆分成单独的块,以及如何命名这些块。动态导入是ES6模块系统的一部分,它允许你在代码中异步加载模块。Webpack将根据配置自动将这些模块拆分为单独的块。函数,你可以在需要的时候延迟加载模块,从而实现代码分割。为了实现代码分割,你需要配置Webpack的。

记录每日学习的知识&技术 730

代码分割

打包大多数 React 应用都会使用 Webpack,Rollup 或 Browserify 这类的构建工具来打包文件。 打包是一个将文件引入并合并到一个单独文件的过程,最终形成一个 “...

文摘资讯 321

懒加载路由:基于import()的代码分割深度解析

本文深入探讨了懒加载路由如何利用ES6的import()语法实现代码分割,提升前端应用性能。文章从Vue和React框架实践出发,分析了动态导入机制、路由分组策略及错误处理方案,并介绍了Webpack配置优化、预加载策略等高级技巧。同时提供了性能监控方法和常见问题解决方案,展望了模块联邦、HTTP/2推送等未来趋势。通过代码分割技术,开发者可显著减少初始加载体积,使应用首屏加载时间降低40-60%,实现更好的用户体验。

1100

import和require

Webpack支持两种按需拆分,切入点分别是import()和require.ensure(),首选前者,它是ECMAScript的建议,import也是es6的关键词;后者是webpack所特有的。 其中http、fs、net等都是node.js提供的核心模块,使用C/C++实现,外部用JavaScript封装。 动态导入import Webpack把import()作为拆分点,...

abcde1872531的博客 153

研究到论文 AI 协作模式选型指南

你让 AI"帮我写一篇关于 X 的论文",收获一篇 5000 字但论据空心的稿子;或者只想查一条引用,AI 却顺手重写全文。Academic Research Skills(下称 ARS)是面向 Claude Code 的学术研究技能套件,覆盖研究到论文定稿的全流程——但打开它,你会看到 5 个模块、35 个模式,自己那句话到底会落到哪一档?本文给你一套三问判断法,不用背模式名。 ## 该谁用:

gitblog_00964的博客 819

webpack优化构建体积示例-按需加载:代码分割 懒加载

按需加载(也称为代码分割或懒加载),基于import()实现的。尽管 import() 语法是在 ES2020 标准中正式引入的,但它在早期就已经被一些工具和库(如 Webpack)所支持,并且被用作实现代码分割和懒加载的方式。相比import … from …,import() 是动态导入用来在运行时按需加载和执行模块,import … from … 是静态导入,它在编译时确定需要哪些模块。加载前点击后可以看到点击后加载了对应的js资源。

qq_36413371的博客 500

webpack基础--代码分割和懒加载

代码分割和懒加载 内置方法和Loader require.ensure() 内置方法:require.ensure([dependencies], callback,errorCalback,chunkName) 动态加载代码 参数: dependencies: 依赖项, 是一个数组, 不会执行 callback: 在这里执行代码 errorCallback: 可省略 chunkN...

彩虹 1889
上一篇: element-ui生成自定义主题
下一篇: vscode使用prettier格式化svg文件
feral_coder
博客等级 码龄9年 19粉丝 80原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值