多平台编包动态引入依赖的解决方案

server/2024/11/13 10:48:11/

最近开发时遇到了这样的需求,A 平台需要引入一个 video.js,B 平台却是不需要的,那么面向 B 平台打包的时候把依赖装进去自然就不大合适。最好的方法是动态引入依赖,根据平台来判断要不要引入

动态引入依赖

很快啊,动态引入依赖的代码就写好了

if (window.isPlatformA()) {import("!video.js").then((videojsModule) => {const videojs = videojsModule.default;......})
}

关于为什么 video.js 前要加 ! 见 Webpack and Video.js,简单来说就是 webpack 会破坏 video.js 的代码,让它不好使了,从现象来看就是视频一直处于 loading 状态。所以通过这种写法来使得 video.js 不经过 webpack

自信启动,npm start!

播不出来 /(ㄒoㄒ)/~~

Uncaught ReferenceError: D_Projects_XXX_node_modules_babel_preset_react_app_node_modules_babel_runtime_helpers_esm_createClass__WEBPACK_IMPORTED_MODULE_11__ is not defined

点进去看调用栈,是 babel 运行时的一个模块,没解析出来
这玩意搜也不好搜,只能拆开搜 createClass、babel runtime helpers 之类的。有的说给 babel 的 presets 里面加 “absoluteRuntime”: false,这个是管绝对路径的,感觉没什么用;还有人说是 babel runtime 的版本要换,我这都没有 babel runtime。。

不对,既然是在代码跑起来的时候去动态的判断某些数值然后采取不同的措施,这意思不正是所谓的“运行时”嘛!再看 @babel/runtime 的介绍,@babel/runtime is a library that contains Babel modular runtime helpers,原来报错中提到的 babel runtime helpers 是出自它手

npm install @babel/runtime

解决了!

预编译优化

完成动态 import 之后,直接进行编包,结果完全没有缩小啊!

想想也是,加载的时候按需加载,这是针对浏览器的,浏览器的负担确实是小了。但是编包的时候,webpack 一看,这个 chunk 有可能会用到也有可能不会用到,那么我是把它打进去呢还是不打进去呢?还是打进去吧。这样的话,包就不可能小

C++ 的项目里,有通过 #ifdef 来实现预编译,动态决定编译时是否执行某段代码,js 有没有这种机制呢

果然,webpack 有一个叫 DefinePlugin 的 plugin(https://www.webpackjs.com/plugins/define-plugin/),可以起到类似 #define 的效果

 	plugins: [new webpack.DefinePlugin({IS_PLATFORM_A: JSON.stringify(false),}),] 

修改 import 处的条件

if (IS_PLATFORM_A) {import("!video.js").then((videojsModule) => {const videojs = videojsModule.default;......})
}

最后修改 uglifyjs 的配置,enable dead_code,使之过滤掉所有进不去的代码

compress: {dead_code: true,
},

成功!
最后编出来的包比之前小了近 2000 KB


http://www.ppmy.cn/server/140837.html

相关文章

剑指offer第九天

1.数组中只出现一次的两个数 #include <vector> class Solution { public:vector<int> FindNumsAppearOnce(vector<int>& nums) {// write code hereint v 0;for(int&x:nums)v^x;int cnt 0;while(v){v>>1;cnt;}int a 0,b 0;for(int&x…

UE5.1 控制台设置帧率

仅个人记录&#xff0c;未经过严格验证。 也可通过控制台命令蓝图节点&#xff0c;在运行时执行 锁帧&#xff1a; 0->120帧 1-》60帧

【报错解决】使用@SpringJunitConfig时报空指针异常

报错描述 具体的报错如下图所示&#xff1a; 我的测试代码如下&#xff1a; import config.StudentConfig; import controller.StudentController; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test…

Java学习篇之JVM 调优

Java学习篇之JVM 调优 一、JVM 是什么&#xff1f;二、JVM 官方参数建议三、JVM调优的场景四、如何监控JVM五、JVM调优的流程步骤1. 明确优化目标2. 监控和分析3. 确定调优参数4. 实施调优策略5. 持续观察和调整6. 定期评估和优化 一、JVM 是什么&#xff1f; JVM&#xff0c;…

1.62亿元!812个项目立项!上海市2024年度“科技创新行动计划”自然科学基金项目立项

本期精选SCI&EI ●IEEE 1区TOP 计算机类&#xff08;含CCF&#xff09;&#xff1b; ●EI快刊&#xff1a;最快1周录用&#xff01; 知网(CNKI)、谷歌学术期刊 ●7天录用-检索&#xff08;100%录用&#xff09;&#xff0c;1周上线&#xff1b; 免费稿件评估 免费匹配期…

如何在 IntelliJ IDEA 中调整 `Ctrl+/` 快捷键生成注释的位置

前言 在使用 IntelliJ IDEA 编写代码时&#xff0c;注释是代码可读性和维护性的重要组成部分。IDEA 提供了快捷键 Ctrl/ 用于快速生成单行注释。然而&#xff0c;默认情况下&#xff0c;使用此快捷键生成的注释会出现在行首&#xff0c;导致注释与代码之间存在较大的空格&…

electron 中 ipcRendererEvent 作用

1. 理解 IPC&#xff08;进程间通信&#xff09;的背景和重要性 在 Electron 应用中&#xff0c;主进程和渲染进程是相互隔离的。这种隔离有助于提高应用的安全性和稳定性&#xff0c;但也需要一种有效的通信机制来协同工作。 IPC&#xff08;进程间通信&#xff09;就是用于…

【Linux系统编程】线程--概念

目录 理解线程 进程与线程的本质与关系 CPU调度 页表 页表的映射 进程代码段如何划分给多个线程&#xff1f; 线程的优缺点 理解线程 首先我们对于线程的切入点是从操作系统教材中对线程和进程的定义入手 线程&#xff1a;线程是进程内部的一个执行分支&#xff0c;是…