[万字长文] 从 Vue 3 的项目模板学习 tsconfig 配置

在这里插入图片描述

文章目录

  • 一、`tsconfig.json` 的作用
  • 二、基本介绍
  • 三、Vue 3 的 `tsconfig.json` 的结构分析
    • 1. 总配置 `tsconfig.json`
    • 2. Web 侧 `tsconfig.app.json`
      • a. 继承基础配置
      • b. 包含和排除的文件
      • c. 编译器选项
    • 3. 测试 `tsconfig.vitest.json`
      • a. 继承的基础配置
      • b. 包含和排除的文件
      • c. 编译器选项
      • d. 为什么分开?
    • 4. 命令行环境 `tsconfig.node.json`
      • a. 继承的基础配置
      • b. 包含的文件
      • c. 编译器选项
      • d. 工具配置文件的 TypeScript 支持
      • e. `outDir` 的缺失
  • 四、可能的优化
      • 1. 创建一个配置目录
      • 2. 移动 TypeScript 配置文件
      • 3. 更新文件引用
      • 4. 更新项目中的其他引用
      • 5. 验证更改
  • 总结

前两天写了篇文章,喷 TypeScript 太过难用了,不过难用也得学啊,主要是因为我用过静态强类型语言,在项目规模变大的时候,确实对项目的质量把控是有帮助的,这可能就是后端程序员学习前端的迷信吧。反正我认识一个资深的前端朋友,他就反感且他自己也不会选择 TypeScript,他说自己很有自信能写对,也知道自己在写些什么,好吧。

那么 TypeScript 为什么那么痛苦呢?我觉得根本原因还是 javascript 这个语言,本身是一个弱类型动态语言,原生就不支持类型之类的事情,而 TypeScript 又选择了不破坏它的核心,只是渐进式增补类型到代码里。所以,就处处要照顾原有的一些设定。

好吧好吧,书归正言,本文打算介绍 Vue 3 项目中,如果运用 TypeScript 的话,如何配置 tsconfig.json。上次我们已经从官方脚手架,创建了一个 Vue 3 + TypeScript 的项目,这个脚手架其实很有价值,比如,里面就提供了一套 tsconfig 的配置,通过学习这个配置,我们可以了解一些 TypeScript 在项目中的正确用法。

一、tsconfig.json 的作用

我们在项目中使用 TypeScript 的时候,实际执行还是 javascript,所以要想执行,先需要编译,将代码进行转换:

tsc source.ts

这是处理单个代码文件的时候的做法,不过,一般我们项目里都有成百上千的源码文件,不可能一个一个去处理,这时候就需要用 tsconfig.json 告诉编译器,或者一些处理工具,如何处理 TypeScript 的问题。

通过此配置文件,我们可以告诉编译器,编译的选项,需要处理的文件集合,目标文件的目录等等。

{
  "compilerOptions": {
    "target": "ES5",             // 目标语言的版本
    "module": "commonjs",        // 指定生成代码的模板标准
    "noImplicitAny": true,       // 不允许隐式的 any 类型
    "removeComments": true,      // 删除注释 
    "preserveConstEnums": true,  // 保留 const 和 enum 声明
    "sourceMap": true            // 生成目标文件的sourceMap文件
  },
  "files": [   // 指定待编译文件
    "./src/index.ts"  
  ]
}

这是一个典型的 tsconfig.json

二、基本介绍

tsconfig.json 的顶层字段有:

  • compileOnSave 行为开关
  • compilerOptions 编译选项
  • exclude 排除一些文件
  • extends 继承一份配置
  • files 文件列表
  • include 包括的文件
  • references 项目引用,配置可以切成多块来分别设置
  • typeAcquisition 本项目中的自动类型检查,2.1 以上支持

最重要的是编译选项,常用的一些大概有:

