react项目搭建从0到1 踩坑以及技术文档 全文很长

276 阅读27分钟

SPA单页应用

zhuanlan.zhihu.com/p/505743865

技术栈

下面这个三个还没用到

公共类封装

1 路由拦截与鉴权,路由首页懒加载 ---首屏加载事件过长问题

2 请求响应拦截器

3页面layout布局

4 配置代理proxy

[TOC]

代码书写顺序

1 模块化引入 提交时删除未使用的声明 可以设置自动化删除

2 变量及声明 翻译插件统一 :www.deepl.com/translator column行列定义 3 事件 useEffect 4 return dom 5 模块化导出: export default HomePage; 最后有;

命名规则

1 小驼峰命名

特例: 组件采用大驼峰 且组件内部组件名也是大驼峰, 大驼峰情况举例如下:

image.png

2 使用英文命名

严禁拼音/拼音英文混用

英文不要缩写: 比如 abstractClass 命名为absClass

英文检索: 统一采用同一个翻译器 www.deepl.com/translator

prettierrc

{
     // 每行末尾不会自动添加分号
    "semi": false,  
    "tabWidth": 2, 
    // 字符串使用单引号
    "singleQuote": true,
    //是否在对象属性添加空格
   	 // true: { foo: bar }
 	 // false: {foo: bar}
    "bracketSpacing": true,
     //在jsx中把'>' 是否单独放一行
    "jsxBracketSameLine": false,
    // 换行长度,默认80
    "printWidth": 200
}

注释

1 需要注释的四个部位; 组件注释: jsn写在每个组件最上方 变量注释:useState变量注释 传参变量如当前行 尤其是英文名 写在当前定义变量上方(另起一行) 自定义事件注释 ():有特定含义的事件需要注释 注: onChange 这种很容易理解可以不写注释

2 头部注释

插件: koroFileHeader

/*
 * @Author:
 * @Date: 2022-11-03 18:16:19
 * @LastEditors: 
 * @LastEditTime: 2022-11-03 18:55:56
 * @FilePath: \bbs-web\src\services\article.ts
 * @Description: 位于文件头部 简述组件作用
 */

3 可选择 配置注释vscode快捷键

{
    "Print to jsNoteTitle": {
      "prefix": "jsNoteTitle",
      "body": [
        "/*",
        " *@description:",
        " *@author: liuzy",
        " *@date: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE} ${CURRENT_HOUR}:${CURRENT_MINUTE}:${CURRENT_SECOND}",
        "*/"
      ],
      "description": ""
    },
    "Print to jsfn": {
      "prefix": "jsfn",
      "body": [
        "/*",
        " *@functionName: ${TM_CURRENT_LINE}",
        " *@params1: ${1:参数1}",
        " *@params2: ${2:参数2}",
        " *@description:",
        " *@author: liuzy",
        " *@date: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE} ${CURRENT_HOUR}:${CURRENT_MINUTE}:${CURRENT_SECOND}",
        "*/"
      ],
      "description": ""
    },
    "Print to jsModify": {
      "prefix": "jsModify",
      "body": [
        "/*",
        " *@description:",
        " *@modifyContent:",
        " *@author: liuzy",
        " *@date: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE} ${CURRENT_HOUR}:${CURRENT_MINUTE}:${CURRENT_SECOND}",
        "*/"
      ],
      "description": ""
    },
    "Print to jsVariable": {
      "prefix": "jsVariable",
      "body": [
        "/*",
        " *@description:",
        " *@author: liuzy",
        " *@date: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE} ${CURRENT_HOUR}:${CURRENT_MINUTE}:${CURRENT_SECOND}",
        " *@variable1: ${1:变量1}",
        " *@variable2: ${2:变量2}",
        "*/"
      ],
      "description": ""
    }
  }

文件目录

cfg 部署配置文件

public 公用文件 首页最外层index.html

src 主要内容

app+features redux文件夹 存储仓库和reducer文件

assets:资源文件 如图片文件

		components: 公共组件 : 此文件夹下命名采用大驼峰
		data.d.ts: 类型文件
		json: jsonserver文件存储位置 现在使用mock方式 这个文件夹没用
		layout: 首页外层布局文件
		mock: mock假数据
		pages: 页面文件和交互操作

routes: 存放路由信息

services: 调用接口文件夹

utils: 公共类封装

react-app-env.d.ts : 全局支持的文件后缀配置

reportWebVitals.ts

setupProxy.js: 配置代理

setupTests.ts: 测试文件 还未使用

.commitlint.config.js: git commit 配置文件 约束提交注释

lintstagedrc.js : eslin 配置

craco.config.js: craco给webpack打补丁

tsconfig.json: 配置绝对路径src 自动找到src下文件 sass使用时在绝对路径加('~asset/') 否则会报错

package.json: 包版本号

prettierignore : prettier 自动格式化忽略文件

.prettierrc.json: prettier 自动格式化 配置文件

image.png

git规范

/**
* feature:新功能
* update:更新某功能
* fix:修补某功能的bug
* refactor:重构某个功能
* optimize: 优化构建工具或运行时性能
* style:仅样式改动
* docs:仅文档新增/改动
* chore:构建过程或辅助工具的变动
* build: 打包
*/

配置镜像源

切换 npm config set registry registry.npm.taobao.org/ 查看 npm config get registry

另:三秒删除node module包

npm install rimraf -g

rimraf node_modules

项目打包

本系统采用线下打包 线上部署方式

打包命令如下: yarn build /npm run build 测试和生产同

当无法提交提示文件太大(The remote end hung up unexpectedly)

使用如下命令扩容为500M git config http.postBuffer 524288000 合并时经常出现冲突 最好增加配置 push时候自动删除build目录再打包

项目分支管理问题

测试和生产目前暂时均使用test_branch分支

git 写错分支如何切换


在branch1 commit,但是想在branch2 commit

在branch1记住commit的id.切换到branch2 然后执行git  cherry-pick id

如果遇到冲突 先解决冲突 再提交

git push报错

the remote end hung up unexpectedly

image-20231031100257183

添加

[http]

postBuffer = 524288000

脚手架创建

npx create-react-app  xxx(不能有大写字母)
npx create-react-app 项目名称 --template typescript
npx create-react-app react-admin --template redux-typescript

blog.csdn.net/qq_43180019…

3.报错(文件名、目录名或卷标语法不正确。)问题介绍 在命令正确的情况下,如npm, yarn ,umi,create-react-app 这些正确的情况下 去node的如下目录

nodejs/node_global/bin/对应命令的.cmd看这个cmd文件是不是

@"C:\Users\find me\AppData\Local\Yarn\Data\global\node_modules.bin\create-react-app.cmd" %* 极大可能是这里多了%~dp0 @"%~dp0\C:\Users\find me\AppData\Local\Yarn\Data\global\node_modules.bin\create-react-app.cmd" %*

严格模式

 <React.StrictMode>
    <App />
  </React.StrictMode>

加载速度

import reportWebVitals from './reportWebVitals';
reportWebVitals();
const reportWebVitals = onPerfEntry => {
  if (onPerfEntry && onPerfEntry instanceof Function) {
    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
      getCLS(onPerfEntry);
      getFID(onPerfEntry);
      getFCP(onPerfEntry);
      getLCP(onPerfEntry);
      getTTFB(onPerfEntry);
    });
  }
};

export default reportWebVitals;

react 18 新特性 距离16.8已经三年了

ReactDOM.createRoot

rfce 快捷生成函数

报错: You are running create-react-app5.0.0, which is behind the latest release (5.0. 1).

1、删除C:\Users\用户(当前计算机用户名)\下的.npmrc文件(如果不存在,表示当前文件可能被隐藏。)

img

2、在命令行输入npm cache clean --force

结果如下

image-20220908134824856

最后执行 unistall

create-react-app.bootcss.com/docs/folder…

安装antd

ant-design.gitee.io/docs/react/…

$ yarn add antd

@import '~antd/dist/antd.css';

yarn错误The engine "node" is incompatible with this module except version ^14.15.0

 yarn config set ignore-engines true

版本号

  • 如果只是修复bug,需要更新Z位。
  • 如果是新增了功能,但是向下兼容,需要更新Y位。
  • 如果有大变动,向下不兼容,需要更新X位。

^version 更新到当前 major version(也就是第一位数字)中最新的版本

从左数,第1个不为 0 的数字 + 1,后面的变成 0

^1.2.3 >=1.2.3 <2.0.0 ^0.2.3 >=0.2.3 <0.3.0 ^0.0.3 >=0.0.3 <0.0.4

~version 更新到当前 minor version(也就是中间的那位数字)中最新的版本

从左数,第2个数字 + 1,后面的变成 0

~1.2.3 >=1.2.3 <1.3.0 为了方便记忆,我们可以这样想,在正则表达式,放在首位的 ^ 表示匹配第一个,所以也就对应到这里的 major,而波浪线 ~ 表示波动到第二位,也就是 minor。

node官网:nodejs.org/en/download… 选择LTS长期支持版本

添加路由router

yarn add react-router-dom

create-react-app.bootcss.com/docs/adding…

router6 新特性

1 在app外层包

这种大版本更新不能跟随上一个的经验 会影响判断 要从0开始

image-20220908214335047

每次点击路由 都会调navlink

