超全面的前端工程化配置指南

news2024/11/23 21:05:31

前端工程化配置指南

本文讲解如何构建一个工程化的前端库,并结合 Github Actions,自动发布到 Github 和 NPM 的整个详细流程。

示例

我们经常看到像 Vue、React 这些流行的开源项目有很多配置文件,他们是干什么用的?他们的 Commit、Release 记录都那么规范,是否基于某种约定?

废话少说,先上图!

图片

上图标红就是相关的工程化配置,有 Linter、Tests,Github Actions 等,覆盖开发、测试、发布的整个流程。

相关配置清单

  • Eslint

  • Prettier

  • Commitlint

  • Husky

  • Jest

  • GitHub Actions

  • Semantic Release

下面我们从创建一个 TypeScript 项目开始,一步一步完成所有的工程化配置,并说明每个配置含义以及容易踩的坑。

初始化

为了避免兼容性问题,建议先将 node 升级到最新的长期支持版本。

首先在 Github 上创建一个 repo,拉下来之后通过npm init -y初始化。然后创建src文件夹,写入index.ts

package.json 生成之后,我需要添加如下配置项:

   "main": "index.js",
+  "type": "module",
   "scripts": {
     "test": "echo \"Error: no test specified\" && exit 1"
   },
+  "publishConfig": {
+    "access": "public"
+  }

我们将项目定义为ESM规范,前端社区正逐渐向ESM标准迁移,从Node v12.0.0开始,只要设置了 "type": "module", Node 会将整个项目视为ESM规范,我们就可以直接写裸写import/export

publishConfig.access表示当前项目发布到NPM的访问级别,它有 restrictedpublic两个选项,restricted表示我们发布到NPM上的是私有包(收费),访问级别默认为restricted,因为我们是开源项目所以标记为public

配置

创建项目之后,我们开始安装工程化相关的依赖,因为我们是 TypeScript 项目,所以也需要安装 TypeScript 的依赖。

Typescript

先安装 TypeScript,然后使用 tsc 命名生成 tsconfig.json

npm i typescript -D
npx tsc --init

然后我们需要添加修改 tsconfig.json 的配置项,如下:

{
  "compilerOptions": {
    /* Basic Options */
    "baseUrl": ".", // 模块解析根路径,默认为 tsconfig.json 位于的目录
    "rootDir": "src", // 编译解析根路径,默认为 tsconfig.json 位于的目录
    "target": "ESNEXT", // 指定输出 ECMAScript 版本,默认为 es5
    "module": "ESNext", // 指定输出模块规范,默认为 Commonjs
    "lib": ["ESNext", "DOM"], // 编译需要包含的 API,默认为 target 的默认值
    "outDir": "dist", // 编译输出文件夹路径,默认为源文件同级目录
    "sourceMap": true, // 启用 sourceMap,默认为 false
    "declaration": true, // 生成 .d.ts 类型文件,默认为 false
    "declarationDir": "dist/types", // .d.ts 类型文件的输出目录,默认为 outDir 目录
    /* Strict Type-Checking Options */
    "strict": true, // 启用所有严格的类型检查选项,默认为 true
    "esModuleInterop": true, // 通过为导入内容创建命名空间,实现 CommonJS 和 ES 模块之间的互操作性,默认为 true
    "skipLibCheck": true, // 跳过导入第三方 lib 声明文件的类型检查,默认为 true
    "forceConsistentCasingInFileNames": true, // 强制在文件名中使用一致的大小写,默认为 true
    "moduleResolution": "Node", // 指定使用哪种模块解析策略,默认为 Classic
  },
  "include": ["src"] // 指定需要编译文件,默认当前目录下除了 exclude 之外的所有.ts, .d.ts,.tsx 文件
} 

更多详细配置参考:www.typescriptlang.org/tsconfig

注意的点,如果你的项目涉及到WebWorker API,需要添加到 lib 字段中

"lib": ["ESNext", "DOM", "WebWorker"],

