第一部分 - 基础篇:从 0 到 1,还原一个后台项目
原文连接javascript
2020年,做为一名普通前端打字员,我平时工做的主要目标仍是使用 React 构建应用程序。去年一直想创建一个属于本身的 NPM 库,用于沉淀本身的业务组件、Hooks
,可是因为不少概念都不是很了解的缘故,又感受这个目标有点高不可攀。css
可是其实只要明白一些原理和细节以后,构建本身的 NPM 库实际上是一件很简单的事情。不只能够拓宽视野,还能够将本身在多个项目中反复使用的某些相同的组件编译到一个组件库中,推广给其余小伙伴使用,贡献开源,岂不美哉。前端
本篇文章,是这个系列的第一篇:基于 React 和 Antd,从 0 到 1,还原一个后台项目java
让咱们看看在 2020 年,一个普通的后台项目,须要的技术栈有哪些:node
具体实现,能够参考这个:Demo 项目react
预览地址:https://jokingzhang.github.io...git
此处首先肯定下,咱们已经安装了 npm
模块,没有安装的童鞋能够去 Node 官网 下载一个安装包安装一下,而后你就有 npm
了😑。es6
执行下面的命令,初始化项目:github
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
这个时候,应该能够看到一个经典的初始化页面了~typescript
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
/* 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 组件库!在接下来的章节中,还会和你们讨论测试,和打包的话题,敬请期待吧~