{
  // ...
  "compilerOptions": {
    "incremental": true, // TS编译器在第一次编译之后会生成一个存储编译信息的文件,第二次编译会在第一次的基础上进行增量编译,可以提高编译的速度
    "tsBuildInfoFile": "./buildFile", // 增量编译文件的存储位置
    "diagnostics": true, // 打印诊断信息 
    "target": "ES5", // 目标语言的版本
    "module": "CommonJS", // 生成代码的模板标准
    "outFile": "./app.js", // 将多个相互依赖的文件生成一个文件,可以用在AMD模块中,即开启时应设置"module": "AMD",
    "lib": ["DOM", "ES2015", "ScriptHost", "ES2019.Array"], // TS需要引用的库,即声明文件,es5 默认引用dom、es5、scripthost,如需要使用es的高级版本特性,通常都需要配置,如es8的数组新特性需要引入"ES2019.Array",
    "allowJS": true, // 允许编译器编译JS,JSX文件
    "checkJs": true, // 允许在JS文件中报错,通常与allowJS一起使用
    "outDir": "./dist", // 指定输出目录
    "rootDir": "./", // 指定输出文件目录(用于输出),用于控制输出目录结构
    "declaration": true, // 生成声明文件,开启后会自动生成声明文件
    "declarationDir": "./file", // 指定生成声明文件存放目录
    "emitDeclarationOnly": true, // 只生成声明文件,而不会生成js文件
    "sourceMap": true, // 生成目标文件的sourceMap文件
    "inlineSourceMap": true, // 生成目标文件的inline SourceMap,inline SourceMap会包含在生成的js文件中
    "declarationMap": true, // 为声明文件生成sourceMap
    "typeRoots": [], // 声明文件目录,默认时node_modules/@types
    "types": [], // 加载的声明文件包
    "removeComments":true, // 删除注释 
    "noEmit": true, // 不输出文件,即编译后不会生成任何js文件
    "noEmitOnError": true, // 发送错误时不输出任何文件
    "noEmitHelpers": true, // 不生成helper函数,减小体积,需要额外安装,常配合importHelpers一起使用
    "importHelpers": true, // 通过tslib引入helper函数,文件必须是模块
    "downlevelIteration": true, // 降级遍历器实现,如果目标源是es3/5,那么遍历器会有降级的实现
    "strict": true, // 开启所有严格的类型检查
    "alwaysStrict": true, // 在代码中注入'use strict'
    "noImplicitAny": true, // 不允许隐式的any类型
    "strictNullChecks": true, // 不允许把null、undefined赋值给其他类型的变量
    "strictFunctionTypes": true, // 不允许函数参数双向协变
    "strictPropertyInitialization": true, // 类的实例属性必须初始化
    "strictBindCallApply": true, // 严格的bind/call/apply检查
    "noImplicitThis": true, // 不允许this有隐式的any类型
    "noUnusedLocals": true, // 检查只声明、未使用的局部变量(只提示不报错)
    "noUnusedParameters": true, // 检查未使用的函数参数(只提示不报错)
    "noFallthroughCasesInSwitch": true, // 防止switch语句贯穿(即如果没有break语句后面不会执行)
    "noImplicitReturns": true, //每个分支都会有返回值
    "esModuleInterop": true, // 允许export=导出,由import from 导入
    "allowUmdGlobalAccess": true, // 允许在模块中全局变量的方式访问umd模块
    "moduleResolution": "node", // 模块解析策略,ts默认用node的解析策略,即相对的方式导入
    "baseUrl": "./", // 解析非相对模块的基地址,默认是当前目录
    "paths": { // 路径映射,相对于baseUrl
      // 如使用jq时不想使用默认版本,而需要手动指定版本,可进行如下配置
      "jquery": ["node_modules/jquery/dist/jquery.min.js"]
    },
    "rootDirs": ["src","out"], // 将多个目录放在一个虚拟目录下,用于运行时,即编译后引入文件的位置可能发生变化,这也设置可以虚拟src和out在同一个目录下,不用再去改变路径也不会报错
    "listEmittedFiles": true, // 打印输出文件
    "listFiles": true// 打印编译的文件(包括引用的声明文件)
  }
}

三、Vue 3 的 tsconfig.json 的结构分析

Vue 3 的 Web 项目有什么特点呢?代码会在多种不太的环境运行,也会有多种不同的编译需求。

从配置文件中,我们可以看到,Vue 3 的实现的 App,在线上需要在浏览器运转,但是在测试的时候,需要在命令行环境运转,上线时候不需要测试的代码,所以编译至少有两种需求。

此外,很多配置文件,比如 Vite 的,Vitest 的,都是在命令行运行的,也是用的 ts 作为代码载体,还需要进行一些语法检查,这就又是一套需求。

在这里插入图片描述
可以看到,脚手架项目里,提供了四个 tsconfig.json 文件,如上面解释的那样,每个需求,单独占一个配置文件。