navlink里面clasName是函数

实现高亮

计算样式类名: 实现复用

重定向no

路由表

​ useLocation 传参

最外层

  <BrowserRouter>
    <React.StrictMode>
      <App />

    </React.StrictMode>
  </BrowserRouter>

router路由表

export default [
    {
        path: '/',
        element: <Navigate to="/testaa" />
    },
    {
        path: '/testaa',
        element: <Testaa />
    },
    {
        path: '/testbb',
        element: <Testbb />,
        children: [
            {
                path: 'message',
                element: <MessageCom />,
                children: [
                    {
                        // path: 'detail/:id/:title/:content',
                        path: 'detail',
                        element: <Details />
                    }
                ]
            },
            {
                path: 'news',
                element: <News />
            },
        ]
    },

]

路由拦截和权限控制

参考:

github.com/neohan666/r…

src/router/index.js 首页 布局 登录 404 403 首先渲染的地方 此处进行路由拦截 onRouteBefore

​ 逻辑: 判断==是否需要登录== 如果需要登录

判断==是否含有用户信息==,如果没有=> 调用接口获取UserInfo

​ userInfo会返回accessIdList 授权列表 ,根据授权列表查询用户==是否具有权限==,没有权限返回403

​ 如果有用户信息: 但是没权限 返回403

src/router/nest.tsx 一般路由配置

前端路由模式之 hashRouter和BrowserRouter

hashRouter 默认有个#

browserHistory 没有# ,==需要server端支持==

刷新会丢失404(上线中会出现问题 本地开发中不会)

底层原理不一样:

  1. BrowserRoute使用的是H5的history API,不兼容IE9及以下版本。 HashRouter使用的是URL的哈希值。

  2. path表现形式不一样 BrowserRouter的路径中没有#,例如:localhost:3000/demo/test HashRouter的路径包含#,例如:localhost:3000/#/demo/test 刷新后对路由state参数的影响

  3. BrowserRouter没有任何影响,因为state保存在history对象中。 HashRouter刷新后会导致路由state参数的丢失!!! 备注:HashRouter可以用于解决一些路径错误相关的问题。

!配置模块化 修改webpack配置

1 暴露配置 不推荐 此操作不可逆 慎用!! 不贴出来了

eject 适用于修改大量配置的情况

2 打补丁的方式 覆盖文件

cnpm i customize-cra --save-dev
npm i react-app-rewired --save-dev

customize-cra 用来找到config-overrider.js来进行修改 react-app-rewired是修改package.json里的启动配置的 config-overrider.js是修改规则文件

在package.json的同级目录中新建一个config-overrides.js文件

更改 package.json 中的 scripts 配置,如下所示。即用 react-app-rewired命令代替 react-scripts

 "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-app-rewired eject"
  },

按需引入antddesign 修改主题色

antd样式自定义主题 自定义主题需要用到 less 变量覆盖功能。我们可以引入 customize-cra 中提供的 less 相关的函数 addLessLoader 来帮助加载 less 样式,同时修改 config-overrides.js 文件。

customize-cra依赖库我们在进行样式的按需引入时已经安装过了,我们只需要安装less以及less-loader即可:

npm install less less-loader@5
yarn add less less-loader@5

修改config-overrides.js文件:

const { fixBabelImports, override, addLessLoader } = require("customize-cra");
module.exports = override(
    fixBabelImports('import', {
        libraryName: 'antd',
        libraryDirectory: 'es',
        // style: 'css',
        style: true,
    }),
    addLessLoader({
        javascriptEnabled: true,
        modifyVars: { '@primary-color': 'red' },
    }),
    // ...其他配置...
);

我升级了nodejs 项目启动失败了

删除node module文件夹

这里给给出个快速的方法

首先下载个包管理器:rimraf

直接在所在包含nodemodules的文件夹内打开命令行安装包

npm install rimraf -g

rimraf 包的作用:以包的形式包装rm -rf命令,用来删除文件和文件夹的,不管文件夹是否为空,都可删除.

然后再执行删除操作:

rimraf node_modules

node_modules目录没了,秒删!

安装ts

npx create-react-app 项目名称 --template typescript

模块化配置 在最外层加文件 global.d.ts,否则可能会不识别 。module.css文件

declare module '*.css';
declare module '*.less';
declare module '*.scss';
declare module '*.sass';
declare module '*.svg';
declare module '*.png';
declare module '*.jpg';
declare module '*.jpeg';
declare module '*.gif';

'isFragment' (imported as 'isFragment') was not found in 'react-is'

卸载重装包 删除node module

ts 基本用法

// 字符串
let a:string
let a:string[]
// 数组泛型
let a:Array<number> =[1,2]
//对象 详细写属性
let a:object 替换为
//数组
let a:number
let arr:number[]=[1,2]
// 布尔
let flag:boolean=true

类型断言
<number> str
str as number
let b:string|number // a or b
let c?:string // c属性可以不存在


接口
// 形参
interface Params{
	title:string;
	content:string;
	say:()=>string //函数
}
let Question: Params{
	title:"a";
	content:"b";
	say:():string=>{return "aaa"}
}

继承 单
interface Person{
age:number
}
interface Musician extends Person{
	song:string
}
let a=<Musician>{};
a.age=33;
a.song="sing"


interface Child extend Person,Musician{}
let Iobj:Child={age:12,song:'eqewq'}

对象
let object_name={
	key1:"value1",
	key2:"a",
	key3:["a","b"],
	key4:function(){
	
	}
}

no安装dva

dvajs.com/guide/getti…

显示webpack

从create-react-app创建项目后,运行npm run eject报错解决方法

blog.csdn.net/duansamve/a…

create-react-app app-demo
cd app-demo
git init
git add .
git commit -m 'Saving before ejecting'
npm run eject

react生态

react toolkit 官方 redux封装

modx 用的人也不少

hookstate 完美结合hook 新出的 用的人少 但是是未来趋势

useContext 官方用法

dva 是类组件时代的产物 现在社区停止更新了 和umi很像

umi 体积较大 编译打包很久 需要研究官方文档 封装的比较狠 umi属于dva的升级版。都有模板代码,同时失去了灵活性

  1. 启动时间长
  2. 热更新慢
  3. 太臃肿
  4. 框架 BUG 修复不及时
  5. 过度封装,自定义插件难度大
  6. 约定式功能太单一

vite 快 但底层不是webpack

我认为最佳: vite(+esbuild+)+ ts+react router+react hooks+hookStates+ antd+ mock

目前:create react app(+ webpack+ )+ redux toolkit + ts+react router+react hooks+ antd+ mock

安装axios

npm install axios -g
import axios from 'axios';
export async function select(){
    return axios.get('/question/select')
    .then(function(response){
        console.log('axios response.data',response.data)
        return response;
    })
    .then(function(error){
        return error
    })
}
export  const insert = async({title})=>{
    axios.post('/question/select',{
        title
    })
    .then(function(response){
        console.log('axios response.data',response.data)
        return response;
    })
    .then(function(error){
        return error
    })
}

安装axios

配置拦截器

安装react-cookies库

这个过程出现一个问题就是用node安装成功但是package.json就是没有,最后用git bash安装一遍

就安装成功了 注意--save

配置src/utils文件夹的http.js文件


import axios from "axios";
import cookie from 'react-cookies';

let baseUrl = '/api'

// 创建axios实例,在这里可以设置请求的默认配置
const instance = axios.create({
    timeout: 20000, // 设置超时时间10s
    // baseURL: baseUrl // 根据自己配置的反向代理去设置不同环境的baseUrl
})
// 文档中的统一设置post请求头。下面会说到post请求的几种'Content-Type'
instance.defaults.headers.post['Content-Type'] = 'application/json'

/** 添加请求拦截器 **/
instance.interceptors.request.use(config => {
    var token = cookie.load('token')//获取本地存储的token
    // 判断cookie有没有存储token,有的话加入到请求头里
    if (token) {
        if (config && config.headers) {

            config.headers['token'] = token//在请求头中加入token
        }
    }
    // 如果还需要在请求头内添加其他内容可以自己添加 [] 内为自定义的字段名 = 后的内容为字段名对应的内容
    // config.headers['api'] = api
    return config
}, error => {
    // 对请求错误做些什么
    return Promise.reject(error)
})

/** 添加响应拦截器  **/
instance.interceptors.response.use(response => {
    if (response.statusText === 'OK') {
        return Promise.resolve(response.data)
    } else {
        return Promise.reject(response.data.msg)
    }
}, error => {
    // 请求报错的回调可以和后端协调返回什么状态码,在此根据对应状态码进行对应处理
    if (error.response) {
        // 如401我就让用户返回登录页
        if (error.response.status === 401) {
            // this.props.history.push('/login');

        }
        return Promise.reject(error)
    } else {
        return Promise.reject('请求超时, 请刷新重试')
    }
})

/* 统一封装get请求 */
export const get = (url, params, config = {}) => {
    debugger
    return new Promise((resolve, reject) => {
        instance({
            method: 'get',
            url,
            params,
            ...config
        }).then(response => {
            resolve(response)
        }).catch(error => {
            reject(error)
        })
    })
}