然后我们将编译后的文件路径添加到 package.json,并在 scripts 中添加编译命令。

-  "main": "index.js",
+  "main": "dist/index.js",
+  "types": "dist/types/index.d.ts"
   "type": "module",
-   "scripts": {
-     "test": "echo \"Error: no test specified\" && exit 1"
-   },
+   "scripts": {
+     "dev": "tsc --watch",
+     "build": "npm run clean && tsc",
+     "clean": "rm -rf dist"
+  },
   "publishConfig": {
     "access": "public"
   }

types 配置项是指定编译生成的类型文件,如果 compilerOptions.declarationDir 指定的是dist,也就是源码和 .d.ts 同级,那么types可以省略。

验证配置是否生效,在 index.ts 写入

const calc = (a: number, b: number) => {
  return a - b
}
console.log(calc(1024, 28))

在控制台中执行

npm run build && node dist/index.js

会在 dist 目录中生成 types/index.d.tsindex.jsindex.js.map,并打印 996

Eslint & Prettier 

代码规范离不开各种 Linter, 之所以把这两个放在一起讲,借用 Prettier 官网的一句话:“使用 Prettier 解决代码格式问题,使用 linters 解决代码质量问题”。虽然eslint也有格式化功能,但是prettier的格式化功能更强大。

大部分同学编辑器都装了prettier-vscode和eslint-vscode这两个插件,如果你项目只有其中一个的配置,因为这两者部分格式化的功能有差异,那么就会造成一个的问题,代码分别被两个插件分别格式化一次,网上解决prettier+eslint冲突的方案五花八门,甚至还有把整个rules列表贴出来的。

那这里我们按照官方推荐,用最少的配置去解决prettiereslint的集成问题。

Eslint

首先安装 eslint,然后利用 eslint 的命令行工具生成基本配置。

npm i eslint -D
npx eslint --init

执行上面命令后会提示一些选项,我们依次选择符合我们项目的配置。

 

注意,这里 eslint 推荐了三种社区主流的规范,Airbnb、Standard、Google,因个人爱好我选择了不写分号的 Standard规范。

生成的.eslintrc.cjs文件应该长这样

module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true
  },
  extends: [
    'standard'
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 12,
    sourceType: 'module'
  },
  plugins: [
    '@typescript-eslint'
  ],
  rules: {
  }
}

有些同学可能就要问了,这里为什么生成的配置文件名称是.eslintrc.cjs而不是.eslintrc.js

因为我们将项目定义为ESMeslit --init会自动识别type,并生成兼容的配置文件名称,如果我们改回.js结尾,再运行eslint将会报错。出现这个问题是eslint内部使用了require()语法读取配置。

同样,这个问题也适用于其他功能的配置,比如后面会讲到的PrettierCommitlint等,配置文件都不能以xx.js结尾,而要改为当前库支持的其他配置文件格式,如:.xxrc.xxrc.json.xxrc.yml

验证配置是否生效,修改index.ts

  const calc = (a: number, b: number) => {
    return a - b
  }
- console.log(calc(1024, 28))
+ // console.log(calc(1024, 28))

package.json中添加lint命令

  "scripts": {
    "dev": "tsc --watch",
    "build": "npm run clean && tsc",
+   "lint": "eslint src --ext .js,.ts --cache --fix",
    "clean": "rm -rf dist"
  },

然后在控制台执行 lint,eslint将会提示 1 条错误信息,说明校验生效。

npm run lint
# 1:7  error  'calc' is assigned a value but never used  no-unused-vars

因为是 Typescript 项目所以我们还要添加Standard规范提供的 TypeScrip 扩展配置(其他规范同理)

安装eslint-config-standard-with-typescript

npm i eslint-config-standard-with-typescript -D

添加修改 .eslintrc.cjs

    module.exports = {
      env: {
        browser: true,
        es2021: true,
        node: true
      },
-     extends: ['standard']
+     extends: ['standard', 'eslint-config-standard-with-typescript'],
      parser: '@typescript-eslint/parser',
      parserOptions: {
        ecmaVersion: 12,
        sourceType: 'module',
+       project: './tsconfig.json'
      },
      plugins: ['@typescript-eslint'],
      rules: {}
    }

