1.项目能力支持
1.项目初始化脚手架
1.前端编码规范工程化(lint工具、Node CLI等)
2.用工具提升项目的编码规范,如:eslint
、stylelint
、commitlint
、markdownlint
、husky等
3.工具对于JavaScript
、Typescript
、React
、Vue
等不同类型的前端项目下的标准的语法限制;
2.相关基础功能
• React : 前端页面展示框架; • Redux :状态管理; • React Router :前端路由; • Connected React Router :支持将 Redux 与 React Router 进行绑定; • Express 服务端; • TypeScript 类型检查; • Webpack 打包构建工具; • Babel : ES6+ 转 ES5 工具; • nodemon :监测 Node 应用变化时,自动重启服务器; • axios 基于 Promise 的 HTTP 客户端; • react-helmet :在客户端及服务端上管理标题、 meta 、样式和脚本标签; • loadable-component :支持组件的懒加载; • Webpack Dev Middleware :通过 Express 服务器提供 webpack 服务; • Webpack Hot Middleware :支持基于 Express 的热更新; • Webpack Bundle Analyzer :打包分析工具; • morgan :服务器日志; • terser-webpack-plugin :压缩 JS ; • css-minimizer-webpack-plugin :压缩 CSS ;3.运行指令
使用cross-env提供跨平台的设置及环境变量:
## step1
====================================安装初始脚手架
命令行 start
sudo npm install -g encode-fe-lint
sudo encode-fe-lint init
React 项目 (TypeScript)
Y Y Y
====================================命令行 end
## step2
基础环境配置
- 查看 package.json 文件
"private"
"script"-"preinstall"/"prepare"/"init"
"engines"
"devDependencies"
"dependencies"
====================================命令行 start
sudo npm install -g pnpm
sudo pnpm install
====================================命令行 end
2.项目初始化配置
项目目录:
1. 新建 babel.config.js,以及内部配置
2. tsconfig 的配置, tsconfig.json
sudo npm install -g typescript
sudo tsc --init
3. 实现相关的 postcss,创建 postcss.config.js
4. webpack cross-env
我们需要客户端和服务端渲染,所以如下
webpack 目录
- base.config.ts
- client.config.ts
- server.config.ts
我们看到网上很多都是如下
- webpack.common.js
- webpack.dev.js
- webpack.prod.js
webpack 是纯用于打包的,和 js/ts 没有关系的
webpack5 中 MiniCssExtractPlugin,将 css 分离出
progressPlugin 编译进度包
webpack-manifest-plugin ssr 中需要引入的,页面中的基本信息
loadablePlugin 分包的方式引入子包的内容
DefinePlugin 定义全局变量
bundle-analyze plugin 分析线上的包
⭐️⭐️⭐️⭐️⭐️⭐️⭐️
通用的能力做抽离,根据不同的环境,进行不同的配置。
先打包构建,生产产物
nodemon.json,开发过程中,可以监听 public 下面文件的变化&&服务端的更新
到这一步为止,基础环境已经配置完成.不用脚手架,自己手写也可以,加油吧~
3.客户端配置
1.入口文件
// src/app/index.tsx
const App = ({ route }: Route): JSX.Element => (
<div className={styles.App}>
<Helmet {...config.APP} />
<Link to="/" className={styles.header}>
<img src={logo} alt="Logo" role="presentation" />
<h1>
<em>{config.APP.title}</em>
</h1>
</Link>
<hr />
{/* Child routes won't render without this */}
{renderRoutes(route.routes)}
</div>
};
// src/client/index.tsx
const render = (Routes: RouteConfig[]) =>
ReactDOM.hydrate(
<Provider store={store}>
<ConnectedRouter {...props}>{renderRoutes(Routes)}</ConnectedRouter>
</Provider>,
document.getElementById('react-view'),
);
// loadable-component setup
loadableReady(() => render(routes as RouteConfig[]));
2.错误边界处理
import { ReactNode, PureComponent } from "react";
interface Props {
children?: ReactNode;
}
interface State {
error: Error | null;
errorInfo: { componentStack: string } | null;
}
class ErrorBoundary extends PureComponent<Props, State> {
constructor(props: Props) {
super(props);
this.state = { error: null, errorInfo: null };
}
componentDidCatch(error: Error, errorInfo: { componentStack: string }): void
// Catch errors in any components below and re-render with error message
this.setState({ error, errorInfo });
// You can also log error messages to an error reporting service here
}
render(): ReactNode {
const { children } = this.props;
const { errorInfo, error } = this.state;
// If there's an error, render error path
return errorInfo ? (
<div data-testid="error-view">
<h2>Something went wrong.</h2>
<details style={{ whiteSpace: "pre-wrap" }}>
{error && error.toString()}
<br />
{errorInfo.componentStack}
</details>
</div>
) : (
children || null
);
}
}
export default ErrorBoundary;
3.页面入口配置
const Home: FC<Props> = (): JSX.Element => {
const dispatch = useDispatch();
const { readyStatus, items } = useSelector(
({ userList }: AppState) => userList,
shallowEqual
);
// Fetch client-side data here
useEffect(() => {
dispatch(fetchUserListIfNeed());
}, [dispatch]);
const renderList = () => {
if (!readyStatus || readyStatus === "invalid" || readyStatus === "request"
return <p>Loading...</p>;
if (readyStatus === "failure") return <p>Oops, Failed to load list!</p>;
return <List items={items} />;
};
return (
<div className={styles.Home}>
<Helmet title="Home" />
{renderList()}
</div>
);
};
// Fetch server-side data here
export const loadData = (): AppThunk[] => [
fetchUserListIfNeed(),
// More pre-fetched actions...
];
export default memo(Home);
1
4.路由配置
export default [
{
component: App,
routes: [
{
path: "/",
exact: true,
component: AsyncHome, // Add your page here
loadData: loadHomeData, // Add your pre-fetch method here
},
{
path: "/UserInfo/:id",
component: AsyncUserInfo,
loadData: loadUserInfoData,
},
{
component: NotFound,
},
],
},
] as RouteConfig[];
4.服务端配置
1.请求配置
// 使用https://jsonplaceholder.typicode.com提供的接口设置请求
export default {
HOST: 'localhost',
PORT: 3000,
API_URL: 'https://jsonplaceholder.typicode.com',
APP: {
htmlAttributes: { lang: 'zh' },
title: '萍宝贝 ES6 项目实战',
titleTemplate: '萍宝贝 ES6 项目实战 - %s',
meta: [
{
name: 'description',
content: 'wikiHong ES6 React 项目模板',
},
],
},
};
2.入口文件
const app = express();
// Use helmet to secure Express with various HTTP headers
app.use(helmet({ contentSecurityPolicy: false }));
// Prevent HTTP parameter pollution
app.use(hpp());
// Compress all requests
app.use(compression());
// Use for http request debug (show errors only)
app.use(logger('dev', { skip: (_, res) => res.statusCode < 400 }));
app.use(favicon(path.resolve(process.cwd(), 'public/logo.png')));
app.use(express.static(path.resolve(process.cwd(), 'public')));
// Enable dev-server in development
if (__DEV__) devServer(app);
// Use React server-side rendering middleware
app.get('*', ssr);
// @ts-expect-error
app.listen(config.PORT, config.HOST, (error) => {
if (error) console.error(chalk.red(`==>
标签:ES6,13,const,true,app,React,webpack,error,config
From: https://blog.csdn.net/qq_34334992/article/details/141562309