当前位置: 首页 > news >正文

Typescript第九/十章 前后端框架,命名空间和模块

第九章 前后端框架

9.1 前端框架

Typescript特别适合用于开发前端应用。Typescript对JSX有很好的支持,而且能安全地建模不可变性,从而提升应用的结构和安全性,写出的代码正确性高,便于维护。

9.1.1 React

JSX/TSX内容等

详情请到React官方学习

9.1.2 Angular

详情请到Angular学习

依赖注入,控制反转

9.1.3 Vue

详情请到Vue官方学习

Vue3全面支持Typescript

9.2 类型安全的API

  • 针对REST式API的swagger
  • 针对GraphQI的Apollo
  • 针对RPC的gRPC

9.3 后端框架

Nest.js完全支持Typescript

通过Typescript访问数据库,TypeORM超好用

第十章 命名空间和模块

在一个程序中,我们可以在不同的层级上进行封装。在最底层,函数封装行为,对象和列表等数据结构封装数据。函数和数据还可以放在类中,还可以把函数放在单独的数据库或数据存储器中,把函数和数据放入独立的命名空间中。

通常一个类或一系列使用函数放在一个文件中。再向上一层,我们可能会把多个类或多组使用函数组织在一起,构建成包(package),发布到NPM中。

模块(module)是一个重要概念,

我们要知道编译器(TSC)是如何解析模块的,

要知道构建系统(Webpack,Gulp,Vite等)是如何解析模块的,

还要知道模块在运行时是如何加载到应用的(使用<script/>标签,SystemJS等)。

对JavaScript来说,这些操作往往都由单独的程序执行,有点混乱。CommonJS和ES2015模块标准简化了这三个程序之间的互操作,Webpack等强大的打包程序进一步抽象了这三个解析过程背后涉及的操作。

本章着重讨论这这三种工具中的第一种,即Typescript解析和编译模块所用的工具,第12章再讨论构建系统和运行时加载程序。

  • 实现命名空间和模块的不同方式
  • 导入和导出代码的不同方式
  • 在代码增长的过程中弹性伸缩这些方法。
  • 模块模式与脚本模式的比较
  • 声明合并的概念及其作用

10.1 JavaScript模块简史

由于Typescript最终编译成JavaScript,并与JavaScript互操作,因此Typescript要支持JavaScript程序使用的各种模块标准。

起初(1995)JavaScript并不支持任何模块系统。由于没有模块,一切都在全局命名空间中声明,导致应用非常难以构建和弹性伸缩。而且,我们无法显式指明各个模块对外开放哪些API。

为了解析问题,人们通过对象或理解调用函数(IIFE)表达式模拟模块,把对象或IIFE附加到全局对象window上,供当前应用

 window.emailListmModule = {renderList(){}}window.emailComposerModule = {renderComposer(){}}window.appModule = {renderApp(){window.emailListmModule.renderList()window.emailComposerModule.renderComposer()}}

可是加载和运行JavaScript会阻塞浏览器UI,浏览器会变得越来越慢。

于是有了新方案:在页面加载完成之后动态加载JavaScript,而不同时加载。

在页面加载完毕之后惰性(通常是异步)加载JavaScript代码,为了实现异步惰性,需要做到以下三点:

  1. 模块要适当的封装,否则,不断流入的依赖会导致页面崩溃
  2. 模块之间的依赖要显示声明,否则,不知道需要加载什么模块,以及以什么顺序加载。
  3. 每个模块在应用中都要有一个唯一标识符。否则,无法指定需要加载哪个模块。

nodejs大哥采用用的是Commonjs模块标准

 // emailBaseModule.jslet emailList = require('emailListModule')let emailComposer = require("emailComposerModule")module.exports.renderBase = function(){}

可是Commjs处理事情的方式有几个问题,包括:require必须同步调用,Commonjs模块解析算法不适合在web使用。Commjs的代码在某些情况下不会做静态分析。

因为module.exports可能出现在任何位置(甚至可能在不会执行的分支),require调用可以出现任何位置,而且可以包含任意字符串和表达式,就导致静态链接JavaScript,不能确认被 引用的文件真实存在,也无法确保被引用的文件真正的到处了声称的代码。

然后,ECMAScript语言第六版,即ES2015为导入和导出引入了一个新标准,句法更简洁,而且支持静态分析。

 // emailBaseModule.jsimport emailList from 'emialListModule'import emailComposer from 'emailCpmposerModule'export function rederBase(){}