验证配置是否生效

在控制台执行lint,eslint将会提示 2 条错误信息,说明校验生效。

npm run lint
# 1:7  error  'calc' is assigned a value but never used  no-unused-vars
# 1:14 error  Missing return type on function 
Prettier

现在我们按照官网的推荐方式,把 prettier 集成到 eslint 的校验中。

安装 prettier 并初始化配置文件

npm i prettier -D
echo {}> .prettierrc.json

然后在.prettierrc.json添加配置,这里只需要添加和你所选规范冲突的部分。

{
  "semi": false, // 是否使用分号
  "singleQuote": true, // 使用单引号代替双引号
  "trailingComma": "none" // 多行时尽可能使用逗号结尾
}

更多配置详见:prettier.io/docs/en/opt…

安装解决冲突需要用到的两个依赖

  • eslint-config-prettier 关闭可能与 prettier 冲突的规则

  • eslint-plugin-prettier 使用 prettier 代替 eslint 格式化

npm i eslint-config-prettier eslint-plugin-prettier -D

再添加修改 .eslintrc.cjs,如下:

  module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
- extends: ['standard', 'eslint-config-standard-with-typescript'],
+ extends: ['standard', 'eslint-config-standard-with-typescript', 'prettier'],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 12,
    sourceType: 'module',
    project: './tsconfig.json',
  },
- plugins: ['@typescript-eslint'],
+ plugins: ['@typescript-eslint', 'prettier'],
- rules: {},
+ rules: {
+   'prettier/prettier': 'error'
+ },
}

然后验证配置是否生效,修改index.ts

