1,创建项目 npx create-react-app music --template typescript
2,配置项目别名@
javascript">npm install @craco/craco@alpha -D
javascript">1,最外层与src平级创建 craco.config.js
const path = require('path')
const resolve = (dir) => path.resolve(__dirname, dir)
module.exports = {
webpack: {
alias: {
'@': resolve('src'),
},
},
}
2,tsconfig.json的compilerOptions里面添加
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
]
}
3,package.json里面修改
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"eject": "react-scripts eject"
},
3,配置统一的代码风格
javascript">// 1,新建 .editorconfig
# http://editorconfig.org
root = true
[*] #表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent-style = space # 缩进风格 (tab | space)
indent-size = 2 # 缩进大小
end_of_line = 1f # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行尾的任意空白字符
insert_final_newline = true # 始终在文件末尾插入一个新行
[*.md] # 表示仅 md 文件适用以下规则
max_line_Length = off
trim_trailing_whitespace = false
// 2,安装prettier
npm install prettier -D
-新建.prettierrc文件
useTabs: 使用tab缩进还是空格缩进,选择false;
tabWidth: tab是空格的情况下,是几个空格,选择2个;
printWidth: 当行字符的长度,推荐80,也有人喜欢100或者120:
singleQuote: 使用单引号还是双引号,选择true,使用单引号:.
trailingComma: 在多行输入的尾逗号是否添加,设置为 none,比如对象类型的最后一个属性后面是否加一大
semi: 语句末尾是否要加分号,默认值true,选择false表示不加;
{
"useTabs": false,
"tabWidth":2,
"printWidth":80,
"singleQuote": true,
"trailingComma": "none",
"semi": false
}
3-1,如果配置上面文件,保存时并没有格式化代码
或者设置里面搜索
4,安装eslint检查代码
javascript">npm install eslint -D
4-1,初始化
javascript">npx eslint --init
4-2,安装插件
javascript">npm install eslint-plugin-prettier eslint-config-prettier -D
eslint-config.mjs配置
javascript">import globals from 'globals'
import pluginJs from '@eslint/js'
import tseslint from 'typescript-eslint'
import pluginReact from 'eslint-plugin-react'
import antfu from 'eslint-config-antfu'
/** @type {import('eslint').Linter.Config[]} */
export default [
antfu,
{ files: ['**/*.{js,mjs,cjs,ts,jsx,tsx}'] },
{ languageOptions: { globals: globals.browser } },
pluginJs.configs.recommended,
...tseslint.configs.recommended,
pluginReact.configs.flat.recommended,
{
rules: {
/** 可以出现any类型 */
'@typescript-eslint/no-explicit-any': 'off',
/** 需要分号 */
// semi: ['error', 'always'],
/** 可以使用require */
'@typescript-eslint/no-require-imports': 'off',
eqeqeq: ['error', 'always', { null: 'ignore' }], // 强制用 === 而不是 ==, 除了 == null 是允许的
'require-await': 'error', // async 函数内一定要有 await
'no-constant-condition': ['error', { checkLoops: false }], // 不允许 if(true),但是 white(true) 可以
'@typescript-eslint/no-empty-function': 'warn', // 当函数没有内容时会警示
/** 可以用ts-ignore */
'@typescript-eslint/ban-ts-comment': 'off',
/**
* 不检查以下划线开头的 未使用的变量
* 包含了参数变量,解构变量,catch中的参数变量
*/
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
destructuredArrayIgnorePattern: '^_'
}
],
'no-restricted-globals': [
// 不允许直接用 global,必须加上 prefix window.setTimeout 这样。
'error',
'localStorage',
'location',
'alert',
'setTimeout',
'clearTimeout',
'setInterval',
'clearInterval',
'requestAnimationFrame',
'cancelAnimationFrame',
'navigator'
]
}
},
{
ignores: [
'config/',
'build/',
'public/',
'scripts/',
'mock/',
'.vscode/',
'src/utils/XMLToJson.js',
'**/*.test.js'
]
}
]
5,目录结构
6,css重置
javascript"> npm install normalize.css
index.tsx里面引入import 'normalize.css'
javascript">npm install craco-less
// craco.config.js
const CracoLessPlugin = require('craco-less');
module.exports = {
plugins: [
{
plugin: CracoLessPlugin,
options: {
// 这里可以配置 Less 的选项,比如全局变量文件等
lessLoaderOptions: {
lessOptions: {
modifyVars: { '@primary-color': '#1DA57A' },
javascriptEnabled: true,
},
},
},
},
],
};
7,路由配置
javascript">npm install react-router-dom
// 1,index.tsx引入HashRouter
import { HashRouter } from 'react-router-dom'
root.render(
<HashRouter>
<App />
</HashRouter>
)
// 2,app.tsx添加router
import { useRoutes } from 'react-router-dom'
import routes from './router/user'
function App() {
return <div className="App">{useRoutes(routes)}</div>
}
// 3,router文件夹添加路由
import { RouteObject } from 'react-router-dom'
import { lazy } from 'react'
const User = lazy(() => import('@/views/user')) // 路由懒加载
const routes: RouteObject[] = [
{
path: '/',
element: <Navigate to="/user" />
},
{
path: '/user',
element: <User />
}
]
export default routes
// 4,views文件夹 添加视图文件
const User = () => {
return <div>user</div>
}
export default User
8,创建react模板
https://snippet-generator.app/?description=&tabtrigger=&snippet=&mode=vscode
tsreact为快捷键名称
将下面模板代码拷入上面链接地址
javascript">import React, {memo} from "react";
import type {FC, ReactNode} from 'react'
interface IProps {
children?: ReactNode
}
const ${1:Home}: FC<IProps> = () => {
return <div>${1:Home}</div>
}
export default memo(${1:Home})
将编译后的代码放入下面模板中
9,添加Suspense应急方案
javascript">// 在app.tsx中
import React, { Suspense } from 'react'
function App() {
return (
<div className="App">
{useRoutes(routes)}
<Suspense fallback="lading...">
<div className="main"></div>
</Suspense>
</div>
)
}