如今,我们在JavaScript和Typescript中使用的就是这个标准。不是每个JavaScript引擎都原生支持这个标准,所以要把代码编译成被支持的格式(在nodejs中编译成commonjs格式,在浏览器环境中,编译成全局或单个模块可加载的格式)

TSC的构建系统还支持针对不同的目标环境编译模块,包括:全局,ES2015,Commonjs,AMD,Systemjs,UMD。

10.2 import,export

除非迫不得已,不要在Typescript中使用Commjs,全局或命名空间下的模块。

 // a.tsexport function foo(){}export function bar(){}​import {foo,bar} from './a'​export let result = bar()
 // ./c.tsexport default function meow(){}import meow form './c'meow()
 import * as a from './a'​a.foo()
 export * from './a'export {result} from './b'export meow from './'

由于我们编写的是Typescript,而不是JavaScript代码,所以,除了值外,还可以导出类型和接口。因为类型和值位于不同的命名空间中,所以可以导出两个同名的内容,一个在值层面,一个在类型层面。Typescript将推导出你值得是类型还是值

 // g.tsexport let X = 3;export type X = {y:string}​// h.tsimport {X} from './g'​let a = X + 1let b:X = {y:'z'}

10.2.1 动态导入

应用变大后,初次渲染的时间将不断增加。这对前端应用来说是不可忽视的问题。

进一步的优化措施是惰性加载分块,在真正使用的时候才加载。

LABjs及其衍生库引入了真正需要时才惰性加载的概念,这个概念正式的名称是“动态导入”(dynamic imports),用法

 let locale = awat import('locale_cn-en')

import可以作为一个语句使用,作用是静态获取代码,另外,也可以作为一个函数调用,此时返回结果是一个Promise

动态导入应该使用下面两种做法中的其中一种:

  1. 直接把字符串字面量传给import,不要事先赋值给变量
  2. 把表达式传给import,但要手动注解模块的签名
 import {locale} form ''async function main(){let userlocal = awat getuserlocal()let path = "./loca-${userlocal}"let local:typeof locale = await import(path)}

导入locale不过只作为类型,这样写出代码不仅具有十足的类型安全,而且能动态计算导入那个包。

10.2.2使用Commonjs和AMD模块

使用Commjs或AMD标准的JavaScript模块时,可以直接从模块中导入名称,就像使用es2015模块一样

 import {something} from './commonjs/module'

默认情况下,commonjs的默认导出不能与es2015的默认导出互操作:使用默认 导出,要借助通配符:

 import * as fs from 'fs'fs.readFile('some/file.txt')​// import { readFile } from "fs";​// readFile​// import * as fs from 'fs'// fs.readFile

10.2.3 模块模式与脚本模式

Typescript采用两种模式编译Typescript文件:模块模式和脚本模式,

文件中有没有import或export语句,如果有使用模块模式,如果没有,使用脚本模式

目前为止我们使用的都是模块模式,

在脚本模式下,声明的顶层变量子啊项目中的任何文件都可以使用,无需导入,可以放心使用UMD模块中的全局导出,不用事先导入,下述情况使用脚本模式:

  1. 快速验证不打算编译成任何模块系统的浏览器代码({“module”:”none”}),在html文件中直接使用<script/>标签引入
  2. 创建类型声明(11.1节)

其实,在使用Typescript编写代码时,基本上应该始终使用模块模式,通过import导入代码,通过export导出代码,供其他文件使用。

10.3 命名空间

Typescript还提供了另一种封装代码的方式:namespace关键字。很多java,C#,C++,PHP和python都支持。

要注意一点:虽然Typescript支持命名空间,但这并不是封装代码的首选方式。如果你不确定使用命名空间还是模块,首选模块!

命名空间所做的抽象摒弃了文件在文件系统中的目录结构,我们无需知道.mine函数保存在a/b/c/d中,若想使用这个函数,使用简洁的命名空间A.B.C.D.mine即可

假设有两个文件,一个文件是发起http get请求的模块,另一个文件使用该模块发起请求:

 // Get.tsnamespace Network {export function get<T>(url: string): Promise<T> {return new Promise(()=>{})}}// App.tsnamespace App {Network.get<GitRepo>("api.github.com/repos/")}

