第一部分 - 基础篇:从 0 到 1,还原一个后台项目javascript
原文连接css
2020年,做为一名普通前端打字员,我平时工做的主要目标仍是使用 React 构建应用程序。去年一直想创建一个属于本身的 NPM 库,用于沉淀本身的业务组件、Hooks
,可是因为不少概念都不是很了解的缘故,又感受这个目标有点高不可攀。前端
可是其实只要明白一些原理和细节以后,构建本身的 NPM 库实际上是一件很简单的事情。不只能够拓宽视野,还能够将本身在多个项目中反复使用的某些相同的组件编译到一个组件库中,推广给其余小伙伴使用,贡献开源,岂不美哉。java
本篇文章,是这个系列的第一篇:基于 React 和 Antd,从 0 到 1,还原一个后台项目node
让咱们看看在 2020 年,一个普通的后台项目,须要的技术栈有哪些:react
具体实现,能够参考这个:Demo 项目git
预览地址:jokingzhang.github.io/dantd-demo/es6
此处首先肯定下,咱们已经安装了 npm
模块,没有安装的童鞋能够去 Node 官网 下载一个安装包安装一下,而后你就有 npm
了😑。github
执行下面的命令,初始化项目:typescript
sudo npm i -g npx
npx create-react-app my-app --template typescript
cd my-app
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
npm start
复制代码
这个时候,应该能够看到一个经典的初始化页面了~
npm install antd --save
复制代码
npm install --save react-router-dom @types/react-router-dom
复制代码
npm install -D eslint eslint-config-prettier eslint-config-react-app eslint-plugin-flowtype eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-prettier eslint-plugin-react eslint-plugin-react-hooks lint-staged prettier husky
复制代码
依赖安装好以后,就能够为项目增长一些配置文件了
tsconfig.json
文件中指定了用来编译这个项目的根文件和编译选项。这是当前项目所用到的配置文件:
{
"compilerOptions": {
"target": "es5",
"lib": [
"es6",
"dom"
],
"downlevelIteration": true,
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
"sourceMap": true,
"baseUrl": "./src",
"allowSyntheticDefaultImports": true,
"moduleResolution": "node"
},
"exclude": [
"node_modules"
],
"include": [
"src"
]
}
复制代码
.eslintrc
文件中,容许你指定你想要支持的 JavaScript 语言选项。这是当前项目所用到的配置文件:
{
"extends": "react-app",
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": ["error", {
"vars": "all",
"args": "after-used",
"ignoreRestSiblings": false
}]
}
}
复制代码
你能够经过在项目根目录建立一个 .eslintignore
文件告诉 ESLint 去忽略特定的文件和目录。.eslintignore
文件是一个纯文本文件,其中的每一行都是一个 glob 模式代表哪些路径应该忽略检测。
node_modules/*
复制代码
prettierrc
的配置文件,打造适合大家团队的代码配置
module.exports = {
singleQuote: true,
trailingComma: 'all',
printWidth: 100,
proseWrap: 'never',
overrides: [
{
files: '.prettierrc',
options: {
parser: 'json',
},
},
],
};
复制代码
若是你是使用 Visual Studio Code 来开发项目的话,这个配置文件就能够方便的统一团队的编辑器配置,解决项目中,缩进是「2个空格」仍是「4个空格」的问题。
{
"editor.tabSize": 2,
"eslint.autoFixOnSave": true,
"eslint.validate": [
"javascript",
"javascriptreact",
{ "language": "typescript", "autoFix": true },
{ "language": "typescriptreact", "autoFix": true }
],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}
复制代码
当咱们搜索 create-react-app 是如何快速解决 alias 的问题时,Dan 给出的答案是添加 .env
这个文件:
NODE_PATH=src
复制代码
到这里,就整理完了全部须要的配置文件
更加详细的解析,请参考 Antd 的文档
安装下面依赖:
npm i -D react-app-rewired customize-cra babel-plugin-import less less-loader
复制代码
/* package.json */
"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
}
复制代码
而后在项目根目录建立一个 config-overrides.js
用于修改默认配置。
const { override, fixBabelImports, addLessLoader } = require('customize-cra');
module.exports = override(
fixBabelImports('import', {
libraryName: 'antd',
libraryDirectory: 'es',
style: true,
}),
addLessLoader({
javascriptEnabled: true,
}),
);
复制代码
到此,咱们就能够在项目中,愉快的使用 less
了~
此时,使用编辑器打开项目,咱们能够看到以下的 src
目录结构:
├── src
| ├── App.css
| ├── App.test.tsx
| ├── App.tsx
| ├── index.css
| ├── index.tsx
| ├── logo.svg
| ├── react-app-env.d.ts
| ├── serviceWorker.ts
| └── setupTests.ts
复制代码
这是脚手架为咱们准备的初始目录结构。接下来,咱们须要在这个基础上,进行一些改造。以一个最为简单的 EmptyLine
组件为例子,看看咱们须要增长哪些文件。
首先,增长两个文件夹 , pages
用来存放路由相关的组件,以及components
用来存放通用组件。
此处不作赘述,感兴趣的小伙伴能够看下 demo 的实现 。
此时,代码结构以下:
├── src
| ├── App.less
| ├── App.test.tsx
| ├── App.tsx
| ├── components
| | ├── empty-line
| | | ├── EmptyLine.tsx
| | | ├── demo.tsx
| | | ├── index.tsx
| | | └── style
| | └── index.tsx
| ├── config.tsx
| ├── index.css
| ├── index.tsx
| ├── logo.svg
| ├── pages
| | ├── Component
| | | ├── index.tsx
| | | └── style.less
| | ├── Home
| | | ├── index.tsx
| | | └── style.less
| | └── NotFound
| | └── index.tsx
| ├── react-app-env.d.ts
| ├── serviceWorker.ts
| └── setupTests.ts
复制代码
pages
下面的目录结构比较容易理解,只存放了组件,以及样式文件。
components
下的目录结构,主要参考了 Antd
的源码实现。这样写的有以下好处:
babel-plugin-import
来进行按需加载 Antd
,当咱们想使用 ES module
的方式引入组件的时候,它会对咱们 es
目录下的文件有所要求:下面摘自 babel-plugin-import 的文档:
import { Button } from 'antd';
ReactDOM.render(<Button>xxxx</Button>);
↓ ↓ ↓ ↓ ↓ ↓
var _button = require('antd/lib/button');
ReactDOM.render(<_button>xxxx</_button>);
复制代码
import { Button } from 'antd';
ReactDOM.render(<Button>xxxx</Button>);
↓ ↓ ↓ ↓ ↓ ↓
var _button = require('antd/lib/button');
require('antd/lib/button/style/css');
ReactDOM.render(<_button>xxxx</_button>);
复制代码
import { Button } from 'antd';
ReactDOM.render(<Button>xxxx</Button>);
↓ ↓ ↓ ↓ ↓ ↓
var _button = require('antd/lib/button');
require('antd/lib/button/style');
ReactDOM.render(<_button>xxxx</_button>);
复制代码
因此,不论以后时使用 commonjs
的方式打包,仍是使用 es
的方式打包,组件的目录结构最好和 Antd
的组件目录结构保持一致,不然 babel-plugin-import
这个插件会找不到对应的文件所在。
如今,咱们能够开始写咱们的第一个组件了,<EmptyLine />
:产生一个空行,而且能够根据 props
改变高度。
export { default as EmptyLine } from './empty-line';
复制代码
import './style/index.less';
import EmptyLine from './EmptyLine';
export default EmptyLine;
复制代码
import React from 'react';
import './style/index.less';
export interface IEmptyLineProps {
height?: number;
}
const EmptyLine = ({ height = 20 }: IEmptyLineProps) => {
return <div className="empty-line" style={{ height }} />;
};
export default EmptyLine;
复制代码
.empty-line {
width: 100%;
height: 20px;
}
复制代码
import React from 'react';
import EmptyLine from './EmptyLine';
const demo = () => {
return (
<div>
<h3>组件名称:空行(EmptyLine)</h3>
<p>自定义组件,默认高度 20 ,宽度 100%</p>
<p>第一行文字</p>
<EmptyLine />
<p>第二行文字</p>
</div>
);
};
export default demo;
复制代码
到这里,组件就完成了,这是:预览地址
咱们已经从头开始建立了 React 组件库!在接下来的章节中,还会和你们讨论测试,和打包的话题,敬请期待吧~