/* 统一封装post请求  */
export const post = (url, data, config = {}) => {
    return new Promise((resolve, reject) => {
        instance({
            method: 'post',
            url,
            data,
            ...config
        }).then(response => {
            resolve(response)
        }).catch(error => {
            reject(error)
        })
    })
}

export async function select(params?:QuestionParams){
    get('/article/select')
}

安装ahooks

ahooks.js.org/zh-CN

配置代理 proxy

==位置 src下的setupProxy.js 一定是这个名 别的都不识别== ==还有位置注意是src下==

安装中间件: npm install http-proxy-middleware

==修改完一定要重启 配置才能生效==

注意中间件==版本不同 写法不同== 我这里是新版的写法

// commonJs写法  是前端模块化的一种规范
const { createProxyMiddleware } = require('http-proxy-middleware')

module.exports = function (app) {
    app.use(
        createProxyMiddleware('/article', {
            //api1是需要转发的请求(所有带有/api1前缀的请求都会转发给5000)
            target: 'http://localhost:8080', //配置转发目标地址(能返回数据的服务器地址)
            changeOrigin: true, //控制服务器接收到的请求头中host字段的值
            //    pathRewrite: { '^/article': '' }, //去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置)

        }),

        createProxyMiddleware('/api2', {
            target: 'http://localhost:5001',
            changeOrigin: true,
            pathRewrite: { '^/api2': '' },
        })
    )
}

也可以写在package.json里面 但不方便

配置mock

blog.csdn.net/m0_59850169…

注意mock文件放到src下面

在app.tsx中引入mock文件

import './mock';

安装引入redux-toolkit

自动生成一个完成的

如何使用还未知

配置按需引入 覆盖webpack默认配置 config.override.js

craco 的作用类似 react-app-rewired,但是比它的配置更友好。craco 将常用的配置提取出来作为配置项,而 react-app-rewired 只能通过转换函数的方式修改 webpack 的配置,往往还需要 customize-cra 配合使用。

最近在熟悉react,通过react create app创建项目后,并不像以前一样可以进行webpack的配置,官方文档有写到可以npm run eject暴露所有配置,会发现根目录下生成了 config 目录,但是此操作是不可逆的。
如果需要在项目中配置一些webpack配置,需要在根目录下新建一个名称为config-overrides.js的文件
1、下载antd 包
npm install antd

2、安装customize-cra,引入react-app-rewired插件
react-app-rewired的作用就是在不eject的情况下,覆盖create-react-app的配置
npm install react-app-rewired customize-cra babel-plugin-import

3、自定义less-loader,改变antd默认样式
npm install less less-loader

4、在根目录下面新建config-overrides.js,并修改相关配置
const { override, fixBabelImports, addLessLoader, addWebpackAlias } = require("customize-cra");
const path = require("path");

module.exports = override(
  // 针对antd 实现按需打包:根据import来打包 (使用babel-plugin-import)  
  fixBabelImports("import", {    
    libraryName: "antd",    
    libraryDirectory: "es",    
    style: true, //自动打包相关的样式 默认为 style:'css'  
  }),
  //增加路径别名的处理 
  addWebpackAlias({  
    '@': path.resolve('./src')  
  })
); 

5、修改packge.json 的配置文件
 "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react--app-rewired test",
    "eject": "react-scripts eject"
  },

6、最后,在app.js引入需要的组件即可
import { Button, Table } from "antd";


npm install antd babel-plugin-import *--save*

[create-react-app 创建 react 项目 css 模块化处理]

引入less

less作为预编译语言 需要转换为css才能执行,与此相似的还有sass

less相比于css 具有诸多优点

1 嵌套写类选择器 省去堆叠

2 定义变量 方便进行主题修改

关键字搜索: react customize-cra 配置less modules 或者直接搜索module.export addLoadLess

查看网上,基本上都是eject,把webpack暴露出来更改,太吓人了

1 安装less load

npm install less less-loader --dev

2 配置config-overrides.js文件

根据版本不同写法不同

"customize-cra": "^1.0.0-alpha.0",

"less": "^4.1.3",

 const theme = require("package.json").theme;
 addLessLoader({
        lessOptions: { // 这层不写会报错 根据版本不同
            javascriptEnabled: true,
            localIdentName: '[local]--[hash:base64:5]',
            modifyVars: theme
        }
    }),

3 配置支持less后缀 ,CRA默认不支持需要手动配置

/// <reference types="react-scripts" />

// 添加了对导入资源文件的支持
declare module "*.less" {
    const content: { [className: string]: string };
    export default content;
  }

4 需要模块化引入 文件后缀module.less

image-20220919185808370

==5 之后修改配置把module省略 就顺眼很多了==

默认配置文件 react-app-env.d.ts

1、react-app-env.d.ts的作用

在使用create-react-app xxx --typescript生成一个react typescript项目时,在src目录下会生成一个react-app-env.d.ts类型声明文件

/// <reference types="react-scripts" />

三斜线指令是包含单个XML标签的单行注释。 注释的内容会做为编译器指令使用

三斜线指令仅可放在包含它的文件的最顶端。 一个三斜线指令的前面只能出现单行或多行注释,这包括其它的三斜线指令。 如果它们出现在一个语句或声明之后,那么它们会被当做普通的单行注释,并且不具有特殊的涵义。

三斜线引用告诉编译器在编译过程中要引入的额外的文件。

三斜线指令中有两种typespath 两种不同的属性,它们的区别是:types 用于声明对另一个库的依赖,而 path 用于声明对另一个文件的依赖。上面react-app-env.d.ts依赖react-scripts库的类型声明文件,react-scripts下的package.jsontypes指定了TypeScript 的入口文件 image.png

当项目编译时将会根据tsconfig.jsoninclude指定的目录去找代码所需要的类型声明文件,而react-app-env.d.ts会告诉编译器含有哪些类型声明,里面含有一些常用的类型声明,比如react、react-dom的一些API类型声明,图片、样式模块类型声明等等。 image.png

有了上面的类型声明,我们就可以在项目中直接引入图片或者样式

import contentBg from "@assets/image/content-bg.png"
import styles from './index.module.scss';

假如引入的包没有相应的类型声明呢?

比如使用gridmanager-react制作表格,但是目前gridmanager-react还没有提供类型声明,怎么办呢?其实可以在react-app-env.d.ts或者在src目录下另外定义一个.d.ts文件中加上该模块的类型声明

/// <reference types="react-scripts" />
declare module 'gridmanager-react' {
const classes: any;
export default classes;
}

这样,再导入gridmanager-react就不会报如下错误: image.png

2、react-app-env.d.ts如何生成的

react-app-env.d.ts文件删掉,然后执行yarn start启动项目会报类型错误吗?

答案是不会,在执行构建之前会重新生成react-app-env.d.ts image.png

快捷清除clg 不使用用debugger

console.log.*$

1 模块化配置 css写法 试一下

2 数据返回后需要进行是否为空的判断

// 2 webpack打包+eslint+typescript data.d.ts配置

路由鉴权实现:

1 遇到一直循环的问题

需要加入else条件判断

2 一堆userxxx ^^^^^^^^^^^

juejin.cn/post/710192…

) 路由拦截转存失败,建议直接上传图片文件

import { message } from "antd";
import { useEffect } from "react";
import {
    Location, NavigateFunction, useLocation, useNavigate, useRoutes
} from "react-router-dom";
import { useAppSelector } from "../app/hooks";
import { selectAccessIdList } from "../features/counter/counterSlice";
// import { message } from "antd";

interface RouteObject {
    caseSensitive?: boolean;
    children?: RouteObject[];
    element?: React.ReactNode;
    index?: boolean;
    path?: string;
    auth?: boolean;
    accessId?: string
}

//递归查询对应的路由
export function searchroutedetail(
    path: string,
    routes: RouteObject[]
): RouteObject | null {
    for (let item of routes) {
        if (item.path === path) return item;
        if (item.children) {
            return searchroutedetail(path, item.children);
        }
    }
    return null;
}

//全局路由守卫
function Guard(
    location: Location,
    navigate: NavigateFunction,
    routes: RouteObject[],
    accessIdList: string[]
) {
    const { pathname } = location;
    let routedetail = searchroutedetail(pathname, routes);

    console.log('路由拦截目标地址', routedetail)
    console.log(sessionStorage)

    //没有找到路由,跳转*404 
    if (pathname === "/404") {
        return;
    }
    if (pathname === "/403") {
        return;
    }
    if (!routedetail) {
        navigate("/404");

    } else if (routedetail.path === "/login") {
        console.log("login页面正常跳转 不拦截");
    } else if (sessionStorage.length === 0) {
        message.warn("请登录");
        navigate("/login");
    } else if (sessionStorage) {
        console.log("有session正常跳转 下一步判断权限");
        // 如果没有权限
        if (routedetail.accessId) {
            if (accessIdList.includes(routedetail.accessId)) {
                console.log("权限列表包含正常跳转 不拦截", routedetail.accessId)
                return;
            }
            else {
                navigate("/403")
            }
        }
        return true
    }
}


export const RouterGuard = (routes: any) => {
    const location = useLocation();
    const navigate = useNavigate();
    const accessIdList = useAppSelector(selectAccessIdList)
    console.log('accessIdList', accessIdList);
    useEffect(() => {
        Guard(location, navigate, routes, accessIdList)
    }, [location, navigate, routes, accessIdList]);
    // document.documentElement.scrollTo(0, 0);
    const Route = useRoutes(routes);
    return Route;
}

