前言

现今 Web APP 开发很大的比例都是基于 SPA 的架构,透过 Route 分流到不同模组的页面,不管是 React 还是 AngularJS 都是这个脉络。但由于大部份的前端代码都打成一整包,当代码越来越多,Web 初次载入的时间也越来越冗长,接连影响用户体验。为了让代码能够依需求载入 (on demand),开始有了延迟载入 (Lazy Loading) 的技术方案,又延伸到拆分代码至 NPM 包或引入微前端架构。本文针对 SPA 的架构提出一个可以基于需求打包代码的方案,从一开始就先节流,让编译的代码是经过需求而挑选的,精准建设。

为了让整个 Web 被编译或包含的模组是经过挑选的,本文以 React + webpack + react-router 为例。另本文强调的是以需求进行挑选模组,如要降低编译耗时也可结合其他 bundless 解决方案。

动态生成

首先动态生成 (codegen) 在后端已不是什么新鲜的名词,但是基于让 Web 模组可以动态被挑选进来,我们需要代码动态生成的步骤,后端如 ant 或 gradle 都俱备修改静态代码的能力,前端的 webpack 的 loader 也能轻松完成这样的任务,而根据本文的目的,就来写一只自定义的 route loader 吧!

为了让产出的代码经过 loader 的处理,并且在进行代码编译之前就处理完成。我们输入进 webpack 一个 module rule 设定,enforce 为 pre,产生动态代码逻辑的为 layRouteLoader.js,会读入 lazyRoutes.js 的内容并再动态生成代码回 lazyRoutes.js,如下图。

以下为 webpack 的设定。

{enforce: 'pre',include: [path.resolve(__dirname, './src/routes/lazyRoutes.js'),],use: {loader: path.resolve(__dirname, './tool/scripts/lazyRouteLoader.js'),},
}

让我们来看一下 lazyRouteLoader.js 的内容:

function routeLoader(staticCode) {// --- step 1 读入源数据 ---// staticCode 字符串是 lazyRoutes.js 静态代码,读入源数据可以选用以下任一种方式// 1. 我们可以在 lazyRoutes.js 写入静态代码当成源数据使用// 2. 透过设定环境变数从 process.env 中拿取源数据// 我们假设 step 1 后能取得以下的信息const metadata = {"/module1": {"name": "routes/module1","chunkName": "module1",},"/module2": {"name": "routes/module2","chunkName": "module2",},};// --- step 2 依所需整理源数据 ---// 从环境变数 process.env 中拿取要挑选的 modulesconst picks = proccess.env.PICKS // ["/module2"]// 透过 picks 和 metadata 组出以下信息const filterModules = {"/module2": {"name": "routes/module2","chunkName": "module2",},};// --- step 3 输出我们挑的模组代码 ---const modulesKey = Object.keys(filterModules);return `import asyncComponent from 'core/asyncComponent';${modulesKey.map((key, index) => {const route = filterModules[key];return `const com${index} = asyncComponent(() => {return import('${route.name}' /* webpackChunkName:"${route.chunkName}" */);});`;}).join('')}const routes = [${modulesKey.map((key, index) => {const route = filterModules[key];return `{path: '${key}',chunkName: '${route.chunkName}',name: '${route.name}',Component: com${index},},`;}).join('')}];export default routes;`;
}

而最后动态输出到 lazyRoutes.js 如下:

import asyncComponent from 'core/asyncComponent';const com0 = asyncComponent(() => {return import('routes/module2' /* webpackChunkName:"module2" */);
});const routes = [{path: '/module2',chunkName: 'module2',name: 'routes/module2',Component: com0,
},];
export default routes;

透过 lazyRoutes.js export 出来的 routes 就能用在 react-router 上,动态载入。

<Router history={history}>{routes.map(({ path, Component }) =><Route key={path} path={path} render={props => <Component {...props} />} />)}
</Router>

以上就完成 routes 的动态加载,而要如何依需来挑选我们想要的模组呢?上面代码的设定内容中,挑选后的信息变数是透过 process.env 来传递的,所以我们只要将变数放进 process.env 即可。但依据使用的方式而有所不同,如果是本地开发模式,建议可以使用 inquerier 互动式工具来挑选,如下图。

如果是产品模式,能透过设定系统变数或运行参数的方式来汇入 process.env 。以上两种模式将 PICKS 这个变数放入 process.env 即能被 loader 获取来进行动态生成。

小结

本文以挑选 routes 的方式来演示前端代码动态生成,但其实像重复代码或有大量加载模组的档案都能适用此方法,前端的代码编写还是很灵活的,这边列出一些代码生成的优缺点,让大家参考。

优点:

  • 代码动态生成,代码间的相依关系也能动态连结,降低耦合性 (解耦)。
  • 不与 bundless 方案冲突,能够同时使用。
  • 适用于某些用来载入大量其他模组的档案。
  • 适用于被集成的产品,只被集成所需的模组。
  • 在专有或客制案场上,动态挑选要运行模组,而不是利用静态代码分类。
  • 因动态挑选的关系,露出到客户端的代码少,安全性也高。
  • 当开发全新模组或修正单一功能时,动态挑选要运行模组,降低编译时间,精准建设。

缺点:

  • 代码动态生成,耦合性低,但相对地,找查问题时的难度更高了。
  • 内容是以代码写代码,交接或著 code review 的难度也更大。

结合以上的优缺点,代码动态生成是一个很强大的功能,但是应该用在刀口上即可,而不是大量使用,只针对部份依赖性高的单点去使用,希望以上的分享能够带来不一样的想法,欢迎讨论。

