React 低代码项目:项目创建

embedded/2025/1/31 21:19:53/

Date: January 29, 2025

项目创建

思路:

  • 使用 Create-React-App 创建 React 项目
  • 使用 Vite 创建 React 项目
  • 使用 eslint prettier husty 等,制定编码规则


创建项目

注:在这之前,推荐 node 版本:node/18.20.6 ,否则会遇到各种兼容性bug

## 使用 npx
npx create-react-app my-app --template typescript## 使用 npm
npm init react-app my-app --template typescript

**项目结构:**项目入口 src/App.js

启动项目:npm start


📒 笔记:

npm 和 npx 的区别:

  • npm 更侧重于包的管理和维护。
  • npx 则专注于命令行工具的即时执行和跨项目的一次性操作。
npmnpx
用途管理和安装包临时执行包
是否需要安装需要先 npm install不需要安装,直接运行
作用范围主要用于项目依赖主要用于 CLI 工具
示例npm install -g eslint eslint .npx eslint .(无需全局安装)


问题修复

文件系统操作冲突

问题快照:

image.png

问题分析:

这个错误信息表明在使用 npxcreate-react-app 创建新的 React 应用时,出现了由于文件系统操作(特别是重命名)导致的权限或存在冲突的问题。具体而言,npm 在尝试重命名缓存目录中的某个文件时遇到了文件已经存在的问题。同时,还涉及到权限不足的情况。

错误码和系统调用:

  • npm ERR! code EEXIST:表示在进行文件操作时,目标路径已经存在同名文件。这通常出现在尝试创建、移动或重命名一个文件到一个已经存在的文件路径时。
  • npm ERR! syscall rename:指出失败的系统调用是 rename,即在尝试重命名一个文件路径的时候发生错误。

解决方案:

  1. 清理 npm 缓存

使用 npm cache clean --force 来强制清理 npm 缓存。这可以解决由缓存文件损坏引起的问题。

npm cache clean --force
  1. 检查并修复权限问题
  • 确保您具有对 .npm 目录的正确权限。有时候因为之前的安装操作以 root 用户执行导致现在的用户权限不足。

  • 使用以下命令更改 .npm 目录的所有权:

    sudo chown -R $(whoami) ~/.npm
    
  • 如果您在全局安装包时遇到权限问题,可以考虑使用 nvm(Node Version Manager)来管理 Node.js 和 npm,以避免使用 sudo。

  1. 删除冲突文件
  • 手动删除错误信息中提到的具体路径上的冲突文件:
rm -rf /Users/nathanchen/.npm/_cacache/content-v2/sha512/30/8b/3c91d31ffce7e8ab92600bb41d5442612d23c9ac1ad212415b7d768686fe6cc3a56ae156e64fa442b6f60b1be83eb0c02eb87bbaaf76e4a44351555f
  1. 使用 -force 参数重新运行命令
  • 使用 -force 参数来强制覆盖现有文件,不过这需要谨慎,因为它可能会覆盖掉重要文件。

  • 修改命令如下:

    npx create-react-app my-app --template typescript --force
  1. 确保 npm 和 Node.js 是最新的
  • 更新 npm 到最新版本,这样能避免已知的旧版本问题:

    npm install -g npm@latest
  • 确保 Node.js 也是最新稳定版,可以从官方网站下载更新版本。

  1. 查看详细日志
  • 查看完整的日志文件 /Users/nathanchen/.npm/_logs/2025-01-30T05_48_04_261Z-debug-0.log,以获取更多信息和上下文,帮助诊断特定问题。

这里我采用 清理 npm 缓存 成功解决问题,从而项目可以正常创建

nathanchen@192 wenjuan-nathan % sudo npm cache clean --force        
Password:
npm WARN using --force Recommended protections disabled.

注:记得采用 sudo 来获取权限创建


OpenSSL加密算法不兼容

问题快照:

Error: error:0308010C:digital envelope routines::unsupportedat new Hash (node:internal/crypto/hash:68:19)at Object.createHash (node:crypto:138:10)at module.exports (/Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/webpack/lib/util/createHash.js:90:53)at NormalModule._initBuildHash (/Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/webpack/lib/NormalModule.js:401:16)at handleParseError (/Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/webpack/lib/NormalModule.js:449:10)at /Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/webpack/lib/NormalModule.js:481:5at /Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/webpack/lib/NormalModule.js:342:12at /Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/loader-runner/lib/LoaderRunner.js:373:3at iterateNormalLoaders (/Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/loader-runner/lib/LoaderRunner.js:214:10)at iterateNormalLoaders (/Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/loader-runner/lib/LoaderRunner.js:221:10)at /Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/loader-runner/lib/LoaderRunner.js:236:3at runSyncOrAsync (/Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/loader-runner/lib/LoaderRunner.js:130:11)at iterateNormalLoaders (/Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/loader-runner/lib/LoaderRunner.js:232:2)at Array.<anonymous> (/Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/loader-runner/lib/LoaderRunner.js:205:4)at Storage.finished (/Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:55:16)at /Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:91:9
/Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/react-scripts/scripts/start.js:19throw err;^Error: error:0308010C:digital envelope routines::unsupportedat new Hash (node:internal/crypto/hash:68:19)at Object.createHash (node:crypto:138:10)at module.exports (/Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/webpack/lib/util/createHash.js:90:53)at NormalModule._initBuildHash (/Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/webpack/lib/NormalModule.js:401:16)at /Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/webpack/lib/NormalModule.js:433:10at /Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/webpack/lib/NormalModule.js:308:13at /Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/loader-runner/lib/LoaderRunner.js:367:11at /Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/loader-runner/lib/LoaderRunner.js:233:18at context.callback (/Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/loader-runner/lib/LoaderRunner.js:111:13)at /Users/nathanchen/Documents/1Front-End/前端开发/Projects/wenjuan/源码/wenjuan-nathan/my-app/node_modules/babel-loader/lib/index.js:51:103 {opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],library: 'digital envelope routines',reason: 'unsupported',code: 'ERR_OSSL_EVP_UNSUPPORTED'
}Node.js v21.4.0

问题分析:

  1. 错误代码和信息
    • 错误信息 Error: error:0308010C:digital envelope routines::unsupported 以及 ERR_OSSL_EVP_UNSUPPORTED 指向了 OpenSSL 的加密相关功能。
    • digital envelope routines 是 OpenSSL 中用于加密和解密操作的一部分,表明问题与加密算法相关。
  2. Node.js 系统内部调用
    • 错误栈中的 at new Hash (node:internal/crypto/hash:68:19)at Object.createHash (node:crypto:138:10) 显示了错误发生在 Node.js 自身的加密模块中,这是一个明确的信号,指出问题与加密哈希创建有关。
  3. OpenSSL 相关的错误信息
    • opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ] 提供了进一步的证据,指出这个问题是由于加密库初始化失败引起的。

解决方案:

  1. 降级 Node.js 版本

    • 使用 nvm (Node Version Manager)切换到稍微旧一点的 Node.js 版本,比如 16.x 或 14.x。

    • 例如:

      nvm install 16
      nvm use 16
  2. 设置环境变量以禁用 OpenSSL 3.0 的严格模式

    • 可以通过在运行命令前设置环境变量来临时规避该问题。

    • 在终端中执行以下命令:

      export NODE_OPTIONS=--openssl-legacy-provider
      npm start
    • 或者将其添加到你的项目的 package.jsonscripts 中:

      "scripts": {"start": "export NODE_OPTIONS=--openssl-legacy-provider && react-scripts start"
      }
  3. 确保所有依赖项是最新的

    • 更新所有与项目相关的包,因为较新的版本可能已经修复了与 OpenSSL 3.0 不兼容的问题。

    • 运行以下命令更新:

      npm update
  4. 检查特定于 Webpack 的问题

    • 有时候,特定版本的 Webpack 对某些配置或插件的支持可能不完整,查看 Webpack 和相关插件的文档,确认是否有已知问题和修复。

这里我采用降级 Node 版本来解决,采用 node/16.19.0 版本




编码规范

高质量代码特点:

  • 严格编码规范(靠工具、流程,而非自觉)
  • 合理、规范的注释
  • 代码合理拆分