-  const calc = (a: number, b: number) => {
+  const calc = (a: number, b: number): number => {
    return a - b
  }
- // console.log(calc(1024, 28))
+ console.log(calc(1024, 28))

然后在控制台执行lint,这里prettiereslint的行为已保持一致,如果没有报错,那就成功了。

npm run lint

我们现在已经完成了eslintprettier的集成配置。和编辑器无关,也就是说无论你使用什么编辑器,有没有安装相关插件,都不会影响代码校验的效果。

Husky

因为一个项目通常是团队合作,我们不能保证每个人在提交代码之前执行一遍lint校验,所以需要git hooks 来自动化校验的过程,否则禁止提交。

安装Husky并生成.husky文件夹

npm i husky -D
npx husky install

然后我们需要在每次执行npm install时自动启用husky

如果你的npm版本大于等于7.1.0

npm set-script prepare "husky install"

否则手动在package.json中添加

 "scripts": {
    "dev": "tsc --watch",
    "build": "npm run clean && tsc",
    "lint": "eslint src --ext .js,.ts --cache --fix",
    "clean": "rm -rf dist",
+   "prepare": "husky install"
  },

然后添加一个lint钩子

npx husky add .husky/pre-commit "npm run lint"

相当于手动在.husky/pre-commit文件写入以下内容:

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run lint

测试钩子是否生效,修改index.ts

  const calc = (a: number, b: number): number => {
    return a - b
  }
- console.log(calc(1024, 28))
+ // console.log(calc(1024, 28))

然后提交一条commit,如果配置正确将会自动执行lint并提示 1 条错误信息,commit提交将会失败。

git add .
git commit -m 'test husky'
# 1:7  error  'calc' is assigned a value but never used

Commitlint

为什么需要 Commitlint,除了在后续的生成changelog文件和语义发版中需要提取commit中的信息,也利于其他同学分析你提交的代码,所以我们要约定commit的规范。

安装 Commitlint

  • @commitlint/cli Commitlint 命令行工具

  • @commitlint/config-conventional 基于 Angular 的约定规范

npm i @commitlint/config-conventional @commitlint/cli -D

最后将Commitlint添加到钩子

npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'

创建.commitlintrc,并写入配置

{
  "extends": [
    "@commitlint/config-conventional"
  ]
}

注意,这里配置文件名使用的是.commitlintrc而不是默认的.commitlintrc.js,详见 Eslint 章节

测试钩子是否生效,修改index.ts,让代码正确

  const calc = (a: number, b: number): void => {
    console.log(a - b)
  }
- // calc(1024, 28)
+ calc(1024, 28)

提交一条不符合规范的commit,提交将会失败

git add .
git commit -m 'add eslint and commitlint'

修改为正确的commit,提交成功!

git commit -m 'ci: add eslint and commitlint'

Angular 规范说明:

  • feat:新功能

  • fix:修补 BUG

  • docs:修改文档,比如 README, CHANGELOG, CONTRIBUTE 等等

  • style:不改变代码逻辑 (仅仅修改了空格、格式缩进、逗号等等)

  • refactor:重构(既不修复错误也不添加功能)

  • perf:优化相关,比如提升性能、体验

  • test:增加测试,包括单元测试、集成测试等

  • build:构建系统或外部依赖项的更改

  • ci:自动化流程配置或脚本修改

  • chore:非 src 和 test 的修改,发布版本等

  • revert:恢复先前的提交

Jest

美好生活从测试覆盖率 100% 开始。

安装jest,和类型声明@types/jest,它执行需要ts-nodets-jest

这里暂时固定了ts-node的版本为 v9.1.1,新版的ts-node@v10.0.0会导致jest报错,等待官方修复,详见:issues

npm i jest @types/jest ts-node@9.1.1 ts-jest -D

初始化配置文件

npx jest --init

然后修改jest.config.ts文件

   // A preset that is used as a base for Jest's configuration
-  // preset: undefined,
+  preset: 'ts-jest'

将测试命令添加到package.json中。

  "scripts": {
    "dev": "tsc --watch",
    "build": "npm run clean && tsc",
    "lint": "eslint src --ext .js,.ts --cache --fix",
    "clean": "rm -rf dist",
    "prepare": "husky install",
+   "test": "jest"
  },

创建测试文件夹__tests__和测试文件__tests__/calc.spec.ts

修改index.ts

  const calc = (a: number, b: number): number => {
    return a - b
  }
- // console.log(calc(1024, 28))
+ export default calc

然后在calc.spec.ts中写入测试代码

import calc from '../src'

test('The calculation result should be 996.', () => {
  expect(calc(1024, 28)).toBe(996)
})

验证配置是否生效

在控制台执行test,将会看到测试覆盖率 100% 的结果。

npm run test

最后我们给__tests__目录也加上lint校验

修改package.json

  "scripts": {
    "dev": "tsc --watch",
    "build": "npm run clean && tsc",
-   "lint": "eslint src --ext .js,.ts --cache --fix",
+   "lint": "eslint src __tests__ --ext .js,.ts --cache --fix",
    "clean": "rm -rf dist",
    "prepare": "husky install",
    "test": "jest"
  },

这里如果我们直接执行npm run lint将会报错,提示__tests__文件夹没有包含在tsconfig.jsoninclude中,当我们添加到include之后,输出的dist中就会包含测试相关的文件,这并不是我们想要的效果。

我们使用typescript-eslint官方给出的解决方案,如下操作:

新建一个tsconfig.eslint.json文件,写入以下内容:

{
  "extends": "./tsconfig.json",
  "include": ["**/*.ts", "**/*.js"]
}

.eslintrc.cjs中修改

  parserOptions: {
    ecmaVersion: 12,
    sourceType: 'module',
-   project: './tsconfig.json'
+   project: './tsconfig.eslint.json'
  },

然后验证配置是否生效,直接提交我们添加的测试文件,能正确提交说明配置成功。

git add .
git commit -m 'test: add unit test'

Github Actions

我们通过Github Actions实现代码合并或推送到主分支,dependabot机器人升级依赖等动作,会自动触发测试和发布版本等一系列流程。

在项目根目录创建.github/workflows文件夹,然后在里面新建ci.yml文件和cd.yml文件

ci.yml文件中写入:

name: CI

on:
  push:
    branches:
      - '**'
  pull_request:
    branches:
      - '**'
jobs:
  linter:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v2
        with:
          node-version: 16
      - run: npm ci
      - run: npm run lint
  tests:
    needs: linter
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v2
        with:
          node-version: 16
      - run: npm ci
      - run: npm run test

上面配置大概意思就是,监听所有分支的pushpull_request动作,自动执行lintertests任务。

GithubActions 更多用法参考:github.com/features/ac…

然后推送代码,验证配置是否生效

git add .
git commit -m 'ci: use github actions'
git push

此时打开当前项目的 Github 页面,然后点击顶部 Actions 菜单就会看到正在进行的两个任务,一个将会成功(测试),一个将会失败(发布)。

上面只是实现了代码自动测试流程,下面实现自动发布的流程。

在此之前需要到NPM网站上注册一个账号(已有可忽略),并创建一个package

然后创建GH_TOKENNPM_TOKEN(注意,不要在代码中包含任何的 TOKEN 信息):

  • 如何创建 GITHUB\_TOKEN(创建时勾选 repo 和 workflow 权限)

  • 如何创建 NPM\_TOKEN(创建时选中 Automation 权限)

将创建好的两个TOKEN添加到项目的 Actions secrets 中:

Github 项目首页 -> 顶部 Settings 菜单 -> 侧边栏 Secrets

然后修改package.json中的“name”“name”就是你在NPM上创建的package的名称。

cd.yml文件中写入:

name: CD

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main
jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v2
        with:
          node-version: 16
      # https://github.com/semantic-release/git/issues/209
      - run: npm ci --ignore-scripts
      - run: npm run build
      - run: npx semantic-release
        env:
          GH_TOKEN: ${{ secrets.GH_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

由于“黑命贵”,Github 已将新项目的默认分支名称更改为 “main”,详见:issues, 为了方便,后面统一称为 主分支

所以如果你的主分支名称是“main”,上面的branches需要修改为:

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

然后安装语义发版依赖,需要用到semantic-release和它的插件:

  • semantic-release:语义发版核心库

  • @semantic-release/changelog:用于自动生成 changelog.md

  • @semantic-release/git:用于将发布时产生的更改提交回远程仓库

npm i semantic-release @semantic-release/changelog @semantic-release/git -D

在项目根目录新建配置文件.releaserc并写入:

{
  "branches": ["master"],
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    "@semantic-release/changelog",
    "@semantic-release/github",
    "@semantic-release/npm",
    "@semantic-release/git"
  ]
}

这里同样,如果你的主分支名称是“main”,上面的branches需要修改为:

  "branches": ["+([0-9])?(.{+([0-9]),x}).x", "main"],

最后新建分支 develop 分支并提交工作内容。

git checkout -b develop
git add .
git commit -m 'feat: complete the CI/CD workflow'
git push --set-upstream origin develop
git push

然后将 develop 分支合并到 主分支,并提交,注意:这个提交会触发测试并 发布版本 (自动创建tagchangelog)

git checkout master
git merge develop
git push

完成上面操作之后,打开 Github 项目主页 和 NPM 项目主页 可以看到一个 Release 的更新记录。

最后切回到 develop 分支,创建一个自动更新依赖的workflow

.github文件夹中创建dependabot.yml文件,并写入内容:

version: 2
updates:
  # Enable version updates for npm
  - package-ecosystem: 'npm'
    # Look for `package.json` and `lock` files in the `root` directory
    directory: '/'
    # Check the npm registry for updates every day (weekdays)
    schedule:
      interval: 'weekly'

提交并查看 workflows 是否全部通过,再合并到 主分支 并提交,这个提交不会触发版本发布。

git pull origin master
git add .
git commit -m 'ci: add dependabot'
git push 

git checkout master
git merge develop
git push

触发版本发布需要两个条件:

  1. 只有当pushpull_request到 主分支 上才会触发版本发布

  2. 只有commit前缀为featfixperf才会发布,否则跳过。

更多发布规则,详见:https://github.com/semantic-release/commit-analyzer

SemanticRelease 使用方式,详见:semantic-release.gitbook.io

如果你能正确配置上面所有步骤,并成功发布,那么恭喜你!你拥有了一个完全自动化的项目,它拥有:自动依赖更新、测试、发布,和自动生成版本信息等功能。

完整的项目示例:https://github.com/molvqingtai/event-hub

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

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

相关文章

Typora+PicGo+Github+CSDN梦幻联动

文章目录 一、快速搭建个人免费图床二、Typora图片实现自动上传三、Typora图片上传到CSDN出现错误 一、快速搭建个人免费图床 之前写过一篇 快速搭建个人免费图床 的文章,但是每次都要把图片拖到PicGo里面才能生成链接很麻烦,而且在本地用Typora写的文章…

C++ —— Tinyxml2在Vs2017下相关使用2(较文1更复杂,附源码)

相关链接 C —— Tinyxml2在Vs2017下相关使用1(附源码) tinyxml2简介 TinyXML2是一个简单,小巧,高效,CXML解析器,可以很容易地集成到其他程序中。TinyXML-2解析一个XML文档,并从中构建一个 可以…

强化学习章节脉络

强化学习是在求解最优策略

Python爬虫:制作一个属于自己的IP代理模块

前言 在Python爬虫过程中,为了避免被网站的反爬虫机制干扰,我们需要使用IP代理。所谓IP代理,就是通过修改网络请求中的IP地址,来达到隐藏真实IP地址的效果。本文将教你如何制作一个自己的IP代理模块,让你的爬虫更加稳…

网络库OKHttp(1)流程

序、慢慢来才是最快的方法。 背景 OkHttp 是一套处理 HTTP 网络请求的依赖库,由 Square 公司设计研发并开源,目前可以在 Java 和 Kotlin 中使用。对于 Android App 来说,OkHttp 现在几乎已经占据了所有的网络请求操作。 OKHttp源码官网 版…

8.14 PowerBI系列之DAX函数专题-分析客户购买行为

需求 实现 其实如果同时输出订单号的情况下,可以通过订单号出现的次数判断同一订单中同时购买与否的关系。 同时购买了A和B的客户 var v_cust_1 calculatetable(values(客户表[客户姓名]),filter(订单表,订单表[产品编号] "off-pa-10001970")) var v…

2016款奔驰C200车COMAND显示屏黑屏

作者:中鑫之宝鹤壁店 赵玉宾 赵玉宾,从事汽车维修工作9年,现任中鑫之宝汽车服务有限公司鹤壁分公司高级维修技师。 故障现象 一辆2016款奔驰C200车,搭载274发动机,累计行驶里程约为7万km。车主反映,车辆行…

亚马逊、eBay,速卖通,国际站买家账号支付异常问题解决方法

如何解决下单被砍、封号问题,建议采取以下措施: 买家账号下单,不单纯只是解决支付卡、IP问题就可以了,因为平台大数据风控点很多, 我们防关联具体要解决几个问题 一:要硬件参数的关联、安全码、地区码、…

【定时开关机】windows 10 如何设置定时开关机

一、需求 二、场景 三、思路 四、实现 A. 设置来电开机 B. 设置及定时关机 一、需求 需要一台 win 10 的电脑在工作时间内自动开关机(早 8:30 - 晚:6:05) 二、场景 开机:早 8:30 关机:晚 6:05 三、思路 【开机…

github 终端克隆操作,以及对 https/ssh 的理解

前言 最近瞎搞 github 的一些配置,结果搞得有一段时间克隆不了仓库。不过经历了这次风波后,我对 github 的一些原理有了更清楚的了解。所以想稍微写一小篇文章总结输出一下,也欢迎有疑问的读者与博主进一步交流,我的理解还是有限…

2023年中国钢卷尺产量、销量、市场均价及市场规模分析[图]

卷尺是日常生活中常用的工量具,是家庭必备工具之一。鲁班尺、风水尺、文公尺同样属于钢卷尺。钢卷尺是建筑和装修常用工具。钢卷尺可分为,自卷式卷尺、制动式卷尺、摇卷式卷尺。钢卷尺的其他名称有:钢皮卷尺、钢盒尺。 钢卷尺市场已经告别了以…

什么是库存管理?无需Excel,2023年这几款大热库存管理软件你get了吗?

什么是库存管理?库存管理是什么意思?都有哪些好用的库存管理系统?相信这些都是大家非常关注的话题,这篇就跟大家详细唠唠什么是库存管理,都用什么系统可以进行库存管理,并且为大家盘点2023年这几款大热库存…

和硕首次参加展OCP 峰会,将发布多项AI合作项目产品 | 百能云芯

电子代工大厂和硕联合科技宣布,将参与今年的 OCP 全球峰会 (OCP Global Summit),展示与英伟达 (NVIDIA) 合作成果,包含使用英伟达 GH200 Grace Hopper 超级芯片的 MGX AI 服务器,以及搭载 A100、L40 等服务器产品。 OCP 峰会于 10…

斯坦福JSKarel编程机器人使用介绍

斯坦福JSKarel编程机器人使用介绍 为了避免被编程语言固有的复杂性所困扰,有一个被称为卡雷尔(Karel)机器人的微型世界(microworld)的简化环境,可以让编程初学者从中学习理解编程的基本概念,而…

GaussDB for openGauss部署形态

前言 华为云数据库GaussDB是华为自主创新研发的分布式关系型数据库,具有高性能、高可用、高安全、低成本的特点,本文带你详细了解GaussDB数据库的部署形态。 1、GaussDB部署形态三种类型 GaussDB部署形态:单机 独立部署是将数据库组件部署…

10.17课上(七段显示器,递归异或与电路)

异或的递归与数电实现 用二选一选择器实现异或函数 在异或当中,如果有一项为0,就可以把那一项消掉;如果有一项为1,就是把剩下的所有项运算完的结果取反 (由此在算法当中可以采用递归解决) 当w1为0时&…

电脑蓝牙与ESP32蓝牙连接,让电脑发现ESP32

win11蓝牙默认只查看常见蓝牙设备。ESP32创建的蓝牙很有可能是看不到的。 再蓝牙设备发现一栏选择高级&#xff0c;才能查看所有蓝牙设备。 只要下面几行代码&#xff0c;就能让PC发现ESP32 #include <BLEDevice.h> // 引入相关库void setup() {BLEDevice::init("…

使用 PDB Alignment Tool 对 PDB 中多个蛋白结构进行比对

0. 说明&#xff1a; 利用 PDB 提供的在线工具 PDB Alignment Tool (https://www.rcsb.org/alignment) 对 PDB 中多个蛋白进行结构比对&#xff0c;并将比对结果输出&#xff0c;用于后续计算不同链上氨基酸之间的距离。 1. 步骤&#xff08;以 3GBM_A, 3FKU_A 和 2FK0_A 为例…

Linux学习——进程状态

目录 一&#xff0c;进程状态 1&#xff0c;进程状态的分类 2.状态的本质 3.进程状态详解 1.运行状态 2.阻塞状态 3.挂起状态 4.Linux内核中的状态分类 一&#xff0c;进程状态 1&#xff0c;进程状态的分类 如下图&#xff1a; 在计算机中我们的状态的分类便如下图所示…

16-k8s-configMap配置管理中心

文章目录 一、相关概念二、基于目录创建configMap三、基于文件创建configMap四、基于自定义参数创建configMap五、configMap使用六、configMap热更新 一、相关概念 简介 为了解决传统容器中配置的挂载、变更、管理等问题&#xff0c;在k8s中引入了一个叫做configmap的资源对象&…