命名空间必须有名称,命名空间可以导出函数,变量,类型,接口和其他命名空间。namespacekuai中没有显示导出的代码为所在块的私有代码。由于命名空间可以导出命名空间,因此命名空间可以嵌套。

 namespace Netwok {export namespace HTTP {export function get<T>(url:string):Promise<T>{return new Promise(()=>{})}   }export namespace TCP{export function listenerCount(port:number){​}function test(){​}}export namespace UDP{​}}Netwok.HTTP.getNetwok.TCP.listenerCountNetwok.TCP.test // 找不到

命名空间也可以分散在多个文件中。Typescript将递归合并名称相同的命名空间

为了使用方便,可以创建别名

 namespace A {export namespace B{export namespace C {export let d = 3}}}import d = A.B.C.dlet e = d*3console.log(e);//9

10.3.1 冲突

导出相同名称的代码会导致冲突:

 // 报错namespace Network {export function request(){}}namespace Network {export function request(){}}​

特例,改进函数类型时对外参(ambient)函数声明的重载不导致冲突

10.3.2 编译输出

与导入和导出不一样,命名空间不遵循tsconfig.json中的module设置,始终编译成全局变量。

模块优于命名空间

为了更符合JavaScript标准,为了更明确地指定依赖,较之命名空间,应该更多的使用常规的模块

明确指明依赖的好处很多,可以提示代码可读性,可以强制模块隔离,还可以做静态分析。

在大型项目中,建议全部使用模块,不要用命名空间

10.4 声明合并

目前,我们接触到了Typescript所做的三种合并:

  • 合并值和类型,根据使用情况区分一个名称是引用值还是类型
  • 把多个命名空间合并成一个
  • 把多个接口合并成一个

Typescript支持很多类型的合并,让一些难以表达的模式变为可能。

相关文章:

Typescript第九/十章 前后端框架,命名空间和模块

第九章 前后端框架 9.1 前端框架 Typescript特别适合用于开发前端应用。Typescript对JSX有很好的支持&#xff0c;而且能安全地建模不可变性&#xff0c;从而提升应用的结构和安全性&#xff0c;写出的代码正确性高&#xff0c;便于维护。 9.1.1 React JSX/TSX内容等 详情…...

LLM - argparse 解析脚本参数

目录 一.引言 二.argparse 解析 shell 参数 1.使用步骤 2.python 侧示例 3.shell 侧示例 一.引言 CUDA_VISIBLE_DEVICES0 python src/train_bash.py \--stage pt \--model_name_or_path path_to_your_model \--do_train \--dataset wiki_demo \--template default \--fin…...

谈一谈在两个商业项目中使用MVI架构后的感悟

作者&#xff1a;leobertlan 前言 当时项目采用MVP分层设计&#xff0c;组员的代码风格差异也较大&#xff0c;代码中类职责赋予与封装风格各成一套&#xff0c;随着业务急速膨胀&#xff0c;代码越发混乱。试图用 MVI架构 单向流 形成 掣肘 带来一致风格。 但这种做法不够以…...

ApacheCon - 云原生大数据上的 Apache 项目实践

Apache 软件基金会的官方全球系列大会 CommunityOverCode Asia&#xff08;原 ApacheCon Asia&#xff09;首次中国线下峰会将于 2023 年 8 月 18-20 日在北京丽亭华苑酒店举办&#xff0c;大会含 17 个论坛方向、上百个前沿议题。 字节跳动云原生计算团队在此次 CommunityOve…...

Git 代码分支规范

目的 俗话说&#xff1a;没有规矩&#xff0c;不成方圆。遵循一个好的规章制度能让你的工作事半功倍。同时也可以展现出你做事的认真的态度以及你的专业性&#xff0c;不会显得杂乱无章&#xff0c;管理困难。Git分支规范也是一样。当遵循了某种约定的Git分支&#xff0c;在代…...

ATFX汇评:美7月通胀率数据基本符合预期,美指仍无法站稳103关口

ATFX汇评&#xff1a;据美劳工部&#xff0c;美国7月未季调CPI年率&#xff0c;最新值3.2&#xff0c;高于前值3%&#xff0c;低于预期值3.3%&#xff0c;这标志着连续12个月的下降已经停止&#xff1b;7月未季调核心CPI年率&#xff0c;最新值4.7%&#xff0c;低于前值4.8%&am…...

系统架构设计专业技能 · 软件工程(一)【系统架构设计师】

系列文章目录 系统架构设计高级技能 软件架构概念、架构风格、ABSD、架构复用、DSSA&#xff08;一&#xff09;【系统架构设计师】 系统架构设计高级技能 系统质量属性与架构评估&#xff08;二&#xff09;【系统架构设计师】 系统架构设计高级技能 软件可靠性分析与设计…...