懒加载

react16后具备新特性suspense和loading lazy() 实现懒加载

function App() {
  return (
    <Suspense>{
    // routerIndex就是路由表
      RouterGuard(RoutesIndex)
    }</Suspense>
  )
}
export default App;
/**
 * @Description: 路由统一配置
 * @Author: liuzy521
 * @Date: 2022-09-20
 * @LastEditTime: 2022-09-29
 * @LastEditors: liuzy521
 */

import FourOThree from '../components/403';
import Error from '../components/404';
// import HomePage from '../pages/HomePage';
import LoginIndex from '../pages/Login';
import Message from '../pages/Message';
import Details from '../pages/Message/details';
import News from '../pages/News';
import Testbb from '../pages/testbb';
import { lazy } from "react";
const HomePage = lazy(() => import("../pages/HomePage/index"));

export interface RouteObject {
    caseSensitive?: boolean;
    children?: RouteObject[];
    element?: any;
    index?: boolean;
    path?: string;
    auth?: boolean
    accessId: string
}
/**
 * @description: 全局路由配置
 * @param {string} accessId // 路由页面权限id
 */
const RoutesIndex: RouteObject[] = [
    {
        path: '/login',
        element: <LoginIndex />,
        accessId: '10000',
        auth: true
    },
    {
        path: '/',
        element: <HomePage />,
        accessId: '10007',
        auth: true,
        children: [
            {
                path: '/testbb',
                element: <Testbb />,
                accessId: '10004',
                auth: true,
                children: [
                    {
                        path: '/testbb/message',
                        element: <Message />,
                        accessId: '10005',
                        auth: true,
                        children: [
                            {
                                // path: 'detail/:id/:title/:content',
                                path: '/testbb/message/detail',
                                element: <Details />,
                                accessId: '10006',

                            }
                        ]
                    },
                    {
                        path: 'news',
                        element: <News />,
                        accessId: '10008',
                        auth: true,
                    },
                ]
            },
        ]
    },
    {
        path: '/403',
        element: <FourOThree />,
        accessId: '10008',
        auth: true,
    },
    {
        path: '/404',
        element: <Error />,
        accessId: '10009',
    }
]
export {
    RoutesIndex,
};

组件渲染,需要注意的是使用react.lazy动态加载路由必须指定Suspense,并添加回调渲染组件,用于在加载组件过程中显示loading效果,如果不指定该组件,react会报错

如何判断 懒加载 是否真的 ‘懒加载: 看source左侧

懒加载可以解决首屏加载过慢的问题

登录前 左侧文件 点击登录完成的文件

日后再说 nginx 配置

正式发布到nginx服务器上时,需要解决browserHistory模式带来的404问题,参照下面配置做nginx.conf的修改。
``
location / {
    # browserHistory模式 404问题
    try_files $uri $uri/ /react/index.html;
    index index.html;
}
``

小问题

1 省略module的webpack配置

2 eslint自定义 配置

3 删除空行 ^\s*(?=\r?$)\n

4 相对路径优化 @ 绝对路径

5 设置ctrl s 全部保存快捷键

6 tsconfig.json baseUrl:src 后续用@

样式文件也可以

7 sass

yarn add sass

绝对路径加~

1 获取staffInfo信息

2 获取accessMenuList信息

3 存到cookies中

4 守卫渲染这里面的数据

login登录之前无需守卫

路由监听引入的位置

1 element映射为路径

2 routes先存到token

blog.csdn.net/ilovethesun…

blog.csdn.net/zhongzk69/a…

注释规范vscode配置

src绝对路径

import LoginIndex from 'pages/login';

引入 redux持久化插件 redux-persist

juejin.cn/post/712904…

==思路:404无法回退: 设置监听事件 当为404时 navigate(-2) 退回两次==

npm i  redux-persist --save

app/store.ts

import { Action, configureStore, ThunkAction } from '@reduxjs/toolkit';
import { combineReducers } from 'redux';
import thunk from 'redux-thunk';
// 持久化存储
import { persistReducer, persistStore } from 'redux-persist';
import storage from 'redux-persist/es/storage';
import counterSlice from '../features/counter/counterSlice';


// 缓存数据配置
const persistConfig = {
  key: 'root',
  storage,
  blacklist: [  ] // 写在这块的数据不会存在storage
}
const reducers = combineReducers({
  counterSlice
})

const persistedReducer = persistReducer(persistConfig,reducers)
export const store = configureStore({
  reducer: persistedReducer,
  // reducer: {
  //   counter: counterReducer,
  // },
  devTools: process.env.NODE_ENV !== 'production',
  middleware: [ thunk ]
});



export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;
export type AppThunk<ReturnType = void> = ThunkAction<
  ReturnType,
  RootState,
  unknown,
  Action<string>
>;
export const persist = persistStore(store) // 数据持久化存储

counterSlice.ts

export const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    staffInfoReducer:(state,action)=>{
      // console.log('进到counter里面了')
      state.staffInfo=action.payload

    },
    accessMenuListReducer:(state,action)=>{
      state.accessMenuList=action.payload 
      console.log('仓库中的数据权限列表',state.accessMenuList)
    }
  }
});
export const { increment, decrement, incrementByAmount ,staffInfoReducer,accessMenuListReducer} = counterSlice.actions;
export default counterSlice.reducer;

sessionStorage

sessionStorage 是HTML5新增的一个会话存储对象, 用于临时保存同一窗口(或标签页)的数据(key/value), 在关闭窗口或标签页之后将会删除这些数据。是window下的对象。

seesionStorage的存储方式采用key、value的方式。value的值必须为字符串类型。

/**
 * @Description: 公共api接口集合
 * @Author: liuzy521
 * @Date: 2022-09-18
 * @LastEditTime: 2022-09-18
 * @LastEditors: liuzy521
 */
// import http from '@/utils/request/http'

const GetUserInfo = {
    // 获取用户信息
    // getUserInfo: (data) => http('get', '', '/proxy/getUserInfo', data),
    // 模拟从接口获取用户信息
    getUserInfo () {
      return new Promise((resolve) => {
        setTimeout(() => {
          console.log('got userInfo')
          resolve({
            data: {
              userId: '666',
              nickName: 'Neo',
              accessMenuList: ['10000', '10001', '10002']
            },
            errorCode: 0,
          })
        }, 200)
      })
    },
  }
  
  export default GetUserInfo
  

index.tsx

