浏览器require加载devextreme-react组件

十几年前使用了devexpress公司的delphi元件,功能很强。它们的html元件devextreme,功能表现类似,也行强。

devextreme和devextreme-react,我使用的是23.2.3版本。

官方推荐的用法,都是要经过build:

npx devextreme-cli new react-app app-name
cd app-name
npm run start

经过约12秒的build,出来的html中有一个bundle.js,大小为12.5M。

它的模式是MPA,用babel把react组件转换成了js代码。

如果我要做SPA,不要每次都build,如何做?

devextreme和devextrem-react提供了cjs(es5)和esm(es6)两套代码,但是react本身没有esm的代码版本,如果devextreme使用esm版本,还是要经过babel转成es5来使用。

我们用es5的cjs版本吧。

(1)首先要在浏览器实现一个require函数,我是用breq - npm来改的。

(2)后台如何提供模组加载,我用nodejs实现静态文件。

会遇到几个问题:

(1)引用的组件不是相对路径,不是.、..、/打头的。

如:

import {TabPanel,Item as TabPanelItem} from 'devextreme-react/tab-panel.js';
import {locale,loadMessages} from 'devextreme/localization.js';

require需要仿照import实现一个importMap,建立文件映射表,如:

{"devextreme-react/tab-panel.js":'/devextreme-react/cjs/tab-panel.js',"devextreme/localization.js":'/devextreme-react/cjs/localization.js',
}

但是devextreme组件文件有500个以上,用绝对路径加载的也有好几十个,如果一个个加到importMap中也挺累的。可以实现一个目录映射来一网打尽,如:

"devextreme/":"/devextreme/cjs/",

实现后,发现其实import的importMap也支持这样的目录映射,好多文章没讲。

(2)引用的组件没有扩展名,如:

import {TabPanel,Item as TabPanelItem} from 'devextreme-react/tab-panel';
import {locale,loadMessages} from 'devextreme/localization';var _file_saver = require("./exporter/file_saver");
var _image_creator = require("./exporter/image_creator");
var _svg_creator = require("./exporter/svg_creator");
var _type = require("./core/utils/type");
var _deferred = require("./core/utils/deferred");
var _pdf_creator = require("./exporter/pdf_creator");

这需要后台的static函数支持这种检查,看看加上.js、.cjs扩展名是否存在此文件。

(3)引用的组件是个目录。

后台的static要尝试查找此目录下的index.js文件,如果没有index.js,看看有没有package.json文件,解析使用其中的main属性指向的文件。

组件是目录时,还导致一个额外的问题,浏览器发起者不知道这是个目录,以为是个文件,所以接下来再加载相对路径的组件时,就会导致路径错误,如:

let require('a/b/c'),实际是加载了/a/b/c/index.js,浏览器以为是来自/a/b/c.js,当前目录是/a/b,实际当前目录应该是/a/b/c,如果index.js中有一句require('../d.js'),浏览器就会解析为require('/a/d.js'),导致找不到文件,实际应该是a/b/d.js。

有两种方法解决:

a.后台的实际文件,返回到res的headers的location中,参考重定向的规范:http响应状态码(Header常见属性 — Location属性)_http location-CSDN博客。如:res.set('location',req.url);前台获得后,按location值设定当前目录。

b.在importMap中特殊配置一个映射,如:“a/b/c”:"/a/b/c/index.js"

(4)循环引用。就是一个引用文件还没解析执行完,又被其它文件引用到了。devextreme-react中发现2处,引用栈如下:

0: "/devextreme-react/cjs/core/component-base"
1: "/devextreme-react/cjs/core/template-manager"
2: "/devextreme-react/cjs/core/template-wrapper"
3: "/devextreme-react/cjs/core/component-base"

0: "/devextreme-react/cjs/core/component-base"
1: "/devextreme-react/cjs/core/template-manager"
2: "/devextreme-react/cjs/core/component-base"

devextreme中发现1处:

0: "/devextreme/cjs/ui/popup"
1: "/devextreme/cjs/ui/popup/ui.popup.full"
2: "/devextreme/cjs/ui/toolbar"
3: "/devextreme/cjs/ui/toolbar/ui.toolbar"
4: "/devextreme/cjs/ui/toolbar/strategy/toolbar.singleline"
5: "/devextreme/cjs/ui/toolbar/internal/ui.toolbar.menu"
6: "/devextreme/cjs/ui/popup"

为了避免循环引用的死循环栈溢出,require的cache需要在eval前就加入,不能在之后加入。