这种结构给我们一种启示,在我们自己的项目里,如果运用了 TypeScript,也可以用这种方法来分拆配置,以提高编译的速度和体验。下面分别介绍一下每个配置文件。

1. 总配置 tsconfig.json

首先,我们来看一下总配置文件 tsconfig.json

{
  "files": [],
  "references": [
    {
      "path": "./tsconfig.node.json"
    },
    {
      "path": "./tsconfig.app.json"
    },
    {
      "path": "./tsconfig.vitest.json"
    }
  ]
}

这个文件使用了 TypeScript 的 references 功能。“项目引用” 允许一个 TypeScript 项目以声明方式,依赖其他 TypeScript 项目。这在大型代码库中尤其有用,可以帮助组织和分隔代码到更小的、可管理的单元,并且还可以提高编译速度和编辑器响应速度。

这里的关键点是 filesreferences 两个属性:

  • files: 在这个例子中,files 数组是空的。这意味着此配置文件本身不直接包含任何 TypeScript 文件。这是因为它作为一个顶层项目配置,用于引用其他的 TypeScript 配置文件,而不是直接处理文件。

  • references: 这个属性包含了一个对象数组,每个对象指向一个不同的 tsconfig 文件。这表明当前项目依赖于这些子项目或配置。每个引用都通过 path 属性指定,指向一个子项目的 tsconfig.json 文件。

    • ./tsconfig.app.json 是为前端应用配置的 TypeScript 设置。
    • ./tsconfig.vitest.json 是为 Vitest 测试框架配置的 TypeScript 设置。
    • ./tsconfig.node.json 是针对 Node.js 环境进行配置的 TypeScript 设置。

使用这种结构的主要好处包括:

  • 代码隔离:不同部分的代码可以有不同的编译设置,例如,前端代码和后端代码可能需要不同的 targetlib 设置。

  • 构建优化:通过只编译改动的项目,可以减少构建时间。TypeScript 可以更智能地处理依赖项,只重新编译那些需要更新的部分。

  • 更好的代码组织:对于大型项目,这种方法可以帮助更好地组织代码,将其分割成较小、更容易管理的部分。

总之,这种方式为大型和模块化的 TypeScript 项目提供了一个更清晰和更可维护的结构。

2. Web 侧 tsconfig.app.json

然后,我们来看看 tsconfig.app.json 的配置文件,这个 app 指的应该就是项目的主体代码,是一个 SPA(单页应用)所以也叫 App。