C语言 指针的运算

目录 一、介绍 二、指针 整数 、指针 - 整数 二、指针 - 指针 四、指针的关系运算 一、介绍 在C语言中&#xff0c;指针的运算分为三类 1、指针 整数 、指针 - 整数2、指针 - 指针3、指针的关系运算 二、指针 整数 、指针 - 整数 因为数组在…...

【JAVA基础】- 同步非阻塞模式NIO详解

【JAVA基础】- 同步非阻塞模式NIO详解 文章目录 【JAVA基础】- 同步非阻塞模式NIO详解一、概述二、常用概念三、NIO的实现原理四、NIO代码实现客户端实现服务端实现 五、同步非阻塞NIO总结 一、概述 NIO&#xff08;Non-Blocking IO&#xff09;是同步非阻塞方式来处理IO数据。…...

dingding机器人

“自定义机器人”只支持消息发送&#xff0c;自动回复需要“企业内部机器人” 消息发送 import requests import jsonres requests.post(https://oapi.dingtalk.com/robot/send?access_token036a339axxx,data json.dumps({"text": {"content":"h…...

6.6 实现卷积神经网络LeNet训练并预测手写体数字

模型架构 代码实现 import torch from torch import nn from d2l import torch as d2lnet nn.Sequential(nn.Conv2d(1,6,kernel_size5,padding2),nn.Sigmoid(),#padding2补偿5x5卷积核导致的特征减少。nn.AvgPool2d(kernel_size2,stride2),nn.Conv2d(6,16,kernel_size5),nn.S…...

Django路由Router

文章目录 一、路由router路由匹配命名空间反向解析 二、实践创建用户模型Model添加子路由 - 创建用户首页页面跳转 - 使用反向解析和命名空间1. 不使用命名空间的效果2. 使用命名空间的效果 用户详情页面跳转 - 路由传参路由传递多个参数re_path 以前写法,了解即可重定向Redire…...

蜜蜂路线 P2437

蜜蜂路线 题目背景 无 题目描述 一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你&#xff1a;蜜蜂从蜂房 m 开始爬到蜂房 n&#xff0c;m<n&#xff0c;有多少种爬行路线&#xff1f;&#xff08;备注&#xff1a;题面有误&…...

无脑——010 复现yolov8 使用yolov8和rt detr 对比,并训练自己的数据集

1.配置环境 1. 首先去官网下载yolov8的zip https://github.com/ultralytics/ultralytics 存放在我的目录下G:\bsh\yolov8 然后使用conda创建新的环境 conda create -n yolov8 python3.8 #然后激活环境 conda activate yolov8然后安装pytorch&#xff0c;注意 &#xff0c;py…...

如何给Google Chrome增加proxy

1. 先打开https://github.com/KaranGauswami/socks-to-http-proxy/releases 我的电脑是Liunx系统所以下载第一个 2. 下载完之后把这个文件变成可执行文件&#xff0c;可以是用这个命令 chmod x 文件名 3. 然后执行这个命令&#xff1a; ./sthp-linux -p 8080 -s 127.0.0.1:…...

设计模式——原型模式

原型模式就是有时我们需要多个类的实例&#xff0c;但是一个个创建&#xff0c;然后初始化&#xff0c;这样太麻烦了&#xff0c;此时可以使用克隆&#xff0c;来创建出克隆对象&#xff0c;就能大大的提高效率。具体就是要让此类实现Cloneable接口&#xff0c;然后重写Object类…...

Spring框架中的Bean生命周期

目录 Bean的实例化 BeanFactoryPostProcessor 属性赋值 循环依赖 初始化 处理各种Aware接口 执行BeanPostProcessor前置处理 执行InitializingBean初始化方法或执行init-method自定义初始化方法 执行BeanPostProcessor后置处理 销毁 Spring Bean 的生命周期总体分为…...

async和await修饰符

async和await是JavaScript中用来处理异步操作的关键字 。 async和await也是解决回调地域的终极方案&#xff0c;简单&#xff0c;而Promise链混杂难以看懂。 async关键字用于定义一个函数&#xff0c;使其返回一个Promise对象。这意味着该函数可以通过await关键字来暂停执行&…...

vivado tcl创建工程和Git管理

一、Tcl工程创建 二、Git版本管理 对于创建完成的工程需要Git备份时&#xff0c;不需要上传完整几百或上G的工程&#xff0c;使用tcl指令创建脚本&#xff0c;并只将Tcl脚本上传&#xff0c;克隆时&#xff0c;只需要克隆tcl脚本&#xff0c;使用vivado导入新建工程即可。 优…...

田间农业数字管理系统-高标准农田建设

政策背景 2019年11月&#xff0c;国务院办公厅印发的《国务院办公厅关于切实加强高标准农田建设提升粮食安全保障能力的意见》明确提出&#xff0c;到2022年&#xff0c;全国要建成10亿亩高标准农田。 2021年9月16日&#xff0c;由农业农村部印发的《全国高标准农田建设规划&a…...

2025五大免费变声器推荐!

在游戏开黑时想靠声音搞怪活跃气氛&#xff0c;或是在直播中用独特声线吸引观众&#xff0c;又或者给视频配音时想尝试不同角色 —— 但市面上的变声软件要么收费高昂&#xff0c;要么效果生硬、操作复杂&#xff0c;难道找到一款好用又免费的变声器真的这么难&#xff1f; 今…...

用设计模式重新思考(类FSM)验证:从混乱到优雅

在数字设计的世界里&#xff0c;Finite-State Machine&#xff08;FSM&#xff09;就像一个城市的交通信号系统。每个状态都有自己的规则&#xff0c;每个转换都需要精确的条件。而对于验证工程师来说&#xff0c;如何优雅地验证这些状态机&#xff0c;一直是个让人头疼的问题。…...

2025年,百度智能云打响AI落地升维战

如果说从AI到Agent是对于产品落地形态的共识&#xff0c;那么如今百度智能云打响的恰是一个基于Agent进行TO B行业表达的AI生产力升维战。 在这个新的工程体系能力里&#xff0c;除了之前百度Create大会上提出的面向Agent的RAG能力等通用能力模块&#xff0c;对更为专业、个性…...

Seed1.5-VL登顶,国产闭源模型弯道超车丨多模态模型5月最新榜单揭晓

随着图像、文本、语音、视频等多模态信息融合能力的持续增强&#xff0c;多模态大模型在感知理解、逻辑推理和内容生成等任务中的综合表现不断提升&#xff0c;正在展现出愈发接近人类的智能水平。多模态能力也正在从底层的感知理解&#xff0c;迈向具备认知、推理、决策能力的…...

【递归、搜索与回溯】综合练习(四)

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人递归&#xff0c;搜索与回溯算法的学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码…...

使用C/C++和OpenCV实现图像拼接

使用 C 和 OpenCV 实现图像拼接 本文将详细介绍如何利用 OpenCV 库&#xff0c;在 C 环境中实现图像拼接。图像拼接技术可以将多张具有重叠区域的图像合成为一张高分辨率的全景图。OpenCV 提供了一个功能强大的 Stitcher 类&#xff0c;它封装了从特征点检测、匹配到图像融合的…...

GNSS终端授时方式-合集:PPS、B码、NTP、PTP、单站授时,共视授时

GNSS接收机具备授时功能&#xff0c;能够对外输出高精度的时间信息&#xff0c;并通过多种接口、多种形式进行时间信息的传递。 step by step介绍GNSS卫星导航定位基本原理&#xff0c;为什么定位需要至少4个卫星&#xff1f;这个文章的最后&#xff0c;我们介绍了为什么GNSS接…...

PLSQLDeveloper配置OracleInstantClient连接Oracle数据库

PL/SQLDeveloper配置Oracle Instant Client连接Oracle数据库 文章目录 PL/SQLDeveloper配置Oracle Instant Client连接Oracle数据库 1. Oracle Instant Client下载与配置1. Oracle Instant Client下载2. Oracle Instant Client解压配置1. 解压2. 配置 2. PL/SQL Developer下载、…...

自托管图书搜索引擎Bookologia

简介 什么是 Bookologia &#xff1f; Bookologia 是一个专门的书籍搜索引擎&#xff0c;可以在几秒钟内找到任何书籍。它是开源的&#xff0c;可以轻松自托管在 Docker 上&#xff0c;为用户提供一个简单而高效的书籍查找体验。 主要特点 简洁的用户界面&#xff1a;界面设计…...

Python训练营---Day44

DAY 44 预训练模型 知识点回顾&#xff1a; 预训练的概念常见的分类预训练模型图像预训练模型的发展史预训练的策略预训练代码实战&#xff1a;resnet18 作业&#xff1a; 尝试在cifar10对比如下其他的预训练模型&#xff0c;观察差异&#xff0c;尽可能和他人选择的不同尝试通…...