從 React Native 0.57 版本開始,我們終於可以直接使用 TypeScript 開發,不需要任何額外的配置。本文主要介紹如何使用 TypeScript 優雅地開發 React Native 應用。
初始化專案
初始化專案之前,請確保已經按照 React Native 中文網 的搭建開發環境文件完成了環境搭建
$ react-native init AwesomeProject
複製程式碼
注意: 入口檔案
index.js
需要保留,其他檔案都可以使用.ts
或.tsx
字尾。
TypeScript編譯器
$ yarn global add typescript
$ yarn add -D typescript
複製程式碼
配置 tsconfig.json
$ tsc --init --pretty --target esnext --allowJs --checkJs --jsx react-native --allowSyntheticDefaultImports --experimentalDecorators --emitDecoratorMetadata
複製程式碼
注意:注意多餘的註釋可能會不相容,需要移除,詳細文件可查閱 編譯選項。
配置檔案
tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"allowJs": true,
"checkJs": true,
"jsx": "react-native",
"strict": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
"exclude": ["node_modules"]
}
複製程式碼
解釋:
target
: 指定ECMAScript目標版本 "ES3"(預設),"ES5","ES6"/"ES2015","ES2016","ES2017","ES2018", "ES2019" 或 "ESNext"。mode
: 指定生成哪個模組系統程式碼:"None","CommonJS","AMD","System","UMD","ES6", "ES2015" 或 "ESNext"。allowJs
: 允許編譯javascript檔案。checkJs
: 在.js
檔案中報告錯誤。與--allowJs
配合使用。jsx
: 在 .tsx檔案裡支援JSX: "react"、"react-native"或 "preserve"。檢視 JSX。strict
: 啟用所有嚴格型別檢查選項。啟用--strict
相當於啟用--noImplicitAny
,--noImplicitThis
,--alwaysStrict
,--strictNullChecks
和--strictFunctionTypes
和--strictPropertyInitialization
。allowSyntheticDefaultImports
: 允許從沒有設定預設匯出的模組中預設匯入。這並不影響程式碼的輸出,僅為了型別檢查。esModuleInterop
: TypeScript與Babel採取了不同的方案,並且直到現在,還沒出現真正地固定標準。 簡單地說,如果你使用Babel,Webpack或React Native,並期望與你以往使用地不同的匯入行為,TypeScript提供了該編譯選項。experimentalDecorators
: 啟用實驗性的ES裝飾器。給原始碼裡的裝飾器宣告加上設計型別後設資料。
: 給原始碼裡的裝飾器宣告加上設計型別後設資料。
@types/react、@types/react-native
為了提高開發效率和避免 typescript 型別檢查報錯,你需要新增這兩個型別宣告庫。
$ yarn add @types/react @types/react-native -D
複製程式碼
EsLint 程式碼檢測
Lint工具用於檢查程式碼的語法是否正確、風格是否符合要求。最新的工具ESLint不僅允許你自定義語法規則,還允許使用者創造外掛,改變預設的JavaScript語法,比如支援ES6和JSX的語法。
VsCode 支援
安裝 ESLint Plugin
配置 ESLint Plugin
eslint.validate
:ESLint 外掛預設只校驗 javascript 和 javascriptreact,所以需要手動開啟其他語言的校驗支援eslint.autoFixOnSave
: 開啟儲存時自動修復錯誤
settings.json
{
"eslint.validate": [
"javascript",
"javascriptreact",
{
"language": "typescript",
"autoFix": true
},
{
"language": "typescriptreact",
"autoFix": true
},
{
"language": "vue",
"autoFix": true
},
{
"language": "html",
"autoFix": true
}
],
"eslint.autoFixOnSave": true,
}
複製程式碼
專案配置
注意:配置之前請確保根目錄下存在
.eslintrc.js
。如果要指定忽略某些檔案,可以使用.eslintignore
檔案(node_modules、bower_compnents 資料夾已經預設被忽略)
$ yarn add -D eslint eslint-config-airbnb eslint-plugin-jsx-a11y eslint-plugin-import eslint-plugin-react eslint-plugin-react-native @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-import-resolver-typescript
複製程式碼
- eslint: 可組裝的JavaScript和JSX檢查工具
- eslint-config-airbnb: 該軟體包提供Airbnb的
.eslintrc
作為可擴充套件的共享配置 - eslint-plugin-jsx-a11y: 用於JSX元素的可訪問性規則的靜態AST檢查器。
- eslint-plugin-import: 此外掛旨在支援ES2015 +(ES6 +)匯入/匯出語法的linting。
- eslint-plugin-react: ESLint React 校驗規則外掛
- eslint-plugin-react-native: 針對ESLint的React Native特定linting規則
- @typescript-eslint/parser: 將 TypeScript 轉換為 ESTree,使 eslint 可以識別
- @typescript-eslint/eslint-plugin: 一個包含一堆特定於TypeScript的ESLint規則的外掛
- eslint-import-resolver-typescript: 給 eslint-plugin-import 新增 typescript 支援的外掛
配置檔案
.eslintrc.js
module.exports = {
env: {
es6: true,
node: true,
jest: true,
'react-native/react-native': true,
},
extends: [
'airbnb',
'plugin:react-native/all',
'plugin:@typescript-eslint/recommended',
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
jsx: true,
impliedStrict: true,
},
ecmaVersion: 2018,
project: './tsconfig.json',
sourceType: 'module',
},
plugins: [
'import',
'react',
'react-native'
],
settings: {
'import/resolver': {
typescript: {},
},
},
rules: {
'global-require': 0,
'linebreak-style': [2, 'unix'],
'no-console': [
'error',
{
allow: ['warn', 'error', 'info', 'log'],
},
],
'lines-between-class-members': [
2,
'always',
{
exceptAfterSingleLine: true,
},
],
'no-use-before-define': [
2,
{
functions: true,
classes: true,
variables: false,
},
],
'prefer-destructuring': [
2,
{
array: false,
object: true,
},
],
'react/prefer-stateless-function': 0,
'react/prop-types': 0,
'react/jsx-filename-extension': [
2,
{
extensions: ['.js', '.jsx', '.tsx'],
},
],
'jsx-a11y/accessible-emoji': 0,
'react-native/no-color-literals': 0,
'@typescript-eslint/no-use-before-define': [
2,
{
functions: true,
classes: true,
variables: false,
},
],
'@typescript-eslint/explicit-function-return-type': {
allowExpressions: true,
allowTypedFunctionExpressions: true,
},
},
}
複製程式碼
.eslintignore
# /node_modules/* and /bower_components/* ignored by default
複製程式碼
Prettier 程式碼格式化
ESLint 能夠檢測出程式碼中的潛在問題,提高程式碼質量,但是並不能完全統一程式碼風格。而 Prettier 在格式化程式碼方面具有更大優勢。Prettier 掃描檔案中的樣式問題,並自動重新格式化程式碼,以確保縮排、間距、分號、單引號和雙引號等遵循一致的規則。
VsCode 支援
如果你只是想要格式化你的 JS 或 TS 程式碼,你可以忽略這一部分
安裝 Prettier Plugin
配置 Prettier Plugin
注意:除了以下配置,建議你把其他格式化外掛,比如 beautify 直接解除安裝,並配置 prettier 為預設格式化程式。
prettier.requireConfig
: 需要專案中存在一個 prettierconfig 檔案才能執行prettiereditor.formatOnSave
: 開啟儲存時自動格式化
{
"prettier.requireConfig": true,
"editor.formatOnSave": true,
}
複製程式碼
規則配置
Prettier ❤ ESLint
完成上一部分 VSCode 的支援,再配置一個 PrettierConfig 檔案你就可以使用 Prettier 的功能了。但是當樣式出問題時,編輯器並不會給你報錯。更糟糕的是,ESLint 和 Prettier 在格式化規則方面存在一些衝突。幸運的是,Prettier 被設計為易於與 ESLint 整合,所以你可以輕鬆在專案中使兩者,而無需擔心衝突。
$ yarn add prettier eslint-config-prettier eslint-plugin-prettier -D
複製程式碼
- prettier: 主 prettier 庫
- eslint-config-prettier: 關閉所有不必要或可能與 prettier 的規則衝突的ESLint規則。
- eslint-plugin-prettier: 以 ESLint 外掛的形式執行 prettier
配置檔案
.eslintrc.js
module.exports = {
extends: [
'prettier',
'plugin:prettier/recommended',
'prettier/react',
'prettier/@typescript-eslint',
],
}
複製程式碼
.eslintignore
# /node_modules/* and /bower_components/* ignored by default
複製程式碼
.prettierrc.js
module.exports = {
semi: false, // 行位是否使用分號,預設為true
trailingComma: 'es5', // 是否使用尾逗號,有三個可選值"<none|es5|all>"
singleQuote: true, // 字串是否使用單引號,預設為false,使用雙引號
printWidth: 120, // 一行的字元數,如果超過會進行換行,預設為80
tabWidth: 2, // 一個tab代表幾個空格數
bracketSpacing: true, // 物件大括號直接是否有空格,預設為true,效果:{ foo: bar }
}
複製程式碼
.prettierinore
**/node_modules/*
src/**/*.js
src/**/*.jsx
src/**/*.ts
src/**/*.tsx
複製程式碼
EditorConfig 跨編輯器配置統一
當多人共同開發一個專案的時候,往往會出現大家用不同編輯器的情況。就前端開發者來說,有人喜歡 Sublime,有人喜歡 Webstorm , 也有人喜歡 Atom,還有人喜歡 Vim,HBuilder 等等。各種不同程式語言的開發者喜歡各種不同的編輯器。EditorConfig 這個專案就是為了解決跨編輯器開發專案的程式碼風格統一問題的。
VSCode Plugin
安裝
安裝完後不需要配置,直接在專案中新增配置檔案即可。
配置檔案
.editorconfig
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[*.gradle]
indent_size = 4
[BUCK]
indent_size = 4
複製程式碼
Git pre-commit Hook
pre-commit
鉤子在鍵入提交資訊前執行。 它用於檢查即將提交的快照,例如,檢查是否有所遺漏,確保測試執行,以及核查程式碼。 如果該鉤子以非零值退出,Git 將放棄此次提交,不過你可以用git commit --no-verify
來繞過這個環節。 你可以利用該鉤子,來檢查程式碼風格是否一致(執行類似 lint 的程式)、尾隨空白字元是否存在(自帶的鉤子就是這麼做的),或新方法的文件是否適當。
husky: 輕鬆使用 Git hooks
Husky 能阻止壞的
git commit
,git push
和更多的?
$ yarn add -D husky
複製程式碼
配置檔案
.huskyrc.js
module.exports = {
hooks: {
'pre-commit': 'node node_modules/eslint/bin/eslint.js --fix src/**/*.js',
},
}
複製程式碼
注意:測試發現直接執行
eslint --fix
使用的是全域性的模組。
只使用 husky 的問題
- 效能問題:對整個專案執行一個lint程式很慢,而且linting結果可能無關緊要。
- 效率問題:遺留程式碼倉庫上工作的同學很快會遇到新的問題,開啟 Lint 初期,你可能會面臨成千上萬的 Lint Error 需要修復。部分同學對下面這個圖可能並不陌生:只改了檔案 A,但是檔案 B、C、D 中也有大量錯誤。
lint-staged: husky的好幫手
針對暫存的git檔案執行linters並且不要讓?滑入你的程式碼庫!對暫存區概念不熟悉的同學可以看下git-簡明指南
$ yarn add -D husky lint-staged
複製程式碼
- husky: 被用來新增一些 git 鉤子,這裡我們需要一個用
pre-commit
在每次git commit
操作時執行lint-staged
命令。 - lint-staged: 可以對 git 暫存區檔案(也就是你想要 commit 的檔案)執行一些操作,這樣做即提高了效能又提高了效率。
配置檔案
.huskyrc.js
module.exports = {
hooks: {
'pre-commit': 'lint-staged',
},
}
複製程式碼
lint-staged.config.js
module.exports = {
"src/**/*.{js,jsx,ts,tsx}": ["eslint --fix", "git add"]
}
複製程式碼
相對於根目錄引入元件
這部分不是必須的,配置也有些繁瑣。這裡我就只介紹下簡單的配置,詳細文件請請查閱 babel-plugin-root-import。
安裝
$ yarn add -D babel-plugin-root-import eslint-import-resolver-babel-plugin-root-import
複製程式碼
babel.config.js
module.exports = {
...
plugins: [
[
'babel-plugin-root-import',
{
rootPathSuffix: 'src',
rootPathPrefix: '~',
},
],
],
...
}
複製程式碼
.eslintrc.js
{
settings: {
'import/resolver': {
'babel-plugin-root-import': {
rootPathSuffix: 'src',
rootPathPrefix: '~',
},
},
},
}
複製程式碼
tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~/*": ["src/*"]
}
}
}
複製程式碼
支援 .jsx
React Native 都已經內建支援 TypeScript 了,但是卻不支援 .jsx
檔案字尾。如果你想要使用 .jsx
開發,可以配置 metro.config.js
:
module.exports = {
resolver: {
sourceExts: ['ts', 'tsx', 'js', 'jsx', 'json', 'mjs']
},
}
複製程式碼
相關資料
- Using ESLint and Prettier in a TypeScript Project: TypeScript、ESLint、Prettier、VSCode
- 使用 ESLint + Prettier 簡化程式碼 Review 過程: Zeit Now、DevOps
- 用Prettier和ESlint來統一提交程式碼: ESLint、Prettier、husky、lint-staged
- 用 ESLint 和 Prettier 寫出高質量程式碼:ESLint、Prettier、husky、lint-staged
- 使用ESLint+Prettier來統一前端程式碼風格:ESLint、Prettier
- 使用ESLint & Prettier美化Vue程式碼:Vue、ESLint、Prettier、husky、lint-staged、填坑
- 用 husky 和 lint-staged 構建超溜的程式碼檢查工作流: husky、lint-staged