采用工具:

  • eslint- 检查语法语义,如变量未定义、定义未使用
  • prettier - 检查编码风格,如每一行末尾是否加分号


eslint

安装插件:

npm install eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin -save-dev

初始化配置文件 .eslint.js

npx eslint --init

配置清单:

@eslint/create-config: v1.4.0✔ How would you like to use ESLint? · problems
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · react
✔ Does your project use TypeScript? · typescript
✔ Where does your code run? · browser
The config that you've selected requires the following dependencies:eslint, globals, @eslint/js, typescript-eslint, eslint-plugin-react
✔ Would you like to install them now? · No / Yes
✔ Which package manager do you want to use? · npm
☕️Installing...

笔记:

eslint pluginextend 的区别:

  • extend 提供的是 eslint 现有规则的一系列预设
  • plugin 则提供了除预设之外的自定义规则,当你在 eslint 的规则里找不到合适的的时候就可以借用插件来实现了

安装插件 eslint ,此时就可以看到代码 App.txs 中的错误提示(如定义一个未使用的变量)

package.json 中增加 scripts "lint": " eslint 'src/**/*.+(js|ts|jsx|tsx)' "

控制台运行 npm run lint 也可以看到错误提示。如果要自动修复,可以加 --fix 参数


eslint.config.mjs.eslintrc.js

在使用 npx eslint --init 初始化 ESLint 配置时,你可能会注意到生成的配置文件是 eslint.config.mjs 而不是传统的 .eslintrc.js

.eslintrc.js

  1. CommonJS 模块.eslintrc.js 文件使用的是 CommonJS 模块语法,适用于 Node.js 环境。这意味着你可以使用 require 来导入模块,并使用 module.exports 导出配置。
  2. 传统用法.eslintrc.js 是 ESLint 长期以来默认推荐的配置文件格式之一,广泛使用并兼容多数项目。
  3. 灵活性:支持动态计算或条件逻辑,因为它是一个标准的 JavaScript 文件,你可以编写任何合法的 JavaScript 代码。

eslint.config.mjs

  1. ECMAScript 模块 (ESM)eslint.config.mjs 使用的是 ECMAScript 模块语法,这是现代 JavaScript 标准。使用 importexport 语法进行模块管理。
  2. 现代化趋势:随着 Node.js 在较新版本中对 ESM 的支持增强,ESLint 也开始转向支持这种更现代的模块系统。这与 JavaScript 生态系统整体向 ESM 的迁移一致。
  3. 文件扩展名.mjs 扩展名明确表明该文件使用的是 ECMAScript 模块语法,这对于某些工具和运行环境可以自动识别和处理。

总之,两者都可以用于配置 ESLint,只是在模块规范和文件格式上有所不同。选择哪个取决于你的项目环境以及对现代 JavaScript 特性的需求。



prettier

安装插件:

npm install prettier eslint-config-prettier eslint-plugin-prettier -save-dev
  • eslint-config-prettier 禁用所有和 Prettier 产生冲突的规则
  • eslint-plugin-prettier 把 Prettier 应用到 Eslint,配合 rules "prettier/prettier": "error" 实现 Eslint 提醒。

安装 vscode 插件 prettier ,此时可以看到代码 App.txs 中的格式提示(如末尾是否使用 ; ,或单引号、双引号)

插件配置:

1-配置 eslint 配置文件的 extends

import globals from 'globals'
import pluginJs from '@eslint/js'
import tseslint from 'typescript-eslint'
import pluginReact from 'eslint-plugin-react'
import prettierPlugin from 'eslint-plugin-prettier'
import prettierConfig from 'eslint-config-prettier'/** @type {import('eslint').Linter.Config[]} */
export default [{ files: ['**/*.{js,mjs,cjs,ts,jsx,tsx}'] },{ languageOptions: { globals: globals.browser } },pluginJs.configs.recommended,...tseslint.configs.recommended,pluginReact.configs.flat.recommended,// 添加 Prettier 规则{plugins: { prettier: prettierPlugin },rules: {...prettierConfig.rules, // 兼容 Prettier'prettier/prettier': 'warn', // 显示 Prettier 格式化建议},},
]

2-在 package.json 中增加 scripts:

"format": " prettier --write 'src/**/*.+(js|ts|jsx|tsx)' " 

控制台运行 npm run format 可以修复所有的格式错误

3-设置 vscode .vscode/settings.json 自动保存格式,可以在文件保存时,自动保留格式

{"editor.codeActionsOnSave": {"source.fixAll.eslint": true}
}

4-项目中增加配置文件 .prettierrc.json 规定自己的编码格式,运行 npm run format 可以看到效果,保存文件也可以看到效果。

{"arrowParens": "avoid","bracketSpacing": true,"endOfLine": "lf","jsxBracketSameLine": false,"printWidth": 100,"proseWrap": "preserve","semi": false,"singleQuote": true,"tabWidth": 2,"useTabs": false,"trailingComma": "es5","parser": "typescript"
}
// 箭头函数只有一个参数的时候可以忽略括号
arrowParens: "avoid",
// 括号内部不要出现空格
bracketSpacing: true,
// 行结束符使用 Unix 格式
endOfLine: "lf",
// true: Put > on the Last Line instead of at a new Line
jsxBracketSameLine: false,
// 行宽
printWidth: 100,
// 换行方式
proseWrap: "preserve",
// 分号
semi: false,
// 使用单引号
singleQuote: true,
// 缩进
tabWidth: 2,
// 使用 tab 缩进
useTabs: false,
// 后置逗号,多行对象、数组在最后一行增加逗号
trailingComma: "es5",
// 解析器
parser: "typescript"

注意:如果此处没效果,可以重启 vscode 再重试。


注意事项:

一直搞不定,重启 vscode 就好了。在 vscode 搜“prettier” 插件时,发现一个 “reload required” 的提示,于是就重启了

  • CRA 创建的项目,配置文件是 js 格式
  • vite 创建的项目,配置文件是 cjs 格式



流程管理

github管理项目:

echo "# LowCode" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin git@github.com:NathanCh3n/LowCode.git
git push -u origin main


husky

介绍:

  • 一个 git hook 工具
  • 在 git commit 之前执行自定义的命令
  • 如执行代码风格的检查,避免提交非规范代码

安装依赖:

npm install husky -save-dev

增加三个 pre-commit 命令

npm run lint
npm run format
git add .

通过命令加:

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

或者通过项目中 .husky 文件来配置

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"npm run lint
npm run format
git add .

测试:

可以故意制造一个错误:定义一个未使用变量(eslint 配置文件 rules 增加 'no-unused-vars': 'error',),然后执行 git commit 试试

参考文档:

https://github.com/typicode/husky



commit-lint

**介绍:**用于限制 commit 的提交规范

安装:

npm install --save-dev @commitlint/cli

配置:

.husky 下新增 commit-msg 文件

# Add commit message linting to commit-msg hook
echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg

笔记:

commit 规则可以查看

node_modules/@commitlint/config-conventional (在 commitlint.config.js 中有配置)

image.png

尝试 git commit -m "test" 会失败,再尝试 git commit -m "chore: commit lint" 会成功

参考文档:

https://github.com/conventional-changelog/commitlint#getting-started




附录:package.json

推荐node版本:node/18.20.6

{"name": "my-app","version": "0.1.0","private": true,"dependencies": {"@testing-library/jest-dom": "^5.16.5","@testing-library/react": "^13.4.0","@testing-library/user-event": "^13.5.0","@types/jest": "^27.5.2","@types/node": "^16.18.11","@types/react-dom": "^18.0.10","ahooks": "^3.7.4","ajv": "^8.17.1","ajv-keywords": "^5.1.0","antd": "^5.2.2","classnames": "^2.3.2","formik": "^2.2.9","immer": "^9.0.19","react": "^18.2.0","react-dom": "^18.2.0","react-hook-form": "^7.43.1","react-scripts": "5.0.1","sass": "^1.58.0","styled-components": "^5.3.6","styled-jsx": "^5.1.2","typescript": "^4.9.5","web-vitals": "^2.1.4"},"scripts": {"start": "react-scripts start","build": "react-scripts build","test": "react-scripts test","eject": "react-scripts eject","lint": " eslint 'src/**/*.+(js|ts|jsx|tsx)' ","format": " prettier --write 'src/**/*.+(js|ts|jsx|tsx)' ","prepare": "husky install"},"eslintConfig": {"extends": ["react-app","react-app/jest"]},"browserslist": {"production": [">0.2%","not dead","not op_mini all"],"development": ["last 1 chrome version","last 1 firefox version","last 1 safari version"]},"devDependencies": {"@commitlint/cli": "^17.4.2","@commitlint/config-conventional": "^17.4.2","@types/react": "^19.0.8","@types/styled-components": "^5.1.26","@typescript-eslint/eslint-plugin": "^5.50.0","@typescript-eslint/parser": "^5.50.0","eslint": "^8.33.0","eslint-config-prettier": "^8.6.0","eslint-plugin-prettier": "^4.2.1","eslint-plugin-react": "^7.32.2","husky": "^8.0.3","prettier": "^2.8.3"}
}

