第一部分 - 基礎篇:從 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 組件庫!在接下來的章節中,還會和你們討論測試,和打包的話題,敬請期待吧~