<Provider store={store}>
    <PersistGate persistor={persist}>
      <BrowserRouter>
        <React.StrictMode>
          <App />
        </React.StrictMode>
      </BrowserRouter>
    </PersistGate>
  </Provider>
        if (result.code === 200) {
            Cookies.set('x-auth-token', "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdGFmZkNvZGUiOiIxMDYwMjU4NyIsIm9yZ0NvZGUiOiIwMDU2MDA4M")

(option)=>{

​	return{

​

​	}

}

json.parse(option.body)

过滤option.body

## 其他

表单初始化

验证

table loading加载效果

查询按钮加载效果 执行第二次不能点了 下面暗 防止毫秒级别练点

富文本编辑器

文件: 上传 下载 附件

nginx #刷新

表单初始化,loading加载效果,引入富文本编辑器和文件上传下载等细节优化

## scss使用

插件实时编译

@use @forward

\$light-red  未定义

预编译语言

### craco

const CracoLessPlugin = require('craco-less');

module.exports = { plugins: [ { plugin: CracoLessPlugin, options: { lessLoaderOptions: { lessOptions: { modifyVars: { '@primary-color': '#1DA57A' }, localIdentName: '[local]--[hash:base64:5]', javascriptEnabled: true, }, }, fixBabelImports: ("import", { libraryName: "antd", libraryDirectory: "es", style: true, //自动打包相关的样式 默认为 style:'css'
}),

            options: {
                module: true,

            }
        },
    },
],

};


    "scripts": {
        "start": "craco start",
        "build": "craco build",
        "test": "craco test",
        "eject": "react-scripts eject"
      },

<https://www.likecs.com/ask-171833.html?sc=5900>

git commit line

​     `.cz-config.js                                                 `

module.exports = { // 可选类型 types: [ { value: 'feat', name: 'feat: 新功能' }, { value: 'fix', name: 'fix: 修复' }, { value: 'docs', name: 'docs: 文档变更' }, { value: 'style', name: 'style: 代码格式(不影响代码运行的变动)' }, { value: 'refactor', name: 'refactor: 重构(既不是增加feature,也不是修复bug)' }, { value: 'perf', name: 'perf: 性能优化' }, { value: 'test', name: 'test: 增加测试' }, { value: 'chore', name: 'chore: 构建过程或辅助工具的变动' }, { value: 'revert', name: 'revert: 回退' }, { value: 'build', name: 'build: 打包' } ], // 消息步骤 messages: { type: '请选择提交类型:', customScope: '请输入修改范围(可选):', subject: '请简要描述提交(必填):', body: '请输入详细描述(可选):', footer: '请输入要关闭的issue(可选):', confirmCommit: '确认使用以上信息提交?(y/n/e/h)' }, // 跳过问题 skipQuestions: ['body', 'footer'], // subject文字长度默认是72 subjectLimit: 72 }


package.json

    "config": {
        "commitizen": {
          "path": "node_modules/cz-customizable"
        }
      },

## 富文本编辑器

难点: 光标位置错乱

![img](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d737a9daf7c14d3e896d3beb8e7d95a7~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.image)

level 0 DOM的contentEditable 原生编辑能力 输入流畅,但是浏览器兼容差,组合功能的实现复杂

level 1 quill(20w star) ;

​	draft.js (react):Facebook开源的开发React富文本编辑器开发框架,而是可以直接编写React组件实现编辑器的UI

level 2 slate.js  扩展性特别好 需要大量的二次开发

vscode 个性化配置

星星插件

![image-20221102095435792](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8f455ed1d9f3488aa246bd5424f95b3f~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1267\&h=600\&s=127761\&e=png\&b=212121)

## 前端规范 参考阿里

    https://developer.aliyun.com/article/850913

## sourceTree

git 可视化版本管理工具 sourceTree 每次执行后会生成git命令供学习

1 官网下载

2 注册: 我是使用公司邮箱注册

3 密钥生成: generate 然后save private key 存储路径

    C:\Users\Miss Liu\Documents\ssl\id_rsa.pub

## 规范Git检查工作流

husky+lint-staged+prettier+ commitlint

<https://cloud.tencent.com/developer/article/2045915?from=article.detail.1450249>

*   **代码规范落地难**:归根结底在于需要工具去强行保证代码必须经过代码开发规范的扫描;
*   **低质量代码带入线上应用**:最好的方式本地进行commit的时候,最起码需要保证当前代码能够满足团队制定的开发规范,如果不通过,commit都无法成功,这样能够从最源头保证代码质量问题;
*   **代码格式难统一**:需要一种工具强制保证团队内代码的格式是一致;
*   最好的办法是在**本地提交代码时就能够扫描出潜在的错误**,并**强制将其修改后才能提交**,这样就不会将问题代码携带到线上,就

### 1 husky 用于git 拦截

1.  含义: Husky can prevent bad git commit, git push and more ? woof!

2.  安装:

<!---->

    npm install husky --save-dev

3.  在package.json中增加的 prepare命令,执行 husky install  这时会在根目录生成 .husky 文件夹,如图:

         "scripts": {
            "start": "react-scripts start",
            "build": "react-scripts build",
            "test": "react-scripts test",
            "eject": "react-scripts eject",
            "prepare": "husky install"
          },

4.  运行完会生成.husky文件夹,在.husky文件夹下有一个pre-commit,这个文件是用来定义git commit之前应该执行什么命令,默认内容如下

    生成 husky pre文件

        npx husky add .husky/pre-commit   =
        npx husky add .husky/commit-msg "npx --no -- commitlint --edit $1"   

    pre-commit 内容修改 如下 最后一行的undefined改为lint-staged  ==代码校验==

        #!/usr/bin/env sh
        . "$(dirname -- "$0")/_/husky.sh"

        npx lint-staged

​		commit-msg 如下   ==提交信息校验==

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

    npx --no -- commitlint --edit $1

### 2 lint-staged 对暂存 git 校验(add . 而不是全部文件)

    yarn add --dev husky lint-staged

.lintstagedrc.js

    module.exports = {
        "src/**/\*{js,jsx,ts,tsx,md,html}": ["eslint", "prettier --write"],
        "src/**/*.scss": ["stylelint --fix", "git add"],
    }

或者在package.json 里添加如下代码

```javascript
{
  "lint-staged": {
    "src/**/*.{less,scss,css}": [
      "stylelint --fix --syntax=less",
      "git add ."
    ],
    "src/**/*.{js,ts,tsx,vue}": [
      "eslint ./src  --ext .js,.tsx,.ts,.vue --cache --fix",
      "git add ."
    ]
  },
  "scripts": {
    "lint": "eslint --fix src",
    "lint:style": "stylelint --fix ./**/*.{scss,css,vue} --custom-syntax",
    "prepare": "husky install"
  },
  "devDependencies": {
    "@blueking/eslint-config-bk": "^2.1.0-beta.6",
    "@blueking/stylelint-config-bk": "^2.0.0",
    "@commitlint/cli": "^17.0.3",
    "@commitlint/config-conventional": "^17.0.3",
    "bk-vision-cli": "^4.0.4",
    "husky": "^8.0.1",
    "lint-staged": "^13.0.3",
  }
}

3 prettier自动修正 格式化

prettier.io/docs/en/opt…

  1. 安装
yarn add --dev --exact prettier

2. 在最外层添加配置文件

echo {}> .prettierrc.json

3. 测试prettier会不会自动修正

​ 新建一个test1.js文件

var a = 0
var b = 555;
var c = function () {
  return 0;
}

​ 运行prettier

npx prettier --write test1.js

​ 会自动修正

4.commitlint

  1. 安装
yarn add --save-dev @commitlint/config-conventional @commitlint/cli

创建commitlint.config.js ==前面没有.==

/**
* feature:新功能
* update:更新某功能
* fix:修补某功能的bug
* refactor:重构某个功能
* optimize: 优化构建工具或运行时性能
* style:仅样式改动
* docs:仅文档新增/改动
* chore:构建过程或辅助工具的变动
*/
module.exports = {
    extends: [
        '@commitlint/config-conventional'
    ],
    rules: {
        'type-enum': [2, 'always', [
            'feature', 'update', 'fix', 'refactor', 'optimize', 'style', 'docs', 'chore'
        ]],
        'type-case': [0],
        'type-empty': [0],
        'scope-empty': [0],
        'scope-case': [0],
        'subject-full-stop': [0, 'never'],
        'subject-case': [0, 'never'],
        'header-max-length': [0, 'always', 72]
    }
};

5 git提交规范不对导致报错

git commit -m "fix: 测试"

如果想跳过 就删除husky 的commit-msg 最后一行 不建议!

image-20221103151250267

koro1FileHeader

文件头:control + ⌘ + i 方法:control + ⌘ + t

兼容性问题

原因:

react16.8 之后框架不支持ie兼容 js不兼容 还会有语法不兼容的情况 没报错说明是框架本身的问题 不是部分语法的问题

尝试1

html添加:不好使

<meta http-equiv="X-UA-Compatible" content="IE=edge"/>

尝试2:craco.config.ts webpack添加配置

 alias: {
          'react': path.resolve('./node_modules/react'),
          'react-dom': path.resolve('./node_modules/react-dom'),
        },

尝试3

最后一招: 安装polyfill 兼容性工具解决

package.json

postcss

babel

babel7之前

"presets":["stage-0"]

browserslist

官网: browsersl.ist/

位置: package.json配置或者单独文件都可

实现功能: 设置兼容浏览器支持

能兼容node版本 ios 各种版本 近两年 哪年开始等等以及not 兼容哪些

注意`: webpack配置 proset target会覆盖browserlist 尽量不要在这配 仅js生效

命令查询

npx browserslist
npx browserslist ">1%,last 2 years"

是或的关系

chrome 79兼容的话 chrome8也兼容 但是市场占有率低 所以没列出来

   "browserslist": {
    "production": [
      ">0.2%",// 市场占有率 eg >5% in US
      "last 2 version", //最新两个版本
      "not dead",// 24个月之内都没有官网更新 不再兼容 
      "Firefox ESR",// 专为一些学校提供的内核
      "ie > 9"    
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version",
      "ie > 9"    
    ]
  },

image-20231026205151404

工程化

caniuse.com/

webpack

exclude: /node module/

bundle.js

entry 第三方库

usebuiltlns

.home_sider

 :global{
    .uni-layout-sider-children{
      background: white
    }
    .uni-menu-sub-menu{
      background: white

    }
    
  }

image.png

home.less

image.png

改样式

@layout-body-background定制主题

菜单和省分菜单

左侧菜单实际用的是省分菜单的代码 !! 坑死我了!!!!!

不能相信名字 要一点一点定位

   defaultSelectedKeys={['1']}
npm install yarn@latest -g
 Error: http://ccp.tianti.tg.unicom.local/artifactory/api/npm/sjxt-npm-virtual/@ant-design/pro-components/-/pro-components-2.6.35.tgz: Request failed "404 Not Found"
      at ResponseError.ExtendableBuiltin (D:\nodejs\node_global\node_modules\yarn\lib\cli.js:696:66)
      at new ResponseError (D:\nodejs\node_global\node_modules\yarn\lib\cli.js:802:124)
      at Request.<anonymous> (D:\nodejs\node_global\node_modules\yarn\lib\cli.js:67099:16)
      at Request.emit (node:events:513:28)
      at Request.module.exports.Request.onRequestResponse (D:\nodejs\node_global\node_modules\yarn\lib\cli.js:141760:10)
      at ClientRequest.emit (node:events:513:28)
      at HTTPParser.parserOnIncomingClient (node:_http_client:674:27)
      at HTTPParser.parserOnHeadersComplete (node:_http_common:128:17)
      at HTTPParser.execute (<anonymous>)
      at Socket.socketOnData (node:_http_client:521:22)

改了menu和layout为antd menu

.npmrc 配置多镜像源

registry=https://registry.npm.taobao.org/
@union-design:registry=http://ccp.tianti.tg.unicom.local/artifactory/api/npm/sjxt-npm-virtual/

npm config list 查看配置

设置折叠代码

  const [marginStyle, setMarginStyle] = useState<any>({
    marginLeft:'210px'
  })
 // 折叠展开
 const onChangeVisible=(e:boolean)=>{
  console.log(e)
  // 折叠
  if(e===false){
     setMarginStyle(null)

  }
  //展开
  else if(e===true){
    setMarginStyle({
      marginLeft:'210px'
    })

  }
}
  <Content className={styles.content} style={marginStyle}>

classname加判断逻辑

className={`${collapsed===true? styles.home_sider_Collapsed : styles.home_sider} `}

image-20231031150335683

第三方代码处理bundle代码

第一种 不使用polyfill

第二种 使用usage

第三种 使用entry

webpack

webpack.docschina.org/concepts/

webpack+babel

优秀博客

betheme.net/houduan/156…

了解

entry:入口 指明了需要打包文件的入口,让webpack知道从按个文件开始打包 output: 输出 指明了打包的文件要输出到哪里去,并且如何命名等 loader:加载器 由于webpack本省的功能很少,只能解析js、json等资源,所以在处于其他资源的时候就需要借助loader,webpack才能解析 plugins:插件 就好比浏览器的插件一样,可以扩展webpack的功能,我们需要下载并且引用它 mode:模式 生产模式:production 开发模式:deveplopment

1 安装webpack

conflict peer dependency or retry this command with

这个问题时因为npm的v7以后的版本都默认安装了peerDependency,它虽然解决了依赖安装的冗余的问题,但有时也会导致依赖的包版本与各个子项目依赖的包版本相互不兼容,所以安装时要加上--legacy-peer-deps

image-20231031153730356

2

image-20231031161901049

webpack

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  entry: './src/index.tsx',
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: 'bundle.js',
  },
  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
    alias: {
        app: path.resolve(__dirname, 'src/app'), // 适应你的项目结构
        services: path.resolve(__dirname, 'src/services'), // 适应你的项目结构
        routes: path.resolve(__dirname, 'src/routes'), // 适应你的项目结构
        layout:path.resolve(__dirname, 'src/layout'),
        features:path.resolve(__dirname, 'src/features'),
        components:path.resolve(__dirname, 'src/components'),
        pages: path.resolve(__dirname, 'src/pages'), // 适应你的项目结构
        context: path.resolve(__dirname, 'src/context'), // 适应你的项目结构
        assets:  path.resolve(__dirname, 'src/assets'), // 适应你的项目结构
        utils: path.resolve(__dirname, 'src/utils'), // 适应你的项目结构
      }
  },
  
  module: {
    rules: [
      {
        test: /\.(js|jsx|ts|tsx)$/,
        exclude: /node_modules/,
        use: 'babel-loader',
      },
      {
        test: /\.module.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            options: {
              modules: true,
            },
          },
          'sass-loader',
        ],
      },
     
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.s[ac]ss$/, // 匹配 .scss 或 .sass 文件
        use: [
          'style-loader', // 创建 <style> 标签并将样式插入其中
          'css-loader',   // 将 CSS 转换为 CommonJS 模块
          'sass-loader'   // 将 Sass 编译为 CSS
        ],
      },
     
      {
        test: /\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)$/,
        loader: 'file-loader',
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: 'public/index.html',
    }),
    new MiniCssExtractPlugin(),
  ],
  devServer: {
    contentBase: './build',
    port: 3000,
    historyApiFallback: true,
  },
};