http://www.ppmy.cn/embedded/158452.html

相关文章

股指期货的基差套利有什么样的风险?

基差说的就是期货价格减去现货价格的那个差。如果期货价格比现货价格高&#xff0c;咱们就叫它升水&#xff1b;反过来&#xff0c;期货价格比现货价格低&#xff0c;那就是贴水。股指期货和股票现货&#xff0c;它们之间有个默契&#xff0c;那就是到了期货交割日&#xff0c;…

消息队列:春招面试的重要知识模块

在之前的文章中&#xff0c;我们深入探讨了 Redis 缓存&#xff0c;了解了它的数据结构、应用场景以及缓存淘汰策略&#xff0c;这对于提升系统性能起到了关键作用。而在现代分布式系统中&#xff0c;消息队列同样是不可或缺的组件。消息队列能够实现系统间的异步通信、解耦以及…

视频外绘技术总结:Be-Your-Outpainter、Follow-Your-Canvas、M3DDM

Diffusion Models专栏文章汇总:入门与实战 前言:视频Inpaint的技术很火,但是OutPaint却热度不高,这篇博客总结比较经典的几篇视频Outpaint技术。其实Outpaint在runway等工具上很火,可是学术界对此关注比较少,博主从这三年的顶会中找到了最具代表性的三篇论文解读。 目录 …

【C++】类和对象

面向对象编程 学习过C语言的小伙伴知道&#xff1a;C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。 面向过程编程也叫结构化编程。虽然结构化编程的理念提高了程序的清晰度&#xff0c;可靠性&#xff0c…

灰色预测模型

特点&#xff1a; 利用少量、不完全的信息 预测的是指数型的数值 预测的是比较近的数据 灰色生成数列原理&#xff1a; 累加生成&#xff1a; 累减生成&#xff1a;通过累减生成还原成原始数列。 加权相邻生成&#xff1a;&#xff08;会更接近每月中旬&#xff0c;更推荐…

粒子群算法 笔记 数学建模

引入: 如何找到全局最大值&#xff1a;如果只是贪心的话&#xff0c;容易被局部最大解锁定 方法有&#xff1a;盲目搜索&#xff0c;启发式搜索 盲目搜索&#xff1a;枚举法和蒙特卡洛模拟&#xff0c;但是样例太多花费巨量时间 所以启发式算法就来了&#xff0c;通过经验和规…

【VASP】AIMD计算总结

【VASP】AIMD计算总结 vasp 计算文件INCAR 参数介绍后处理 二维材料与异质结的构造除了筛选优势还应该判断是否稳定&#xff0c;所以我在这分享一篇基于vasp6.2计算的AIMD 示例&#xff1a; https://www.vasp.at/wiki/index.php/Liquid_Si_-_Standard_MD vasp 计算文件 POSCA…

2025年美赛B题-结合Logistic阻滞增长模型和SIR传染病模型研究旅游可持续性-成品论文

模型设计思路与创新点&#xff1a; 建模的时候应该先确定我们需要建立什么类的模型&#xff1f;优化类还是统计类&#xff1f;这个题需要大量的数据分析&#xff0c;因此我们可以建立一个统计学模型。 统计学建模思路&#xff1a;观察规律&#xff0c;建立模型&#xff0c;参…