{
  "extends": "@vue/tsconfig/tsconfig.dom.json",
  "include": ["src/**/*", "src/**/*.vue", "types/**/*.d.ts"],
  "exclude": ["src/**/__tests__/*"],
  "compilerOptions": {
    "composite": true,
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

让我们逐个看看配置中的关键部分及其意义:

a. 继承基础配置

  • "extends": "@vue/tsconfig/tsconfig.dom.json": 这表明该配置继承自一个预设的 TypeScript 配置,专为在 DOM 环境中运行的 Vue 应用程序设计。这个预设可能包含了一套推荐的编译器选项,适用于大多数 Vue 项目,如适当的 lib 选项(比如包含 dom 和其他浏览器环境的类型定义),以及为 Vue 文件和 DOM API 使用的最佳实践。

b. 包含和排除的文件

  • "include": ["src/**/*", "src/**/*.vue", "types/**/*.d.ts"]: 指定了 TypeScript 编译器应该包含哪些文件。这里包括了项目的 src 目录下的所有文件(无论何种扩展名),所有 Vue 组件文件(.vue),以及 types 目录下的所有 TypeScript 声明文件(.d.ts)。这确保了项目中所有相关的文件都将被 TypeScript 处理。

  • "exclude": ["src/**/__tests__/*"]: 排除了所有在 __tests__ 目录下的文件,这通常是单元测试文件所在的地方。这样做可以防止测试文件被编译到生产构建中,同时也可能加快编译过程,因为测试文件不会被 TypeScript 处理。

c. 编译器选项

  • "composite": true: 启用了项目的组合模式,这对于大型项目或者当你想要将项目分割成多个子项目时非常有用。它允许 TypeScript 项目引用其他 TypeScript 项目,便于代码的模块化和重用。

  • "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo": 指定了 TypeScript 构建信息文件的存放位置。这个文件用于存储关于项目的增量编译信息,可以帮助 TypeScript 编译器快速地执行后续的编译,提高构建性能。

  • "baseUrl": ".": 设置了模块解析的基准目录为项目的根目录。这是 paths 映射的基础。

  • "paths": {"@/*": ["./src/*"]}: 提供了一个别名配置,允许在项目中使用 @ 前缀来引用 src 目录下的文件。这是一种常见的做法,可以使得在项目中引用模块时的路径更简洁明了。

总结而言,这个 tsconfig.app.json 配置为前端 Vue 应用提供了一套合理的默认 TypeScript 编译设置,通过继承、文件包含/排除规则和编译器选项来优化开发和构建过程。

3. 测试 tsconfig.vitest.json

然后,我们看一下 tsconfig.vitest.json 的内容:

{
  "extends": "./tsconfig.app.json",
  "exclude": [],
  "compilerOptions": {
    "composite": true,
    "lib": [],
    "types": ["node", "jsdom"]
  }
}

通过比较 tsconfig.app.jsontsconfig.vitest.json 的内容,我们可以明确地看到两者之间的区别,并理解为什么要将它们分开。下面是主要的区别及其潜在的考虑因素:

a. 继承的基础配置

  • tsconfig.app.json: 这个文件继承自 @vue/tsconfig/tsconfig.dom.json,这表明它主要针对在浏览器环境下运行的 Vue 应用程序进行配置。它包含了适用于 DOM 环境的默认配置,比如对 DOM API 的类型检查支持。

  • tsconfig.vitest.json: 这个文件则继承自 tsconfig.app.json,意味着它会沿用应用程序配置的所有设置,但同时它提供了一些特定的调整来适配测试环境。

b. 包含和排除的文件

  • tsconfig.app.json 明确排除了 src/**/__tests__/* 目录,这意味着应用程序的编译过程会忽略测试文件。这有助于保持生产构建的清洁,确保测试代码不会被错误地包含在最终的构建中。

  • tsconfig.vitest.json 移除了 exclude 配置,这表明在进行测试时,所有的文件包括测试文件都会被考虑。这是合理的,因为进行测试时,你会希望包括测试文件及其依赖。

c. 编译器选项

  • tsconfig.app.json 中设置了 compositetrue 并指定了 tsBuildInfoFile 路径,这是为了支持增量编译以提高构建性能。此外,它还配置了 baseUrlpaths 以支持模块的别名导入,这在大型项目中非常有用,可以简化模块引用的路径。

  • tsconfig.vitest.json 同样设置了 compositetrue,但它并没有覆盖 tsBuildInfoFile 的设置,这意味着测试构建也会使用相同的增量编译信息文件。不过,它添加了 libtypes 的设置:

    • lib: 虽然这里显示为空数组,但通常这个选项用于指定编译过程中包含的库文件。如果实际使用中没有指定,可能是因为它依赖于从 tsconfig.app.json 继承来的配置,或者是为了避免与继承的设置冲突。
    • types: 明确包括了 nodejsdom 类型定义。这是因为 Vitest 运行于 Node.js 环境中,并可能模拟 DOM 环境(通过 jsdom),这与浏览器环境下的应用程序开发有所不同。这种配置确保了在测试代码中可以正确地使用 Node.js 和 DOM 的类型定义。

d. 为什么分开?

分开这两个配置文件的主要原因是为了分别优化应用程序构建和测试环境。通过这种方式,可以确保生产构建不会包含测试代码,同时测试环境能够访问特定的类型定义和库,以模拟应用运行的环境。此外,这种分离还允许针对不同的环境使用不同的 TypeScript 编译选项,以最大化性能和效率。

4. 命令行环境 tsconfig.node.json

最后,是 tsconfig.node.json 配置文件:

{
  "extends": "@tsconfig/node20/tsconfig.json",
  "include": [
    "vite.config.*",
    "vitest.config.*",
    "cypress.config.*",
    "nightwatch.conf.*",
    "playwright.config.*"
  ],
  "compilerOptions": {
    "composite": true,
    "noEmit": true,
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",

    "module": "ESNext",
    "moduleResolution": "Bundler",
    "types": ["node"]
  }
}

这个 tsconfig.node.json 配置文件主要针对 Node.js 环境进行配置,并且它似乎专门用于工具和配置文件的 TypeScript 支持。让我们分解这个配置文件的关键部分来理解它的作用:

a. 继承的基础配置

  • "extends": "@tsconfig/node20/tsconfig.json": 这表示该配置文件继承自 @tsconfig/node20 的预设配置,这是一个针对 Node.js 20 的预设 TypeScript 配置。这样的预设配置提供了适合于特定 Node.js 版本的默认编译选项,比如适当的 lib 设置和其他编译器标志,以确保 TypeScript 代码能够兼容该 Node.js 版本。

b. 包含的文件

  • "include": [...]: 通过这个设置,配置文件指定了一系列的工具配置文件(如 Vite、Vitest、Cypress、Nightwatch 和 Playwright 的配置文件),这些文件通常使用 JavaScript 或 TypeScript 编写。包含这些文件意味着 TypeScript 编译器会处理它们,以便进行类型检查和其他 TypeScript 特有的分析。

c. 编译器选项

  • "composite": true: 这个选项启用了项目引用支持,使得该配置可以作为其他 TypeScript 项目的引用。这在大型项目中有助于模块化和代码组织。
  • "noEmit": true: 这表示 TypeScript 编译器将执行类型检查但不输出 JavaScript 代码。这对于配置文件来说是理想的设置,因为你通常不需要将这些 TypeScript 编写的配置文件编译成 JavaScript,它们通常是直接由 Node.js 运行时或相应的工具直接解析执行的。
  • "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo": 指定了增量编译信息文件的路径,这有助于加速连续的编译过程。
  • "module": "ESNext", "moduleResolution": "Bundler": 这些设置指定了模块格式和模块解析策略。尽管 noEmittrue,这些设置仍对类型检查和编辑器支持有影响。
  • "types": ["node"]: 明确包含了 node 类型声明,这对于编写 Node.js 环境下运行的配置文件是必要的,确保所有 Node.js 的 API 在类型检查时可用。

d. 工具配置文件的 TypeScript 支持

对于问及工具配置文件是否需要编译的部分,实际上,当配置文件以 TypeScript 编写时,确实需要一个过程来处理这些文件,以便工具能够理解和使用它们。不过,由于这里 noEmit 被设置为 true,这个过程更多是类型检查而非传统意义上的编译过程。在实际开发流程中,某些工具和框架支持直接执行 TypeScript 文件,或者开发者可能会使用其他方式(如 ts-node)来执行或转换这些 TypeScript 编写的配置文件。

e. outDir 的缺失

由于 "noEmit": true 禁止了文件输出,所以这个配置中不需要也没有指定 outDir。如果在其他场景中,TypeScript 代码需要被编译成 JavaScript,那么 outDir 配置项就会指定编译后的 JavaScript 文件应该存放的目录。

总结而言,这个 tsconfig.node.json 配置文件为 Node.js 环境下的工具和配置文件提供了 TypeScript 支持,主要用于类型检查而非代码编译。

四、可能的优化

看最上面的截图,我们看到项目的根目录下,就有了 4 个 tsconfig.* 的配置文件,这样让根目录显得文件很多很乱。这能不能优化呢?

了解了这个文件的结构后,显然,不难猜到,显然也是可以优化的,比如将所有的子配置文件都放入一个文件夹里,外面只保留一个总配置文件即可。

要整理项目根目录中并列放置的多个 tsconfig 文件,使目录显得更整洁,可以考虑将所有 TypeScript 配置文件移动到一个专门的目录中。这样不仅可以清理根目录,还能保持项目的配置结构清晰和有序。下面是如何实现这一点的步骤:

1. 创建一个配置目录

首先,在项目的根目录下创建一个新的目录来存放所有 TypeScript 配置文件。通常,你可以命名这个目录为 tsconfig 或者 config,或者任何具有描述性且便于理解的名称。

例如,创建一个名为 tsconfigs 的目录:

mkdir tsconfigs

2. 移动 TypeScript 配置文件

然后,将所有的 tsconfig 文件移动到你刚创建的目录中。确保调整这些文件的位置后,更新任何依赖这些文件路径的引用,比如在 package.json 中的脚本命令。

mv tsconfig.json tsconfig.app.json tsconfig.node.json tsconfig.vitest.json tsconfigs/

3. 更新文件引用

如果这些配置文件之间存在相互引用(例如,通过 extends 属性继承另一个配置),你需要更新这些引用以反映新的路径。确保在引用路径中包含新的目录名。

例如,如果 tsconfig.vitest.json 继承了 tsconfig.app.json

// Before
{
  "extends": "./tsconfig.app.json"
}

// After
{
  "extends": "./tsconfigs/tsconfig.app.json"
}

4. 更新项目中的其他引用

此外,如果你的项目中的其他工具或脚本引用了这些 tsconfig 文件(如构建脚本、IDE 配置等),记得更新这些引用路径。

例如,在 package.json 中使用特定的 tsconfig 文件进行构建或测试的命令也应该相应更新:

// Before
"scripts": {
  "build": "tsc -p tsconfig.app.json",
  "test": "vitest --config tsconfig.vitest.json"
}

// After
"scripts": {
  "build": "tsc -p tsconfigs/tsconfig.app.json",
  "test": "vitest --config tsconfigs/tsconfig.vitest.json"
}

5. 验证更改

在完成这些步骤后,确保运行项目的构建和测试命令来验证配置更改是否正确无误。如果遇到路径相关的错误,检查所有更新过的引用是否正确指向新的配置文件路径。

通过这种方式,你可以有效地组织和管理项目的 TypeScript 配置,使得根目录更加整洁,同时保持了配置的可访问性和可维护性。

总结

使用 TypeScript 的项目需要编译配置文件 tsconfig.json,本文详细介绍了配置文件的作用,关键的配置字段简介。以及利用 Vue 3 项目模板,当作案例,详细分析了 tsconfig.json 的用法和最佳实践。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Swiper实现轮播效果

swiper官网&#xff1a;https://3.swiper.com.cn/ <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title&…

苹果的“汽车梦”宣告失败,转战AI?能hold住吗?

文 | BFT机器人 一觉睡醒&#xff0c;苹果就宣布了一件爆炸性的新闻&#xff0c;那就是坚持多年和受到很多行业大佬支持和期待的“泰坦”宣布结束了&#xff01;将原有负责汽车项目的大部分主力军转战到AI核心上&#xff0c;这消息一出&#xff0c;业内外纷纷对苹果的这个决定…

仓储自动化新解:托盘四向穿梭车驶入智能工厂 智能仓储与产线紧密结合

目前&#xff0c;由于对仓库存储量的要求越来越高&#xff0c;拣选、输送以及出入库频率等要求也越来越高&#xff0c;对此&#xff0c;在物流仓储领域&#xff0c;自动化与智能化控制技术得以快速发展&#xff0c;货架穿梭车在自动库领域的应用越来越广泛。现阶段&#xff0c;…

从 iOS 设备恢复数据的 20 个iOS 数据恢复工具

作为 iPhone、iPad 或 iPod 用户&#xff0c;您可能普遍担心自己可能会丢失存储在珍贵 iOS 设备中的所有宝贵数据。数据丢失的原因多种多样&#xff0c;这里列出了一些常见原因&#xff1a; 1. iOS 软件更新 2. 恢复出厂设置 3. 越狱 4. 误操作删除数据 5. iOS 设备崩溃 …

CMake、OpenCV 和单元测试

我写了很多关于 CMake 的文章&#xff0c;如果你感兴趣&#xff0c;可以点击以下链接阅读&#xff1a; CMake VS MakeCMake&#xff1a;在构建世界掀起风暴现代 CMake 使用技巧CMake 交叉编译CMake 生成器已开启 我们将继续对 CMake 的探索&#xff0c;这篇文章技术性高&…

如何解决 C/C++ 编译器优化导致的编译BUG(程序崩溃)支援VC++/CLANG/GCC

本文仅适用于&#xff0c;有愿意、爱捣鼓的童靴。 因编译器优化导致编译BUG&#xff0c;即DEBUG下面无故障稳定工作&#xff0c;但RELESE下程序会在特定函数位置上崩溃。 这要求 C/C 开发人员拥有最基本的素质&#xff0c;需要能够承受&#xff0c;逐行审视编译器输出的目标平…

获取当前数据 上下移动

点击按钮 上下移动 当前数据 代码 // 出国境管理 登记备案人员列表 <template><a-row><a-col span"24"><a-card :class"style[a-table-wrapper]"><!-- 出国境 登记备案人员列表 --><a-table:rowKey"records >…

【Java】查看class文件的jdk编译版本的两种方式

一、使用文本编辑工具EditPlus 使用EditPlus打开该class文件&#xff0c;字符集选择16进制&#xff08;Hex viewer&#xff09;。 仅看第一行数据&#xff0c;前面8个字节CA FE BA BE是固定的。 之后4个字节00 00 是次版本。 次版本后面的4个字节00 34 就是jdk版本。 jdk版本…

Java代码块

Java代码块 普通代码块 普通代码块在对象创建时执行&#xff0c;创建一个对象就会执行一次&#xff0c;可把构造函数中的冗余代码放到普通代码块中 public class Test {public void method() {// 普通代码块{int x 10;System.out.println(x);}public method(){}} }普通代码块…

使用mininet快速入门ONOS路由交换技术与原理-路由篇

上篇文章 《使用mininet快速入门ONOS路由交换技术与原理-交换篇》 使用mininet搭建了一个简单的网络拓扑&#xff0c;并实现了同一交换机下同网段多主机的通信&#xff0c;其中涉及到的通信知识主要以二层mac地址通信为主。 但在芸芸网络的世界中&#xff0c;主机间的通信除了…

Education Codeforces Round 162(Div.2) A~E

A.Moving Chips (思维) 题意&#xff1a; 给一个长度为 n n n的数组 a a a&#xff0c; a i 1 a_i1 ai​1或者 a i 0 a_i0 ai​0&#xff0c;现在可以选择一个 1 1 1&#xff0c;然后将其与左侧最近的 0 0 0交换。询问使得所有的 1 1 1连在一起&#xff0c;中间没有 0 0 0…

Vue+SpringBoot打造不良邮件过滤系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统用户模块2.2 收件箱模块2.3 发件箱模块2.4 垃圾箱模块2.5 回收站模块2.6 邮箱过滤设置模块 三、实体类设计3.1 系统用户3.2 邮件3.3 其他实体 四、系统展示五、核心代码5.1 查询收件箱档案5.2 查询回收站档案5.3 新…

js 面试 1判断变量是否是数组 2 检测数据类型方法

1 是否是数组 1) typeof 检测数据类型运算符 优点&#xff1a;使用简单 缺点&#xff1a;只能检测基本类型&#xff08;除null外&#xff09; console.log(typeof(10)) //Number console.log(typeof(false)) //boolean console.log(typeof(hello)) //string console.log(typeof…

LeetCode 刷题 [C++] 第236题.二叉树的最近公共祖先

题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以…

【网络编程】理解客户端和服务器并使用Java提供的api实现回显服务器

目录 一、网络编程 二、客户端和服务器 三、客户端和服务器的交互模式 四、TCP 和 UDP UDP socket api 的使用 1、DatagramSoket 2、DatagramPacket TCP socket api 的使用 1、ServerSocket 2、Socket 一、网络编程 本质上就是学习传输层给应用层提供的 api&#x…

MySQL之事务详解

华子目录 什么是事务银行转账案例方式1方式2具体操作 事务的四大特性并发事务问题脏读不可重复读幻读 事务的隔离级别查看事务隔离级别设置事务隔离级别 session与global的区别 什么是事务 事务&#xff08;transaction&#xff09;&#xff0c;一个最小的不可再分的工作单元&…

实例:NX二次开发抽取平面以及标准柱面中心线

一、概述 最近体验许多外挂&#xff0c;包括胡波外挂、星空外挂及模圣等都有抽取面的中心线&#xff0c;由于刚刚学习&#xff0c;我尝试看看能不能做出来&#xff0c;本博客代码没有封装函数&#xff0c;代码有待改进&#xff0c;但基本可以实现相应的功能。 二、案例实现的功…

Sora 原理与技术实战笔记一

b 站视频合集 【AIX组队学习】Sora原理与技术实战&#xff1a;Sora技术路径详解 Sora 技术报告&#xff08;OpenAI&#xff09; huggingsd 文生图视频系列的一个开源项目 最强视频生成模型Sora相关技术解析 https://github.com/lichao-sun/SoraReview 惊艳效果&#xff1a; 长…

Ps:路径面板

Ps菜单&#xff1a;窗口/路径 Window/Paths “路径”面板 Paths Panel提供了一系列功能&#xff0c;使用户能够创建、编辑、保存和利用路径。 ◆ ◆ ◆ 路径分类 在“路径”面板上的路径可分为五大类。 常规路径 Saved Path 也称“已保存的路径”&#xff0c;指的是已经存储在…

Python进阶学习:Pandas--DataFrame--如何把几列数据合并成新的一列

Python进阶学习&#xff1a;Pandas–DataFrame–如何把几列数据合并成新的一列 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1…