报错

image-20231108144758505

img转存失败,建议直接上传图片文件

 {
        test: /\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)$/,
        loader: 'file-loader',
      },

throw new Error("Module build failed (from ./node_modules/sass-loader/dist/cjs.js):\nexpected "{".\n ╷\n2 │ import API from "!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js";\n │ ^\n ╵\n src\pages\videoZone\index.module.scss 2:101 root stylesheet");

npm install sass-loader@latest
npm install node-sass@latest
npm cache clean --force
npm install
yarn add postcss-loader    
yarn add style-loader  
yarn add sass-loader
yarn add postcss-preset-env
webpack --config webpack.config.js

webpack -cli 命令行

webpack 代码中

autoprefixer -D 自动添加浏览器前缀

 {
        test: /\.css$/,
        use: [
            'style-loader', 'css-loader',
             {
                loader: 'postcss-loader',
                options:{
                    postcssOptions:{
                        plugins:"autoprefixer"
                    }
                }
            }
        ],
      },

postcss是一个功能 给postcss再添加插件

postcss-preset-env 预设 安装对应的插件,配置对应的插件

错误:

bbs-web\node_modules\style-loader\dist\cjs.js!D:\react\bbsWebTest\bbs-web\node_modules\css-loader\dist\t\bbsWebTest\bbs-web\src\pages\postReview\index.module.scss 1 | throw new Error("Module build failed (from ./node_modules/sass-loader/dist/cjs.js):\nexpected "{".\n ╷\njectStylesIntoStyleTag.js";\n │

很多人在说版本不兼容的问题

11.9

image-20231109104529526

原因:

react16.8 之后框架不支持ie兼容 js不兼容 还会有语法不兼容的情况 没报错说明是框架本身的问题 不是部分语法的问题

尝试1 html配置

html添加:不好使

<meta http-equiv="X-UA-Compatible" content="IE=edge"/>

尝试2 修改已有webpack配置

craco.config.ts webpack添加配置

 alias: {
          'react': path.resolve('./node_modules/react'),
          'react-dom': path.resolve('./node_modules/react-dom'),
        },

尝试3 browserslist

官网: browsersl.ist/

位置: package.json配置或者单独文件都可

实现功能: 设置兼容浏览器支持

能兼容node版本 ios 各种版本 近两年 哪年开始等等以及not 兼容哪些

注意`: webpack配置 proset target会覆盖browserlist 尽量不要在这配 仅js生效

命令查询

npx browserslist
npx browserslist ">1%,last 2 years"

是或的关系

chrome 79兼容的话 chrome8也兼容 但是市场占有率低 所以没列出来

   "browserslist": {
    "production": [
      ">0.2%",// 市场占有率 eg >5% in US
      "last 2 version", //最新两个版本
      "not dead",// 24个月之内都没有官网更新 不再兼容 
      "Firefox ESR",// 专为一些学校提供的内核
      "ie > 9"    
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version",
      "ie > 9"    
    ]
  },

image-20231026205151404

工程化

caniuse.com/

webpack

exclude: /node module/

bundle.js

entry 第三方库

usebuiltlns

webpack

webpack.docschina.org/concepts/

尝试4 polyfill

最后一招: 安装polyfill 兼容性工具解决

package.json

postcss

babel

babel7之前

"presets":["stage-0"]

webpack+babel

优秀博客

betheme.net/houduan/156…

了解

entry:入口 指明了需要打包文件的入口,让webpack知道从按个文件开始打包 output: 输出 指明了打包的文件要输出到哪里去,并且如何命名等 loader:加载器 由于webpack本省的功能很少,只能解析js、json等资源,所以在处于其他资源的时候就需要借助loader,webpack才能解析 plugins:插件 就好比浏览器的插件一样,可以扩展webpack的功能,我们需要下载并且引用它 mode:模式 生产模式:production 开发模式:deveplopment

webpack

官网: webpack.docschina.org/concepts/

1 安装webpack

安装webpack和cli

webpack -cli 命令行

webpack 代码中

11.9

image-20231109104529526

原因:

react16.8 之后框架不支持ie兼容 js不兼容 还会有语法不兼容的情况 没报错说明是框架本身的问题 不是部分语法的问题

尝试1 html配置

html添加:不好使

<meta http-equiv="X-UA-Compatible" content="IE=edge"/>

尝试2 修改已有webpack配置

craco.config.ts webpack添加配置

 alias: {
          'react': path.resolve('./node_modules/react'),
          'react-dom': path.resolve('./node_modules/react-dom'),
        },

尝试3 browserslist

官网: browsersl.ist/

位置: package.json配置或者单独文件都可

实现功能: 设置兼容浏览器支持

能兼容node版本 ios 各种版本 近两年 哪年开始等等以及not 兼容哪些

注意`: webpack配置 proset target会覆盖browserlist 尽量不要在这配 仅js生效

命令查询

npx browserslist
npx browserslist ">1%,last 2 years"

是或的关系

chrome 79兼容的话 chrome8也兼容 但是市场占有率低 所以没列出来

   "browserslist": {
    "production": [
      ">0.2%",// 市场占有率 eg >5% in US
      "last 2 version", //最新两个版本
      "not dead",// 24个月之内都没有官网更新 不再兼容 
      "Firefox ESR",// 专为一些学校提供的内核
      "ie > 9"    
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version",
      "ie > 9"    
    ]
  },

image-20231026205151404

工程化

caniuse.com/

webpack

exclude: /node module/

bundle.js

entry 第三方库

usebuiltlns

webpack

webpack.docschina.org/concepts/

尝试4 polyfill

最后一招: 安装polyfill 兼容性工具解决

package.json

postcss

babel

babel7之前

"presets":["stage-0"]

webpack+babel

优秀博客

betheme.net/houduan/156…

了解

entry:入口 指明了需要打包文件的入口,让webpack知道从按个文件开始打包 output: 输出 指明了打包的文件要输出到哪里去,并且如何命名等 loader:加载器 由于webpack本省的功能很少,只能解析js、json等资源,所以在处于其他资源的时候就需要借助loader,webpack才能解析 plugins:插件 就好比浏览器的插件一样,可以扩展webpack的功能,我们需要下载并且引用它 mode:模式 生产模式:production 开发模式:deveplopment

webpack

官网: webpack.docschina.org/concepts/

1 安装webpack

安装webpack和cli

webpack -cli 命令行

webpack 代码中

conflict peer dependency or retry this command with

这个问题时因为npm的v7以后的版本都默认安装了peerDependency,它虽然解决了依赖安装的冗余的问题,但有时也会导致依赖的包版本与各个子项目依赖的包版本相互不兼容,所以安装时要加上--legacy-peer-deps

image-20231031153730356

2

image-20231031161901049

2 .webpack文件备份1

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
​
module.exports = {
  entry: './src/index.tsx',
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: 'bundle.js',
  },
  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
    alias: {
        app: path.resolve(__dirname, 'src/app'), // 适应你的项目结构
        services: path.resolve(__dirname, 'src/services'), // 适应你的项目结构
        routes: path.resolve(__dirname, 'src/routes'), // 适应你的项目结构
        layout:path.resolve(__dirname, 'src/layout'),
        features:path.resolve(__dirname, 'src/features'),
        components:path.resolve(__dirname, 'src/components'),
        pages: path.resolve(__dirname, 'src/pages'), // 适应你的项目结构
        context: path.resolve(__dirname, 'src/context'), // 适应你的项目结构
        assets:  path.resolve(__dirname, 'src/assets'), // 适应你的项目结构
        utils: path.resolve(__dirname, 'src/utils'), // 适应你的项目结构
      }
  },
  
  module: {
    rules: [
      {
        test: /.(js|jsx|ts|tsx)$/,
        exclude: /node_modules/,
        use: 'babel-loader',
      },
      {
        test: /.module.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            options: {
              modules: true,
            },
          },
          'sass-loader',
        ],
      },
     
      {
        test: /.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /.s[ac]ss$/, // 匹配 .scss 或 .sass 文件
        use: [
          'style-loader', // 创建 <style> 标签并将样式插入其中
          'css-loader',   // 将 CSS 转换为 CommonJS 模块
          'sass-loader'   // 将 Sass 编译为 CSS
        ],
      },
     
      {
        test: /.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)$/,
        loader: 'file-loader',
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: 'public/index.html',
    }),
    new MiniCssExtractPlugin(),
  ],
  devServer: {
    contentBase: './build',
    port: 3000,
    historyApiFallback: true,
  },
};