循环引用实际没有导致devextreme元件出bug,因为export的是一个object,加上js代码执行时的”Hoisting"(变量和函数提升),不马上使用require结果时没有问题。

如:\devextreme-react\cjs\core\template-wrapper.js

var component_base_1 = require("./component-base");
...
var TemplateWrapperComponent = function (_a) {component_base_1 = require("./component-base");//add by mustapha...
}

第1行代码不能删除,否则可能导致其它组件没有加载进来。TemplateWrapperComponent 中的那行其实也不用加,加了看起来更保险。

(5)require函数返回的module.exports如何处理default?

不要做任何处理,直接返回module.exports。

对于:

import {A} from '/x.js';
A.name='shanghai';
import B from '/y.js';
B.name='chongqing';
export default {A,B};
export {A,B};

banel转换后,首先会把module.__esModule设置为true,对import B,会用_interopRequireDefault函数为非模组化元件准备default值,后面统一用y['default']赋值给B。

"use strict";Object.defineProperty(exports, "__esModule", {value: true
});
Object.defineProperty(exports, "A", {enumerable: true,get: function get() {return _x.A;}
});
Object.defineProperty(exports, "B", {enumerable: true,get: function get() {return _y["default"];}
});
exports["default"] = void 0;
var _x = require("/x.js");
var _y = _interopRequireDefault(require("/y.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
_x.A.name = 'shanghai';
_y["default"].name = 'chongqing';
var _default = {A: _x.A,B: _y["default"]
};
exports["default"] = _default;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/648417.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

对二值化后的管接头表面缺陷图像进行垂直和水平投影这里面的水平投影和垂直投影是什么意思?

问题描述: 对二值化后的管接头表面缺陷图像进行垂直和水平投影 这里面的水平投影和垂直投影是什么意思? 问题解答: 在图像处理中,垂直投影和水平投影是两种常用的直方图投影方法,用于分析图像的特征,特别…

GitHub Copilot 与 OpenAI ChatGPT 的区别及应用领域比较

GitHub Copilot 和 OpenAI ChatGPT 都是近年来颇受关注的人工智能项目,它们在不同领域中的应用继续引发热议。本文旨在分析和比较这两个项目的区别,从技术原理、应用场景、能力和限制、输出结果、能力与限制和发展前景等方面进行综合评估,帮助…

Mysql 学习(十 四)事务简介

为什么要有事务? 数据库的出现其实是有应用场景的,最好的例子就是交易,以前的交易是通过账本记录的,也就是通过纸和笔来记录,而数据库的出现大大提升了效率,但是现实中的有些问题,数据库也需要…

数据分析 - python 数据处理

数据处理 去除重复数据 # 删除重复值 保留重复行 第一行的数据 data.drop_duplicates(inplaceTrue, keepfirst)数据格式转化 日期格式化 data[order_date] pd.to_datetime(data[order_dt], format%Y%m%d)data[销售时间] pd.to_datetime(data[销售时间]) # 交货时间 销售…

MIT_线性代数笔记:线性代数常用计算公式

目录 1.矩阵的加法和数乘2.矩阵的乘法3.转置 Transposes 相关运算 1.矩阵的加法和数乘 2.矩阵的乘法 1)标准方法(行乘以列) 矩阵乘法的标准计算方法是通过矩阵 A 第 i 行的行向量和矩阵 B 第 j 列的列向量点积得到 cij。即我们常说的点积,也…

SIP INVITE method

在RFC 3261定义了SIP:INVITE,以下是具体内容。 当UA客户端希望发起session,例如voice call 或video call时,UAC就可以发送INVITE request。INVITE request会要求服务器建立session,然后该请求由代理转发,最终到达一个或多个可能接受邀请的UAS。 UAS 可以通过发送 2xx res…

c++ class总结

c class的使用总结 1.继承2.静态成员变量与静态成员函数3.多态4.虚函数5.纯虚函数6.友元类、友元函数6.1 友元类6.2 友元函数 1.继承 类Man、WoMan 继承于类Person。 类Man、WoMan 的实例对象都可以使用类Person中public属性的成员及成员函数。 #include<iostream>cla…

使用GtkSharp下载zip包过慢问题解决方案

背景 安装GtkSharp这个包准备使用C#进行跨平台窗体应用程序开发&#xff0c;运行时发现其需要从github上下载【https://github.com/GtkSharp/Dependencies/raw/master/gtk-3.24.24.zip】这个依赖包&#xff0c;不知道是被墙了还是咋的&#xff0c;下载超时导致运行失败。 解决…

【算法练习】leetcode算法题合集之动态规划篇

普通动规系列 LeetCode343. 整数拆分 LeetCode343. 整数拆分 将10的结果存在索引为10的位置上&#xff0c;需要保证数组长度是n1&#xff0c;索引的最大值是n&#xff0c;索引是从0开始的。 n的拆分&#xff0c;可以拆分为i和n-i&#xff0c;当然i可以继续拆分。而且拆分为n-…

django mysql in 有序返回

from django.db.models import * ordering f"FIELD(id, {,.join([str(_) for _ in ids])})" # 默认就按照算法返回的 id 排序p_data_result PeptidesDataResult.objects.using("polypeptide").filter(id__inids).values().extra(select{ordering: orderi…

Cybellum—信息安全测试工具

产品概述 由于软件和数据在汽车上的使用越来越多&#xff0c;汽车越来越“智能化”&#xff0c;汽车行业面临着重大的信息安全挑战。2021年8月&#xff0c;ISO/SAE 21434正式发布&#xff0c;标准中对汽车的信息安全提出了规范化的要求&#xff0c;汽车信息安全不容忽视。 Cyb…

Redis数据结构与底层实现揭秘

在高并发的系统开发中&#xff0c;缓存和高效的数据存储机制对于提升应用性能至关重要。Redis&#xff0c;作为其中的佼佼者&#xff0c;以其卓越的性能和丰富的数据结构赢得了开发者的青睐。本文将深入探讨Redis的数据结构及其底层实现&#xff0c;带领读者走进这个高性能数据…

CentOS7 安装PostgreSQL以及配置服务

文章目录 前言1. 安装步骤2. 连接PostgreSQL3. 配置服务配置文件所在路径设置监听地址修改数据库密码已经修改了密码,为什么没有生效?不需要密码就可以连接?设置访问权限4. 新的配置生效前言 PostgreSQL是一种功能强大的开源关系型数据库管理系统,被广泛用于各种应用程序和…

多个SSH-Key下,配置Github SSH-Key

首先&#xff0c;检查 github 的连接性&#xff0c;因为DNS污染的原因&#xff0c;很多机器ping不通github&#xff0c;就像博主的机器&#xff1a; 怎么解决DNS污染的问题&#xff0c;博主查了很多教程&#xff0c;测试出一个有效的方法&#xff0c;那就是修改hosts文件。host…

设计模式_组合模式_Composite

案例引入 学校院系展示 编写程序展示一个学校院系结构: 需求是这样&#xff0c;要在一个页面中展示出学校的院系组成&#xff0c;一个学校有多个学院&#xff0c;一个学院有多个系 【传统方式】 将学院看做是学校的子类&#xff0c;系是学院的子类&#xff0c;小的组织继承大…

代码随想录算法训练营第二天—数组02 | *977.有序数组的平方 ,209.长度最小的子数组 ,*59.螺旋矩阵II

*977.有序数组的平方 题目链接&#xff1a;https://leetcode.cn/problems/squares-of-a-sorted-array/ 文章讲解&#xff1a;https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html 视频讲解&#xff1a; https://www.bilib…

HarmonyOS 鸿蒙应用开发( 六、实现自定义弹窗CustomDialog)

自定义弹窗&#xff08;CustomDialog&#xff09;可用于广告、中奖、警告、软件更新等与用户交互响应操作。开发者可以通过CustomDialogController类显示自定义弹窗。具体用法请参考自定义弹窗。 在应用的使用和开发中&#xff0c;弹窗是一个很常见的场景&#xff0c;自定义弹窗…

idea连接docker

idea 插件无法连接docker问题 原文&#xff1a;idea 插件无法连接docker问题 // 修改docker配置 vi /usr/lib/systemd/system/docker.service // 加上该段配置允许任何ip访问 -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock // 重启docker即可 systemctl restart dock…

虹科数字化与AR部门升级为安宝特AR子公司

致关心虹科AR的朋友们&#xff1a; 感谢您一直以来对虹科数字化与AR的支持和信任&#xff0c;为了更好地满足市场需求和公司发展的需要&#xff0c;虹科数字化与AR部门现已升级为虹科旗下独立子公司&#xff0c;并正式更名为“安宝特AR”。 ”虹科数字化与AR“自成立以来&…

opencv010 卷积02(方盒滤波和均值滤波)

今天继续学习滤波器的相关知识&#xff01;这篇比较简单&#xff0c;也短一些&#xff0c;明天写高斯滤波 方盒滤波 boxFilter(scr, ddepth, ksize[, dst[, anchor[, normalize[, borderType]]]]) 方盒滤波的卷积核如下&#xff1a; normalize&#xff08;标准化&#xff0…