react组件库开发实录·一 项目搭建

First Post:

Last Update:

准备工作

创建项目

1
2
3
mkdir react-erp
cd react-erp
npm init -y

安装相关依赖

1
2
3
4
5
6
npm i react react-dom -S
npm i webpack webpack-dev-server webpack-cli -D
# typescript & loader
npm i typescript babel-loader @babel/core @babel/preset-env style-loader css-loader ts-loader -D
# HtmlWebpackPlugin
npm install html-webpack-plugin -D

搭建目录结构

1
mkdir src src/components src/types src/utils src/hooks src/servers src/doc

目录结构

配置webpack

新建配置文件

1
touch webpack.config.js

写入配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
mode: 'development',
devtool: 'eval-source-map',
entry: {
doc: './src/doc/index.tsx'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
test: /\.(js|jsx)?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.(ts|tsx)?$/,
use: ['ts-loader']
},
]
},
devServer: {
client: {
progress: true,
},
hot: true,
open: true
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
}),
],
resolve: {
extensions: ['.tsx', '.ts', '.js'],
}
};

新建模板文件:

1
touch src/index.html

编写模板文件index.html:

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

配置TypeScript

新建配置文件

1
touch tsconfig.json

写入配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"compilerOptions": {
"jsx": "react",
"module": "commonjs",
"target": "es5",
"sourceMap": true,
"esModuleInterop": true,
"baseUrl": ".",
},
"exclude": [
"node_modules",
]
}

安装react-route来管理路由

1
2
npm i react-router react-router-dom -S
npm i @types/react-router @types/react-router-dom -D

touch src/doc/index.tsx:

1
2
3
4
5
6
7
8
import React from 'react';
import { render } from "react-dom";
import { HashRouter } from 'react-router-dom';
import 'antd/dist/antd.css';
import App from './app';

const rootElement = document.getElementById("root");
render(<HashRouter><App /></HashRouter>, rootElement);

touch src/doc/app.tsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import React from 'react';
import { useRoutes } from 'react-router-dom';
import { Layout, Menu, Breadcrumb } from 'antd';
import routes from './routes';
import './index.css';

const { Header, Content, Footer, Sider } = Layout;
const { SubMenu } = Menu;

export default () => {

const element = useRoutes(routes);

return (
<Layout style={{ minHeight: '100vh' }}>
<Sider collapsible>
<div className="logo" />
<Menu theme="dark" defaultSelectedKeys={['1']} mode="inline">
<SubMenu key="sub1" title="Components">
<Menu.Item key="1">Tom</Menu.Item>
<Menu.Item key="2">Bill</Menu.Item>
<Menu.Item key="3">Alex</Menu.Item>
</SubMenu>
<SubMenu key="sub1" title="Hooks">
<Menu.Item key="1">Tom</Menu.Item>
<Menu.Item key="2">Bill</Menu.Item>
<Menu.Item key="3">Alex</Menu.Item>
</SubMenu>
<SubMenu key="sub1" title="Utils">
<Menu.Item key="1">Tom</Menu.Item>
<Menu.Item key="2">Bill</Menu.Item>
<Menu.Item key="3">Alex</Menu.Item>
</SubMenu>
<SubMenu key="sub1" title="Severs">
<Menu.Item key="1">Tom</Menu.Item>
<Menu.Item key="2">Bill</Menu.Item>
<Menu.Item key="3">Alex</Menu.Item>
</SubMenu>
</Menu>
</Sider>
<Layout className="site-layout">
<Header className="site-layout-background" style={{ padding: 0 }} />
<Content style={{ margin: '16px' }}>
<div className="site-layout-background" style={{ padding: 24, minHeight: 360 }}>
Components Demo
</div>
</Content>
<Footer style={{ textAlign: 'center' }}>react-erp ©2021 Created by fssc</Footer>
</Layout>
</Layout>
);
}

touch src/doc/routes.tsx:

1
2
3
import type { RouteObject } from "react-router-dom";
const routes: RouteObject[] = [];
export default routes;

touch src/doc/index.css:

1
2
3
4
5
6
7
8
9
.logo {
height: 32px;
margin: 16px;
background: rgba(255, 255, 255, 0.3);
}

.site-layout .site-layout-background {
background: #fff;
}

文档页面demo雏形:
文档页面demo雏形