3. 报错1 文件配置

image.png

 {
        test: /.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)$/,
        loader: 'file-loader',
      },

报错2 sass loader

throw new Error("Module build failed (from ./node_modules/sass-loader/dist/cjs.js):\nexpected "{".\n ╷\n2 │ import API from "!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js";\n │ ^\n ╵\n src\pages\videoZone\index.module.scss 2:101 root stylesheet");

image-20231109105155209

安装css loader命令

npm install sass-loader@latest
npm install node-sass@latest
npm cache clean --force
npm install
yarn add postcss-loader    
yarn add style-loader  
yarn add sass-loader
yarn add postcss-preset-env
webpack --config webpack.config.js

autoprefixer -D 自动添加浏览器前缀

 {
        test: /.css$/,
        use: [
            'style-loader', 'css-loader',
             {
                loader: 'postcss-loader',
                options:{
                    postcssOptions:{
                        plugins:"autoprefixer"
                    }
                }
            }
        ],
      },

postcss是一个功能 给postcss再添加插件

postcss-preset-env 预设 安装对应的插件,配置对应的插件

1 | throw new Error("Module build failed (from ./node_modules/sass-loader/dist/cjs.js):\nexpected "{".\n ╷\njectStylesIntoStyleTag.js";\n │

很多人在说版本不兼容的问题

1 .打包css-loader 顺序 自定义解析

 {
        test: /.css$/,
        use: ['style-loader', 'css-loader','postcss-loader'],
      },
      
  完整写法 是对象 里面可以加options 从右向左读取 style-loader写在前面,在css基础上继续读取
   {
        test: /.css$/,
        use: [
          { loader: 'style-loader'}, 
          {
            loader: 'css-loader',
            options: {
              modules: true,
            },
          }
        ],
      },

less 报错 添加less

 {
        test: /.less$/,
        use: ['style-loader', 'css-loader','less-loader'],// 先less 再css 再style
 },

postcss插件 -postcssOptions-plugins

1 postcss是一个功能 给postcss再添加插件

{
        test: /.css$/,
        use: ['style-loader', 'css-loader','postcss-loader'],// postcss 在里面添加插件 自动添加浏览器前缀 css样式重置 
},

2 autoprefixer -D 自动添加浏览器前缀

 {
        test: /.css$/,
        use: [
            'style-loader',
            'css-loader',
             {
                loader: 'postcss-loader',
                options:{
                    postcssOptions:{ // 抽取从这里开始 规则是插件自己定义的 
                        plugins:"autoprefixer"
                    }
                }
            }
        ],
      },

3 postcss-loader可以单独抽取一个文件 postcss.config.js*=*> module.exports={plugins:"autoprefixer"}

postcss插件-postcss-preset-env 插件

1 预设 安装对应的插件,配置对应的插件 相当于内置autoprefixer

可以将现代css转化为大多数浏览器认识的css,并且根据目标浏览器或运行时环境添加所需的 polyfill

module.exports={plugins:"postcss-preset-env"}

2 将px转化为rem vw

=> webpack不是本身强大, 社区强大 插件很多

现代的前端开发模式,不需要手动添加浏览器前缀 比如umi

2. 打包资源文件--加载文件-内置

image-20231110094627679

   
      {
        test: /.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)$/,
        // loader: 'file-loader',
        type: "asset"
      },
 {
        test: /.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)$/,
        // loader: 'file-loader',
        type: "asset/resource" // 发现生成图片,而且重命名 设置了新路径
        //  type: "asset/inline" // 将图片base64编码  直接放到js中
      },
    

性能:

inline高 优:少发送n个文件次http网络请求,缺点: js时间长

resource: 缺:多网络请求

合理规范: 对于小图片base64 编码,对于大图片单独url-设置

默认asset:自动

 {
        test: /.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)$/,
        // loader: 'file-loader',
        // 设置加载类型
        type: "asset",
        // 控制加载大小
        parser:{
          dataUrlCondition:{
          maxSize:60*1024
          }
        },
        // 重命名: 占位符 +8位hash+扩展符 
        generator:{
          // hash值 唯一
          filename:"[name]_[hash:8][ext]"
        }
      },

3 打包js文件-babel-loader

es6不兼容ie8,只在ie10、ie11中兼容了部分es6的API;实现兼容的方法:可以利用“babel-loader”在ie8中把es6的代码编译成es5执行,使用“npm install babel-loader”即可安装

es6转es5

1 babel

 {
        test: /.(js|jsx|ts|tsx)$/,
        exclude: /node_modules/,
        use: 'babel-loader',
        options:{
          plugins:[
            // 箭头函数变function  不可能每个语法都用插件
            "@bable/plugin-transform-arrow-functions"
           ]
        }
      },

2 babel预设 常见三种预设

babel.config.js

module.exports={
        // plugins:[
        //   // 箭头函数变function  不可能每个语法都用插件
        //   "@bable/plugin-transform-arrow-functions"
        //  ]
        presets: [
            "@babel/preset-env",//es6
            "@babel/preset-react",
            "@babel/preset-typescript"
          ]      
}
   "build": "webpack --mode development",

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
​
module.exports = {
  entry: './src/index.tsx',
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: 'bundle.js',
    publicPath :'/bbs/'
  },
  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
    alias: {
        app: path.resolve(__dirname, 'src/app'), 
        services: path.resolve(__dirname, 'src/services'), 
        routes: path.resolve(__dirname, 'src/routes'), 
        layout:path.resolve(__dirname, 'src/layout'),
        features:path.resolve(__dirname, 'src/features'),
        components:path.resolve(__dirname, 'src/components'),
        pages: path.resolve(__dirname, 'src/pages'), 
        context: path.resolve(__dirname, 'src/context'), 
        assets:  path.resolve(__dirname, 'src/assets'), 
        utils: path.resolve(__dirname, 'src/utils'), 
      }
  },
  
  module: {
    rules: [
      {
        test: /.(js|jsx|ts|tsx)$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      },
      {
        test: /.module.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          { loader: 'style-loader'},
          {
            loader: 'css-loader',
            options: {
              modules: true,
            },
          },
          'sass-loader',
        ],
      },
     
      {
        test: /.css$/,
        use: ['style-loader', 'css-loader',
        {
          loader: 'postcss-loader',
          options: {
            postcssOptions:{ // 抽取从这里开始 规则是插件自己定义的 
              plugins:"postcss-preset-env"
          }
          },
        },],
      },
      {
        test: /.s[c]ss$/, // 匹配 .scss 或 .sass 文件
        use: [
          'style-loader', // 创建 <style> 标签并将样式插入其中
          'css-loader',   // 将 CSS 转换为 CommonJS 模块
          'sass-loader'   // 将 Sass 编译为 CSS
        ],
      },
      {
        test: /.less$/, // 匹配 .scss 或 .sass 文件
        use: [
          'style-loader', // 创建 <style> 标签并将样式插入其中
          'css-loader',   // 将 CSS 转换为 CommonJS 模块
          'less-loader'   // 将 less 编译为 CSS
        ],
      },
     // 资源文件
      {
        test: /.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)$/,
        // loader: 'file-loader',
        // 设置加载类型
        type: "asset",
        // 控制加载大小
        parser:{
          dataUrlCondition:{
          maxSize:60*1024
          }
        },
        // 重命名: 占位符 +8位hash+扩展符 
        generator:{
          // hash值 唯一
          filename:"[name]_[hash:8][ext]"
        }
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: 'public/index.html',
    }),
    new MiniCssExtractPlugin(),
  ],
  devServer: {
    contentBase: './build',
    port: 3000,
    historyApiFallback: true,
  },
};

