网易云音乐项目搭建-代码规范-第三方库集成

136 阅读3分钟

搭建项目

create-react-app twt_ts_react_music --template typescript

配置项目

  • 配置图标
    • head-link
    • 替换public里原有的favicon.ico
  • 配置标题
    • public-index.html-title
  • 配置src的别名@
    • 通过craco(create-react-app-config)修改

      • npm install @craco/craco@alpha -D

        • 支持react-script 4.x 版本,所以安装最新版本
      • 添加文件craco.config.js
      const path = require('path')
      // 拼接起来
      const resolve = (dir) => path.resolve(__dirname, dir)
      module.exports = {
       webpack: {
         alias: {
           '@': resolve('src'),
         },
       },
      }
      
      • 修改tsconfig.json
         "baseUrl": ".",
          "paths": {
            "@/*": ["src/*"]
          }
      
      • 修改package.json
      "scripts": {
          "start": "craco start",
          "build": "craco build",
          "test": "craco test",
          "eject": "react-scripts eject"
      }
      
      • 重启项目
    • eject(不推荐)

代码规范

  • 使用prettier工具

    • 安装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
      }
      
    • 创建.prettierignore忽略文件

      /dist/*
      .local
      .output.js
      /node_modules/**
      
      **/*.svg
      **/*.sh
      
      /public/*
      
    • 测试prettier是否生效

      • 测试一:在代码中保存代码;
      • 测试二:配置一次性修改的命令;在package.json中配置一个scripts:
          "prettier": "prettier --write ."
      
    • 使用ESLint检测

      • 安装 ESLint
        • npm install eslint -D

      • VSCode需要安装ESLint插件

      image-20210722215933360

      • 初始化

        • npx eslint --init

        image.png .eslintrc.js

        module.exports = {
          env: {
            browser: true,
            es2021: true,
            node: true
          },
          extends: [
            'eslint:recommended',
            'plugin:react/recommended',
            'plugin:@typescript-eslint/recommended',
            'plugin:prettier/recommended'
          ],
          overrides: [],
          parser: '@typescript-eslint/parser',
          parserOptions: {
            ecmaVersion: 'latest',
            sourceType: 'module'
          },
          plugins: ['react', '@typescript-eslint'],
          rules: {
            '@typescript-eslint/no-var-requires': 'off',
            '@typescript-eslint/no-explicit-any': 'off'
          }
        }
        
        
      • 解决eslint和prettier冲突的问题:

      npm install eslint-plugin-prettier eslint-config-prettier -D
      
      • VSCode中eslint的配置
        "eslint.lintTask.enable": true,
        "eslint.alwaysShowStatus": true,
        "eslint.validate": [
          "javascript",
          "javascriptreact",
          "typescript",
          "typescriptreact"
        ],
        "editor.codeActionsOnSave": {
          "source.fixAll.eslint": true
        },
      

    image.png

  • 集成editorconfig配置

    • EditorConfig 有助于为不同 IDE 编辑器上处理同一项目的多个开发人员维护一致的编码风格
    # http://editorconfig.org
    
    root = true
    
    [*] # 表示所有文件适用
    charset = utf-8 # 设置文件字符集为 utf-8
    indent_style = space # 缩进风格(tab | space)
    indent_size = 2 # 缩进大小
    end_of_line = lf # 控制换行类型(lf | cr | crlf)
    trim_trailing_whitespace = true # 去除行尾的任意空白字符
    insert_final_newline = true # 始终在文件末尾插入一个新行
    
    [*.md] # 表示仅 md 文件适用以下规则
    max_line_length = off
    trim_trailing_whitespace = false
    

目录结构的划分

image.png

CSS 重置

npm install normalize.css npm install craco-less@2.1.0-alpha.0

  • assets/css
    • index.less
    @import './reset.less';
    @import './common.less';
    
    • reset.less
    body,html,h1,h2,h3,h4,h5,h6,ul,ol,li,dl,dt,dd,header,menu,section,p,input,td,th,ins {
     padding: 0;
     margin: 0;
    }
    
    a {
     text-decoration: none;
     color: #333;
    }
    
    img {
     vertical-align: top;
    }
    
    ul,
    li {
     list-style: none;
    }
    
    button {
     outline: none;
    }
    
    • common.less
    body {
     font-size: 14px;
    }
    
  • index.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from '@/App'
import 'normalize.css'
import './assets/css/index.less'

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)

root.render(<App />)
  • craco.config.js
const path = require('path')
// 拼接起来
const CracoLessPlugin = require('craco-less')

const resolve = (dir) => path.resolve(__dirname, dir)
module.exports = {
  plugins: [{ plugin: CracoLessPlugin }],
  webpack: {
    alias: {
      '@': resolve('src')
    }
  }
}

路由配置

  • npm install react-router-dom

  • 配置
    • src\router\index.tsx
    import React from 'react'
    import { RouteObject } from 'react-router-dom'
    
    import Discover from '@/views/discover'
    
    const routes: RouteObject[] = [
      {
        path: '/discover',
        element: <Discover />
      }
    ]
    export default routes
    
    • App.tsx
    import React from 'react'
    import { useRoutes } from 'react-router-dom'
    import routes from './router'
    
    function App() {
      return <>{useRoutes(routes)}</>
    }
    
    export default App
    
    • index.tsx
    import React from 'react'
    import ReactDOM from 'react-dom/client'
    import App from '@/App'
    import 'normalize.css'
    import './assets/css/index.less'
    import { HashRouter } from 'react-router-dom'
    
    const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
    
    root.render(
      <HashRouter>
        <App />
      </HashRouter>
    )
    
    • src\views\discover\index.tsx
    import React from 'react'
    
    const Discover = () => {
      return <>discover</>
    }
    
    export default Discover
    
  • 补充
    • .eslintrc.js:关闭 any 报错

      • '@typescript-eslint/no-explicit-any': 'off'
    • 换行报错

      image.png