Appearance
CLI 介绍
React@18-hooks 风格的 typescript 项目,构建工具采用了 vite
配备了标准的大厂规范的 prettier + eslint + stylelint
路由采用 react-router-dom@6
工具库采用 yjr-utils
状态管理采用 mobx
下载安装
cmd
> npm i yjr-cli -g
验证下载是否成功
cmd
> yjrcli -v
如何使用
创建项目
cmd
> yjrcli create-app myApp
启动项目查看
cmd
> cd myApp
> npm i --no-fund
> npm run dev
全局状态管理
store.ts
具体使用可参考 mobx 文档 以及 mobx-react
js
import { observable, configure } from "mobx";
// 将 proxy 包装过的数据转换为 js 数据
export { toJS } from "mobx";
/**
* 用到全局状态的组件需要用 observer 包一下
* 如果上游组件能带你上一起更新则不需要用 observer 包裹
*/
export { observer } from "mobx-react-lite";
configure({
enforceActions: "never",
});
// 在此处定义公共状态数据
const globalData = {
count: 0,
};
// 后续通过 $store 来访问全局状态
export const $store = observable(globalData);
路由
RouteViews.tsx
路由配置文件,可随意更改位置,默认为 BrowserRouter(history 模式)
可在 main.ts 中更改为 HashRouter(hash 模式)
js
import ReactDOM from 'react-dom/client';
import App from './App';
import { HashRouter } from 'react-router-dom';
import './main.scss';
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<HashRouter>
<App />
</HashRouter>,
);
具体用法可参考 react-router-dom 文档
文件中示例做了简单的配置和路由懒加载示范
js
import { Route, Routes } from "react-router-dom";
import { lazy, Suspense } from "react";
const Home = lazy(async () => await import("@cpt/Home"));
const Error = (): React.ReactElement => <div className="notFound">404</div>;
export default function RouteViews(): React.ReactElement {
return (
<>
<Routes>
<Route
path="/"
element={
<Suspense>
<Home></Home>
</Suspense>
}
></Route>
<Route path="*" element={<Error></Error>}></Route>
</Routes>
</>
);
}
package.json 介绍
版本号中 * 意为始终使用最新版本
json
{
"scripts": {
// 开发环境 -m注入环境 -c指定配置文件
"dev": "vite -m=dev -c=cli.config.ts",
// 打包 -m注入环境 -c指定配置文件
"build": "npm run lintFix && vite build -m=prod -c=cli.config.ts",
// 预览,运行前确保已有dist目录
"preview": "vite preview -c=cli.config.ts",
// 自动修复和检查项目中出现的lint错误
"lintFix": "tsc && stylelint \"**/*.scss\" --fix && eslint --fix src"
},
"dependencies": {
"mobx": "^6.9.0",
"mobx-react-lite": "^3.4.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.14.0",
"yjr-utils": "*"
},
"devDependencies": {
// 开发环境依赖包,里面包含了开发环境下所需要的 31 个依赖包
"yjrcli-env": "*"
}
}
cli.config.ts 介绍
脚手架配置 具体配置可参考 vite 官网 已预设好了常用的配置
打包产物默认兼容 overrideBrowserslist 中声明的浏览器类型版本
根据需要可自行配置 代理 移动端适配 手动分包等
js
export default defineConfig({
// 打包后资源路径
base: "./",
server: {
// 控制台暴露ip
host: "0.0.0.0",
// 启动后自动打开浏览器
open: true,
// 端口号
port: 4399,
},
// 环境变量命名需要以 yjr_ 开头
envPrefix: "yjr",
css: {
postcss: {
plugins: [
// postcss预设
postcssPresetEnv(),
// 自动加css前缀
autoprefixer({
overrideBrowserslist,
}),
],
},
// 默认导入全局scss文件,无需引入
preprocessorOptions: {
scss: {
additionalData: `@import '@/global.scss';`,
},
},
// 开发环境下开启css-sourcemap
devSourcemap: true,
},
resolve: {
// 路径别名
alias: {
"@": resolve(__dirname, "./src"),
"@cpt": resolve(__dirname, "./src/components"),
"@store": resolve(__dirname, "./src/store.ts"),
},
},
// 插件
plugins: [
// 旧浏览器支持
legacy({
targets: overrideBrowserslist,
}),
pluginReact(),
vitePluginEslint({
failOnError: false,
}),
],
build: {
minify: "terser",
terserOptions: {
// 打包会移除代码中的日志和debug
compress: {
drop_console: true,
drop_debugger: true,
},
},
// 每个chunk不能超过244kb
chunkSizeWarningLimit: 244,
// rollup配置
rollupOptions: {
output: {
// 手动分包
manualChunks(id) {
if (id.includes("node_modules")) {
return id.split("node_modules/")[1].split("/")[0];
}
},
// 入口文件改名
entryFileNames: "js/entry.[hash].js",
// chunk改名
chunkFileNames: "js/chunks/[name].[hash].js",
// asset改名
assetFileNames: "[ext]/[name].[hash].[ext]",
},
},
},
});
.eslintrc.cjs 介绍
配置来自 yjrcli-env,可根据需求自行修改、覆盖、替换 rules 中的配置
js
const { eslintConfig } = require("yjrcli-env");
module.exports = eslintConfig;
自定义规则示范
开启规则 "arrow-body-style"
js
const { eslintConfig } = require("yjrcli-env");
eslintConfig.rules["arrow-body-style"] = "error";
module.exports = eslintConfig;
.stylelintrc.cjs 介绍
配置来自 yjrcli-env,可根据需求自行修改、覆盖、替换 rules 中的配置
js
const { stylelintConfig } = require("yjrcli-env");
module.exports = stylelintConfig;
自定义规则示范
修改规则 "selector-max-id" 的值为 0
js
const { stylelintConfig } = require("yjrcli-env");
stylelintConfig.rules["selector-max-id"] = 0;
module.exports = stylelintConfig;
.env 文件
.dev 为开发环境 .prod 为线上环境 可根据需求添加其他环境 如灰度、日常、预发等
脚本也要同步环境,比如你配置了预发环境 pre, 那么脚本中的-m=dev 就要替换成-m=pre,并再配置一份 .env.pre 的文件
json
{
"scripts": {
// 新增脚本
"pre": "vite -m=pre -c=cli.config.ts",
"build:pre": "npm run lintFix && vite build -m=pre -c=cli.config.ts"
}
}
新增的变量要在 src/env.d.ts 中声明 且变量命名默认以 yjr_开头,可在 cli.config 中修改
ts
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly yjr_environment: string;
// 新增环境变量 yjr_demo
readonly yjr_demo: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}