动态提出的数据怎么换行 js_前端代码动态生成应用及改造相关推荐

  1. Mybatis+MySQL动态分页查询数据经典案例(含代码以及测试)

    最近在用Mybatis做项目的时候遇到了不少问题,今天我就在这和大家分享一下,稀稀拉拉的研究了两天,终于搞好了! 开发人员:1111 开发软件:Myeclipse 用到的框架技术:Mybatis 数据 ...

  2. 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 创建 事件监听器 对应的 动态代理 | 动态代理的数据准备 | 创建调用处理程序 | 创建动态代理实例对象 )

    文章目录 前言 一.创建 事件监听器 对应的 动态代理 二.动态代理 数据准备 三.动态代理 调用处理程序 四.动态代理 实例对象创建 前言 Android 依赖注入的核心就是通过反射获取 类 / 方 ...

  3. 爬虫案例之爬取国家药监局化妆品生产许可明细(爬取动态加载数据)

    一.实验目的 爬取国家药监局(化妆品生产许可信息管理系统服务平台 (nmpa.gov.cn))化妆品生产明细(具体到每家企业的具体信息),当我们进入该网站首页时,发现其结构为每页15条的json类型数 ...

  4. phpcms v9 sql数据{$r[content]},前端如何换行显示?

    已解决:phpcms sql数据{$r[content]},前端如何换行显示 一.效果图 · 前后对比: 1. [解决前] 问题场景 · 如下图所示: 2. [解决后]效果截图: 2. 问题: 问1: ...

  5. layui做折线图_flask+layui+echarts实现前端动态图展示数据效果

    效果图: 该效果主要实现一个table展示数据,并在下方生成一个折线图. 实现方式: 1.首先需要对表格进行一个数据加载,这里用到了layui的table.render,具体用法可以参考 https: ...

  6. php抓取动态数据,php+ajax实现无刷新动态加载数据技术

    我们浏览有些网页的时候,当拉动浏览器的滚动条时到页底时,页面会继续自动加载更多内容供用户浏览.这种技术我暂且称它为滚屏加载技术.我们发现很多网站用到这种技术,必应图片搜索.新浪微博.QQ空间等将该技术 ...

  7. 滚屏加载--无刷新动态加载数据技术的应用

    我们浏览有些网页的时候,当拉动浏览器的滚动条时到页底时,页面会继续自动加载更多内容供用户浏览.这种技术我暂且称它为滚屏加载技术.我们发现很多网站用到这种技术,必应图片搜索.新浪微博.QQ空间等将该技术 ...

  8. 使用echarts实现系统性能动态监控(数据实时展示)

    一. 实现效果 先来一张效果图.gif 二.解决方案 1.目前的解决方案(异步加载) 目前的实现方式比较简单,前端定时从后台请求数据并渲染Echarts,这样做的方式比较简单粗暴,但也有如下几个问题: ...

  9. 网易云音乐前端模块动态下发系统

    关注 前端瓶子君,回复"加群" 加入我们一起学习,天天进步 作者:康东扬 https://zhuanlan.zhihu.com/p/91386560 本文是<滨江前端技术沙龙 ...

  10. 从后端数据库获取数据并传值到前端vue项目的echarts柱状图/折线图/饼图里

    不同图表的数据获取有一定的区别 在这些区别上花了不少功夫试验,把最后成功的方法做个记录,如果有类似项目要做的话,也可看看当个参考. 后端 后端都大同小异,方法上没有区别,在这里以柱状图为例. sql: ...

最新文章

  1. 在“内卷”、“红海”的2020 年,开垦计算机视觉领域的知识荒原:BatchNorm
  2. 10JavaScript中的预解析
  3. [禅悟人生]每个人都可以获得自己的精彩
  4. Tkinter中常用的函数
  5. Alpine Linux 中的 apk 命令讲解
  6. 热门的模型跨界,Transformer、GPT做CV任务一文大盘点
  7. 学习Identity Server 4的预备知识
  8. mysql添加字段时定义候选键_MySQL 表约束
  9. #Java编程题-百钱百鸡
  10. Query siblings()
  11. VDI SolutionTrack - 上海站:11月20日
  12. 拓端tecdat|R语言中使用非凸惩罚函数回归(SCAD、MCP)分析前列腺数据
  13. 《Web漏洞防护》读书笔记——第3章,其他注入防护
  14. python 学习笔记——线性回归预测模型
  15. c语言二次方程的实根,C程序求二次方程的根
  16. 显示 wordpress 文章摘要函数the_excerpt
  17. 关于wifi共享大师破解版在电脑休眠后wifi无法连接的问题
  18. Nature | 基于细菌构建具有类真核细胞结构和功能的人工细胞
  19. 网络数据采集分析工具tcpdump定义抓包过滤器
  20. Java工程师是做什么的 岗位职责都有哪些

热门文章

  1. 图解WIN7通过“磁盘管理”功能进行分区的详细过程
  2. Could not find artifact com.taotao:taotao-parent:pom原因
  3. sourceTree把当前分支合并到远程分支
  4. android中使用setVideoURI()播放视频
  5. 从2013年下半年始计算机等级考试大纲有重要调整
  6. 大刀阔斧,抽丝剥茧:评红黑树系列文章
  7. 关于SQLServer2005的学习笔记——异常捕获及处理
  8. Android 多媒体开发学习之加载大图片
  9. Linux 的 history 命令显示时间
  10. /proc/sys目录下文件的查看方法