craco 直接改webpack

问题截图:

This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to: - add a fallback 'resolve.fallback: { "process": require.resolve("process/browser") }' - install 'process' If you don't want to include a polyfill, you can use an empty module like this: resolve.fallback: { "process": false } @ ./src/App.vue?vue&type=script&lang=js 1:0-189 1:0-189 1:190-368 1:190-368 @ ./src/App.vue 2:0-54 3:0-49 3:0-49 6:49-55 @ ./src/main.js 4:0-28 6:22-25

webpack compiled with 1 error 问题描述: 查了很多资料发现是因为webpack版本引起的,在webpack5中移除了nodejs核心模块的polyfill自动引入,具体可查看这篇文章

wenku.baidu.com/view/7b8427…

通过对日志的分析因为有其他组件引用到了 polyfills 的核心组件并没有安装,所以报错了,这里需要执行 npm install 命令进行包安装即可。

原因是由于在webpack5中移除了nodejs核心模块的polyfill自动引入,所以需要手动引入

解决方案: 1、运行下面这行指令,安装在 Webpack 中 Polyfill Node.js 核心模块。

npm install node-polyfill-webpack-plugin 2、在vue.config.json中添加(本文作者没有用到这一步,用第一步命令安装后就可以运行)

//头部引用 const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')

//加入 configureWebpack: { plugins: [new NodePolyfillPlugin()] } 完整vue.config.json文件如下:

const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')

module.exports = defineConfig({ configureWebpack: { plugins: [new NodePolyfillPlugin()] } })

craco 直接改webpack

问题截图:

This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to: - add a fallback 'resolve.fallback: { "process": require.resolve("process/browser") }' - install 'process' If you don't want to include a polyfill, you can use an empty module like this: resolve.fallback: { "process": false } @ ./src/App.vue?vue&type=script&lang=js 1:0-189 1:0-189 1:190-368 1:190-368 @ ./src/App.vue 2:0-54 3:0-49 3:0-49 6:49-55 @ ./src/main.js 4:0-28 6:22-25

webpack compiled with 1 error 问题描述: 查了很多资料发现是因为webpack版本引起的,在webpack5中移除了nodejs核心模块的polyfill自动引入,具体可查看这篇文章

wenku.baidu.com/view/7b8427…

通过对日志的分析因为有其他组件引用到了 polyfills 的核心组件并没有安装,所以报错了,这里需要执行 npm install 命令进行包安装即可。

原因是由于在webpack5中移除了nodejs核心模块的polyfill自动引入,所以需要手动引入

解决方案: 1、运行下面这行指令,安装在 Webpack 中 Polyfill Node.js 核心模块。

npm install node-polyfill-webpack-plugin 2、在vue.config.json中添加(本文作者没有用到这一步,用第一步命令安装后就可以运行)

//头部引用 const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')

//加入 configureWebpack: { plugins: [new NodePolyfillPlugin()] } 完整vue.config.json文件如下:

const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')

module.exports = defineConfig({ configureWebpack: { plugins: [new NodePolyfillPlugin()] } })

conflict peer dependency or retry this command with

这个问题时因为npm的v7以后的版本都默认安装了peerDependency,它虽然解决了依赖安装的冗余的问题,但有时也会导致依赖的包版本与各个子项目依赖的包版本相互不兼容,所以安装时要加上--legacy-peer-deps

image-20231031153730356

2

image-20231031161901049

域名重定向网站打不开

host文件 内容清空 -还是打不开 但是这个错误不报了 排查下一个问题

C:\Windows\System32\drivers\etc


 Copyright (c) 1993-2009 Microsoft Corp.

# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
127.0.0.1       localhost
10.161.142.99 datav.cloud.view.newbuy.chinaunicom.cn
10.161.142.99 datav.oss.datav.cloud.view.newbuy.chinaunicom.cn
10.161.142.99 oss.datav.cloud.view.newbuy.chinaunicom.cn
#	::1             localhost


54.192.150.46 developer.mozilla.org

# This line is auto added by aTrustAgent, do not modify, or aTrustAgent may unable to work
127.0.0.1	localhost.sangfor.com.cn

# Added by Docker Desktop
192.168.124.5 host.docker.internal
192.168.124.5 gateway.docker.internal
# To allow the same kube context to work on the host and the container:
127.0.0.1 kubernetes.docker.internal
# End of section

注意 前缀问题

本系统需要以bbs开头 在云端服务器需要配置bbs前缀方可访问

后续增加integrate功能 以integrate开头 如需其他前缀 自行配置

静态资源文件也统一以bbs开头 配置在cracod的webpack 如需更改 自行

nginx也配置了bbs开头

目前存在的一些问题

1 ts管理不严格 很多类型使用泛型

2 测试和生产变量未区分配置 目前是根据测试和生产地址来手动配置不同的地址

eg: let headerUrl= url.startsWith('http://10.111/')?2:1;

实现思路 :

const { REACT_APP_ENV } = process.env;

组件中判断变量实现不同的跳转逻辑

const InspectorWrapper = process.env.NODE_ENV === 'development' ? Inspector : React.Fragment;

const Layout: React.FC = ({ children }) => { return {children}; }; 3 未配置前端测试类 test.js 批量统一测试

4 兼容性问题未配置 统一使用polyfill处理 解决中

5 提交规范未完全生效 关键字配置生效 拦截未生效

6 删除无用代码 影响观看

7 路由拦截 :属于接口管理规范 后端返回的格式必须满足resultVo格式 否则前端全部拦截 promise结果返回reject

前端常用宝藏网站

1、CODEPEN

首先要介绍的第一个网站是CODEPEN,这是每一个前端工程师都知道的网站,顾名思义就是代码笔,是前端设计师测试在线测试代码的神器,同时也是前端设计学习和调试、寻找灵感的网站,全球超过180万以上前端设计师在这里分享作品和学习前端技术,除了支持自己的在线调试,还可以查看一些流行炫酷的JS效果。在这里大多数分享的作品都是开源的,你可以学习到优秀的开发人员是如何构建动画和测试功能。

2、w3school

这个网站提供了一些可供开发者参考的学习路径和学习资料,对初学者来说很有用的一个网站,比较适合前端新人,包括HTML、JavaScript、CSS等基本教程,教的都是很简单很容易上手的基础知识,如果你是零基础的前端小白,我建议你可以从这里开始,边学边练。

3、Responsively

一款专用于web开发的浏览器,在地址栏输入网址,你就能看到该网页在移动端和桌面端的显示效果,便于调整排版,提高开发效率,整体来说是一款非常不错的web开发工具。

4、Small Dev Tools

Small Dev Tools是一个前端工具网站,包含了很多实用的功能,比如JSON解码器、JSON格式化程序、UTF8编码、Base64编码、Base64解码、CSS格式化程序、CSS压缩器等。

5、Web Page Test

任何网站的性能一直是一个热门话题。为你的网站提供更慢的服务可能会导致销售额大幅下降成SEO评级降低。网页测试工具将帮助你了解Web应用程序发送到用户浏览器的用户,专业且详细地让你明白如何优化网站。

6、overAPI

不论是多么优秀的程序员都不可能记住一切。倘若在你编写程序的过程中碰到问题需要查阅手册的时候有现成的在线手册参考可以大大提升效率。而overAPI就是这样一个网站,它收集了众多对开发人员非常有用的手册。

7、Vscode Dev

我们可以通过Vscode Dev访问远程GitHub存储库,与GitHub插件相结合是进行代码审查的绝佳伴侣。

8、Can I use

Can I use是一款前端兼容性自查工具。将代码交付到生产环境时,了解你所依赖的本机浏览器功能的支持非常重要,这个可以帮助你了解其对浏览器的整体支持。

9、daily.dev

daily.dev是一个为开发者而生的信息聚合平台,提供了超过350+个开发者资讯来源,汇总了一万多个技术标签,是一个获取最新开发资讯的好渠道。除了Chrome插件之外,它还提供了Firefox、Edge等插件供用户下载。

10、CSS-TRICKS

很多前端工程师都讨厌写CSS,但CSS又是必需的,那这个时候你就缺少不了CSS-TRICKS。这个网站,它不断地在更新一些优秀的教程和技巧,也一直在改版,为前端社区作出了很大的贡献。