Ã¥ÂÂè¨Â
对äºÂÃ¥ÂÂå¼Âå§Âæ¥触并使ç¨create-react-app
èÂÂæÂÂæ¶åÂÂ建ä¸Â个reactÃ¥ÂÂ端工ç¨Âï¼ÂæÂÂ们è¯å®Â好å¥Âè¿Â个工ç¨ÂéÂÂé¢é½éÂÂæÂÂäºÂåªäºÂÃ¥ÂÂè½ï¼ÂÃ¥ÂÂ个工åÂ
·ä¹Âé´æ¯æÂÂä¹ÂÃ¥ÂÂä½Âè¿Âç¨çÂÂï¼Âæ¯Âä¸Â个工åÂ
·çÂÂ主è¦Âä½Âç¨æ¯ä»Âä¹Âï¼ÂèÂÂÃ¥ÂÂtypescriptãÂÂeslintãÂÂbabelãÂÂprettierè¿ÂäºÂå·¥åÂ
·åÂÂé½æÂÂä¾ÂäºÂç¸åÂ
³çÂÂæÂÂ件(plugin),è¿ÂäºÂpluginÃ¥ÂÂæÂÂä»Âä¹Âç¨éÂÂï¼ÂÃ¥ÂÂå¦Âè¦ÂæÂÂ们èª己ä»Â0æÂÂ建ä¸Â个reactå¼ÂÃ¥ÂÂæ¡Âæ¶ï¼ÂÃ¥ÂÂ该å¦Âä½Âå¼Âå§Âï¼ÂæÂ¥ä¸ÂæÂ¥è¿Âç¯ÂæÂÂç« ï¼Âå°Âä¸ÂæÂ¥ä¸ÂæÂ¥åºäºÂwebpack5ï¼Â带é¢Â大家ä¸Âèµ·çÂÂæ¯å¦Âä½Âå°Âè¿ÂäºÂå·¥åÂ
·éÂÂæÂÂå¨ä¸Â起使ç¨ãÂÂ
Ã¥ÂÂå§ÂÃ¥ÂÂå·¥ç¨Â
-
Ã¥ÂÂ建工ç¨Âç®å½Âï¼Âmkdir webpack5-react
-
Ã¥ÂÂå§ÂÃ¥ÂÂ项ç®ï¼Ânpm init
webpackåºæ¬é Âç½®
å¨ä¸Âé¢æÂÂ们已ç»ÂÃ¥ÂÂå§ÂÃ¥ÂÂäºÂä¸Â个空çÂÂ项ç®ï¼Âè¿ÂéÂÂæÂÂ们é¦Âå Âå®Â裠é Âç½®webpackãÂÂ
-
é¦Âå Âå®Â裠webpackç¸堳å ï¼Â
yarn add webpack webpack-cli webpack-dev-server webpack-merge --dev
说æÂÂä¸Âå 个å çÂÂÃ¥ÂÂè½ï¼Â
- webpack: webpackçÂÂæ ¸å¿ÂÃ¥ÂÂ
- webpack-cli: ä»Âwebpack4ä¹ÂÃ¥ÂÂçÂÂçÂÂæ¬ä¸Âï¼Âwebpack-cliÃ¥ÂÂwebpacké½å¨ä¸Â个å éÂÂï¼Âä»Âwebpack4å¼Âå§Â被åÂÂç¬ä½Â为ä¸Â个å ï¼Âç¨æÂ¥å¨å½令è¡Âä¸Âè¿Âè¡ÂwebpackçÂÂ工堷ãÂÂ
- webpack-dev-server: å¨å¼ÂÃ¥ÂÂç¯å¢Â帮æÂÂ们å¼Âå¯ä¸Â个æΡå¼ÂÃ¥ÂÂæÂÂå¡ãÂÂ
- webpack-merge: Ã¥ÂÂ并webpackçÂÂé Âç½®ï¼Â帮å©åºåÂÂå¼ÂÃ¥ÂÂç¯å¢ÂÃ¥ÂÂçÂÂ产ç¯å¢Âä¸ÂÃ¥ÂÂçÂÂé Âç½®ãÂÂ
-
æ ¹ç®å½Âæ·»å æÂÂ件
- index.html
<!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><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="root"></div>
</body>
</html>
- index.js: å ¥å£æÂÂ件
function add(num1, num2){
return num1 + num2
}
- webpack.config.js: webpack堬報é Âç½®æÂÂ件
const path = require('path');
console.log(path.resolve(__dirname, 'dist'));
module.exports = {
entry: './src/index.js',
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist'),
clean: true
},
optimization: {
// Ã¥ÂÂ纯添å æ°æÂÂ件æÂÂèÂÂ
ä¾ÂèµÂï¼Âä¸Â对å«çÂÂbundleçÂÂcontenthash产çÂÂå½±åÂÂãÂÂ
moduleIds: 'deterministic',
// å° runtime 代ç ÂæÂÂÃ¥ÂÂ为ä¸Â个åÂÂ獠chunk,distç®å½Âå°Âä¼Âå¤Âåºä¸Â个runtimeæÂÂ件
runtimeChunk: 'single',
// tree shaking
usedExports: true,
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
},
module: {
rules: []
},
plugins: []
};
- webpack.dev.js: å¼ÂÃ¥ÂÂç¯å¢Âé Âç½®
const {merge} = require('webpack-merge');
const commonConfig = require('./webpack.config.js');
module.exports = merge(commonConfig, {
// 模å¼Â
mode: 'development',
// å¯ç¨sourcemap
devtool: 'inline-source-map',
// dev-server
devServer: {
static: './dist',
// HMR
hot: true
},
})
- webpack.prod.jsï¼ÂçÂÂ产ç¯å¢Âé Âç½®
const {merge} = require('webpack-merge');
const commonConfig = require('./webpack.config.js');
module.exports = merge(commonConfig, {
mode: 'production',
})
-
æ·»å webpackæÂÂ件html-webpack-plugin
å¨ä¸Âé¢æÂÂ们已ç»Âå¨根ç®å½Âæ·»å äºÂindex.htmlï¼ÂæÂÂ们å®Â裠html-webpack-pluginï¼Âå¨æ§è¡Âwebpack大å çÂÂè¿Âç¨Âä¸Âå°±å¯以ä¾Âæ®index.html为模çÂÂï¼Âè¾Âåºhtml模çÂÂæÂÂ件并èªå¨å¼Â堥大å è¿Âç¨Âä¸Âè¾ÂåºçÂÂèµÂæºÂæÂÂ件å¦ÂscriptãÂÂlinkçÂÂãÂÂ
yarn add html-webpack-plugin --dev
ç¶åÂÂå¨webpack.config.jsæÂÂ件添å é Âç½®
const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new HtmlWebpackPlugin({
title: 'webpack for react',
template: './index.html'
})
]
-
å¾çÂÂãÂÂÃ¥ÂÂä½ÂçÂÂèµÂæºÂæÂÂ件å¤ÂçÂÂ
webpack5å 置äºÂAsset Modulesï¼ÂæÂÂ们åªéÂÂè¦Âæ·»å 对åºÂé Âç½®
å¨webpack.config.jsçÂÂmoduleçÂÂrulesæ·»å å¦Âä¸Âé Âç½®ï¼Â
rules: [
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
include: path.resolve(__dirname, 'src'),
type: 'asset/resource'
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
include: path.resolve(__dirname, 'src'),
type: 'asset/resource'
}
]
-
cssãÂÂlessãÂÂscssãÂÂsassæ¯æÂÂ
webpacké»Â认åªæ¯æÂÂ对jsæÂÂ件çÂÂå¤ÂçÂÂï¼ÂæÂÂ以æÂÂ们对äºÂä¸ÂÃ¥ÂÂçÂÂæÂÂ件éÂÂè¦Â对åºÂçÂÂloaderæ¯æÂÂå¤ÂçÂÂ
å®Â裠ï¼Â
yarn add style-loader css-loader less less-loader sass sass-loader --dev
Ã¥ÂÂ个å çÂÂä½Âç¨说æÂÂï¼Â
- style-loaderï¼ÂéÂÂè¿ÂjsèÂÂæÂŒÂÂ建ä¸Â个styleæ Âç¾å°Âæ ·å¼Âæ·»å å°htmlä¹Âä¸ÂãÂÂ
- css-loader: æ¯æÂÂwebpackå¤ÂçÂÂcssæÂÂ件ãÂÂ
- less:lessçÂÂ解æÂÂæ ¸å¿Âå ãÂÂ
- less-loader: æ¯æÂÂwebapckå¤ÂçÂÂlessæÂÂ件
- sass: sassçÂÂ解æÂÂæ ¸å¿Âå ï¼Âä¹ÂÃ¥ÂÂéÂÂè¦Âå®Â裠node-sassï¼Âç°å¨é»Â认å®Â裠dart-sassãÂÂ
- sass-loader: æ¯æÂÂwebpackå¤ÂçÂÂscss\sassæÂÂ件
ç¶åÂÂå¨webpack.config.jsæ·»å 对åºÂé Âç½®ï¼Â
rules: [
{
test: /\.css$/i,
include: path.resolve(__dirname, 'src'),
use: ['style-loader', 'css-loader']
},
{
test: /\.less$/i,
use: ['style-loader', 'css-loader', 'less-loader']
},
{
test: /\.s[ac]ss$/i,
use: ['style-loader', 'css-loader', 'sass-loader']
},
]
-
æ·»å babelæ¯æÂÂes6+è¯Âæ³Âï¼Âjsxæ¯æÂÂ
babelçÂÂ主è¦Âä½Âç¨å¯以æ¦Âæ¬为ä¸Â个ï¼Â
- ç¼Âè¯Âes6è¯Âæ³Â
- å®Âç°æ§çÂÂæ¬æµÂè§Âå¨ä¸Âæ¯æÂÂçÂÂapi
- æ¯æÂÂjsx
å®Â裠ï¼Â
yarn add babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime
å 说æÂÂï¼Â
- @babel/core: babel æ ¸å¿ÂÃ¥ÂÂ
- @babel/preset-env: å®Âæ¹æÂÂä¾ÂçÂÂä¸Â个æºè½é¢Â设ï¼Âå®ÂÃ¥Â
Â许å¼ÂÃ¥ÂÂèÂÂ
使ç¨
æÂÂæ°
ç javascript,å¿æ éÂÂ管çÂÂç®æ Âç¯å¢ÂéÂÂè¦ÂåªäºÂè¯Âæ³Â转æ¢ã - babel-loader: å Â许 webpack 使ç¨ babel 转移 javascript æÂÂ件
- @babel/plugin-transform-runtime:
è¿Â个åÂÂ
éÂÂè¦ÂçÂÂ解ä¸Âï¼Âå¨使ç¨@babel/preset-env Ã¥ÂÂè¯Âæ³Â转æ¢æ¶åÂÂï¼Âbabel å¨转æ¢åÂÂçÂÂ代ç ÂéÂÂé¢注åÂ
¥è¾Â
å©å½æ°
ï¼Â以便è¯Âæ³Â转æ¢æ¶åÂÂ使ç¨ãÂÂ@babel/runtime è¿Â个åÂÂ
æÂÂä¾Â亠babel æÂÂæÂÂçÂÂè¯Âæ³Â转æ¢çÂÂè¾Â
å©å½æ°åÂÂ
ãÂÂèÂÂ@babel/plugin-transform-runtime Ã¥Â
¶ä¸Âä¹Âä¸ÂÃ¥ÂÂè½就æ¯èªå¨å¼ÂÃ¥Â
¥éÂÂè¦Âç¨å°çÂÂè¾Â
å©å½æ°åÂÂ
ãÂÂ
- èªå¨移é¤è¯Âæ³Â转æ¢åÂÂå èÂÂçÂÂè¾ å©å½æ°
- å½Â代ç ÂéÂÂ使ç¨亠core-js ç APIï¼Âèªå¨å¼Âå ¥@babel/runtime-corejs3/core-js-stable/ï¼Â以æ¤æÂ¥æ¿代堨å±Âå¼Âå ¥ç core-js/stable;
- å½Â代ç ÂéÂÂ使ç¨亠Generator/async å½æ°ï¼Âèªå¨å¼Âå ¥@babel/runtime/regeneratorï¼Â以æ¤æÂ¥æ¿代堨å±Âå¼Âå ¥ç regenerator-runtime/runtimeï¼Â
è¿ÂéÂÂÃ¥ÂÂéÂÂç¹说æÂÂä¸Â@babel/preset-envè¿Â个å ï¼Â对äºÂè¿Â个å çÂÂçÂÂ解ï¼Âå¯以åÂÂ为两个é¨åÂÂï¼Â
- preset,é¢Â设ï¼Âbabel ç¼Âè¯Â亠es6+çÂÂè¯Âæ³Âå apiï¼Âæ¯éÂÂè¿Âä¸Â个个æÂÂ件 plugin å»å®Âç°çÂÂãÂÂç¶èÂÂæ¯Âå¹´é½ä¼ÂæÂÂæ°çÂÂæÂÂæ¡ÂãÂÂæ°çÂÂè¯Âæ³ÂãÂÂæ°ç apiï¼Âä½Âæ¯æÂÂ们ä¸Âå¯è½ä¸Â个ä¸Â个æÂÂ件åÂȎÂ
Âç½®ï¼ÂæÂÂ以就æÂÂ亠preset-env è¿Â个åÂÂ
ï¼ÂæÂÂ们å¯以æÂÂå®ÂçÂÂ解为ä¸Â个
è¯Âæ³ÂæÂÂ件éÂÂÃ¥ÂÂÃ¥ÂÂ
ï¼Âè¿Âæ ·æÂÂ们åªéÂÂè¦Âå®Â裠è¿Âä¸Â个å ï¼Âå°±ä¸ÂéÂÂè¦Âä¸Â个ä¸Â个æÂÂ件é Âç½®ï¼Âæ¹便çÂÂ使ç¨åÂÂç¼Âè¯ÂæÂÂæ°çÂÂè¯Âæ³ÂäºÂã - env,æÂÂçÂÂæ¯ç¯å¢Âï¼ÂæÂÂ们å¯以éÂÂè¿Âå®Âé Âç½®æÂÂ们代ç Âè¿Âè¡ÂçÂÂç®æ Âç¯å¢Âï¼Âå®ÂæÂ¥æ§å¶åªäºÂè¯Âæ³ÂéÂÂ覠polyfillãÂÂå®ÂåªæÂÂä¾Âç¼Â诠es6+è¯Âæ³Âï¼Â并ä¸Âå å«æ°ç es6+API.
webpackæ·»å bebelé Âç½®ï¼Â
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
æ ¹ç®å½ÂÃ¥ÂÂ建babel.config.json
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage",
"corejs": "3.30.2"
}
]
],
"plugins": [
[
"@babel/plugin-transform-runtime"
]
]
}
-
reacté Âç½®
å¨æÂÂäºÂÃ¥ÂÂé¢çÂÂåºç¡Âé Âç½®ï¼ÂæÂÂ们å¯以å®Â裠reactæÂ¥å®ÂæÂÂ对reactçÂÂæ¯æÂÂãÂÂ
yarn add react react-dom @babel/preset-react
å 说æÂÂï¼Â
- react,react-dom:reactå®Âæ¹核å¿ÂÃ¥ÂÂ
- @babel/preset-reactï¼ÂbabelçÂÂreacté¢Â设ï¼Â使babelè½å¤Âæ¯æÂÂå¤ÂçÂÂreactçÂÂjsxè¯Âæ³Â
ç¶åÂÂæÂÂ们è¿ÂéÂÂè¦Âå¨babel.config.jsonæÂÂ件添å reacté¢Â设
[
"@babel/preset-react",
{
// æ°çÂÂçÂÂjsx转æ¢ï¼Âä¸ÂéÂÂè¦Â强å¶å¼ÂÃ¥Â
Â¥react
"runtime": "automatic"
}
],
æ·»å typescriptæ¯æÂÂ
è¿ÂéÂÂéÂÂè¦ÂæÂÂÃ¥ÂÂ说æÂÂï¼Âç°å¨æÂÂ们添å typescriptéÂÂè¦Âå½±åÂÂå°çÂÂæÂÂï¼Â
- webpack: 使å¾Âwebpackè½å¤Âæ¯æÂÂts,tsxæÂÂ件
- babel: 使å¾Âbabelè½å¤Â解æÂÂtsè¯Âæ³Â
å®Â裠ï¼Â
yarn add typescript ts-loader --dev
yarn add @types/react @types/react-dom @babel/preset-typescript
å 说æÂÂï¼Â
-
typescript: typescriptæ ¸å¿ÂÃ¥ÂÂ
-
ts-loader: webpackçÂÂloader,è½å¤Âå¤ÂçÂÂtsæÂÂ件
-
@types/react@types/react-domï¼ÂreactÃ¥ÂÂreact-domçÂÂç±»åÂÂæÂÂ件åÂÂ
-
@babel/preset-typescriptï¼Â使å¾Âbabelè½å¤Â解æÂÂts tsx
-
æ ¹ç®å½ÂÃ¥ÂÂ建tsconfig.json
{
"compilerOptions": {
"outDir": "./dist/",
"rootDir": "./",
"module": "es6",
"target": "es5",
"strict": true,
"alwaysStrict": true,
"importHelpers": true,
"moduleResolution": "node",
"esModuleInterop": true,
"declaration": true,
"jsx": "react-jsx",
"allowJs": false,
"checkJs": false,
"sourceMap": true,
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
]
},
"allowUnreachableCode": true,
"noImplicitAny": true,
"noImplicitThis": false,
"noUnusedLocals": true,
"noImplicitReturns": false,
"noImplicitOverride": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
-
webpackæ·»å 对åºÂloaderé Âç½®
{
test: /\.(jsx?)|(tsx?)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/
},
-
babel.config.jsonæ·»å é Âç½®
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage",
"corejs": "3.30.2"
}
],
[
"@babel/preset-react",
{
"runtime": "automatic"
}
],
// typescript
["@babel/preset-typescript"]
],
"plugins": [
[
"@babel/plugin-transform-runtime"
]
]
}
æ·»å editorconfig
为ä»Âä¹Âè¦Âæ·»å editorconfig?
å¨ä¸Â个å¢éÂÂå¼ÂÃ¥ÂÂ项ç®ä¸Âï¼Âä¸Âè½ä¿Âè¯Âå¢éÂÂä¸ÂæÂÂÃ¥ÂÂå ¨é¨éÂÂç¨ç¸åÂÂç¼Âè¾Âå¨ï¼Âè¿Âå°±ä¼Âé æÂÂ项ç®代ç Âæ ¼å¼Âæ æ³Âç»Âä¸Âé®é¢ÂãÂÂä¸ÂÃ¥ÂÂçÂÂç¼Âè¾Âå¨ä¹Âé´çÂÂæ ¼å¼Âå¯è½ä¸ÂÃ¥ÂÂãÂÂ缩è¿Âå¯è½ä¸ÂÃ¥ÂÂãÂÂé£ä¹Âå¦Âä½Âä¿Âè¯Âå¢éÂÂæÂÂÃ¥ÂÂçÂÂ代ç Âå¤Â人å¼ÂÃ¥ÂÂé£Âæ ¼ç»Âä¸Âå¢ï¼Â
editorconfig å®Âæ¹ï¼ÂEditorConfig 帮å©å¼ÂÃ¥ÂÂ人åÂÂå¨ä¸ÂÃ¥ÂÂçÂÂç¼Âè¾Âå¨å IDE ä¹Âé´å®Âä¹ÂÃ¥ÂÂç»´æ¤ä¸Âè´çÂÂç¼Âç Âæ ·å¼ÂãÂÂ
项ç®根ç®å½ÂÃ¥ÂÂ建æÂÂ件:.editorconfigæÂÂ件
root = true
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
[*.{js,css,html,vue,tsx,less,scss}]
charset = utf-8
indent_style = space
indent_size = 2
注æÂÂ
ï¼Âvscode é»Â认ä¸Âæ¯æ editorconfig,éÂÂè¦Âèªè¡Âå®Âè£Â
æÂÂ件
æ·»å prettier
prettieræ¯ä¸Â个ç»Âä¸Â代ç Âé£Âæ ¼çÂÂæ ¼å¼ÂÃ¥ÂÂ工堷ãÂÂ
å®Â裠ï¼Â
yarn add prettier --dev
æ ¹ç®å½Âæ°建æÂÂ件ï¼Â.prettierrc.js
module.exports = {
// è¡Âå°¾éÂÂè¦ÂæÂÂÃ¥ÂÂå·
semi: true,
// æ«尾ä¸ÂéÂÂè¦ÂéÂÂå·
trailingComma: 'none',
// 使ç¨åÂÂå¼Âå·
singleQuote: true,
// ä¸Âè¡ÂæÂÂ夠160 Ã¥ÂÂ符
printWidth: 160,
// ä¸Â使ç¨缩è¿Â符ï¼ÂèÂÂ使ç¨空格
useTabs: false,
// 使ç¨ 2 个空格缩è¿Â
tabWidth: 2,
// 大挷åÂÂ
çÂÂé¦Âå°¾éÂÂè¦Â空格
bracketSpacing: true,
// ç®Â头å½æ°ï¼ÂåªæÂÂä¸Â个åÂÂæ°çÂÂæ¶åÂÂï¼Âä¸ÂéÂÂè¦Â挷
arrowParens: 'always', // always
// 使ç¨é»Â认çÂÂæÂÂè¡Âæ ÂÃ¥ÂÂ
proseWrap: 'preserve',
// æ ¹æ®æ¾示样å¼Âå³宠html è¦Âä¸Âè¦ÂæÂÂè¡Â
htmlWhitespaceSensitivity: 'ignore',
// æ¢è¡Â符使ç¨ lf crlf auto
endOfLine: 'lf'
};
ç°å¨æÂÂäºÂprettierï¼ÂæÂÂ们å¸ÂæÂÂå¯以å¨ä¿ÂÃ¥ÂÂçÂÂæ¶åÂÂèªå¨格å¼ÂÃ¥ÂÂæÂÂ们çÂÂ代ç ÂãÂÂ以vscode为ä¾Âï¼ÂæÂÂ们å¯以å¨项ç®根ç®å½Âæ·»å .vscodeç®å½Âï¼Â并æ°建settings.json
{
// ä¿ÂÃ¥ÂÂèªå¨格å¼ÂÃ¥ÂÂ
"editor.formatOnSave": true
}
æ·»å eslint
eslintæ¯ä¸Â个æÂÂ件åÂÂçÂÂjavascriptçÂÂ代ç Âæ£Âæ¥工堷ãÂÂå¯以帮å©å¼ÂÃ¥ÂÂè é¿å ÂÃ¥ÂÂä¿®å¤Â代ç Âä¸Âæ½Âå¨çÂÂé®é¢ÂãÂÂ
å®Â裠ï¼Â
yarn add eslint eslint-webpack-plugin @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-prettier eslint-plugin-react --dev
å 说æÂÂï¼Â
- eslint: eslint æ ¸å¿ÂÃ¥ÂÂ
- eslint-webpack-plugin: webpack5 å·²ç»Âå¼Âç¨ eslint-loaderï¼ÂèÂÂæ¯éÂÂç¨æÂÂ件 eslint-webpack-ppluginï¼Âå¯以å¨æÂÂ建è¿Âç¨Âä¸Âæ§è¡Âeslint
- @typescript-eslint/parser:ä¸Â个 eslint 解æÂÂå¨ï¼Â使 eslint å¯以解æ typescript,eslint é»Â认解æÂÂå¨åªè½解æ js
- @typescript-eslint/eslint-plugin: typescript è¯Âæ³ÂçÂÂé»Â认æ¨èÂÂ
- eslint-config-prettier: å¤Âç eslint çÂÂä¸ÂäºÂæ£Âæ¥丠prettier å²çªÂï¼ÂéÂÂç¨ prettierãÂÂ
- eslint-plugin-react: 让eslintæ£ÂæÂÂ¥reactè¯Âæ³ÂãÂÂ
项ç®根ç®å½Âæ·»å æÂÂ件ï¼Â.eslintrc.jsÃ¥ÂÂ.eslintignoreæÂÂ件
module.exports = {
root: true,
env: {
browser: true,
es6: true
},
parser: '@typescript-eslint/parser',
parserOptions: {
project: ['./tsconfig.json'],
tsconfigRootDir: __dirname,
ecmaVersion: 12,
ecmaFeatures: {
jsx: true
}
},
// æ©å±Â
// eslint:recommended å®Âæ¹æ¨èÂÂæ©å±Âï¼Â
// eslintå¼Â头çÂÂæ¯å®Âæ¹æ©å±ÂãÂÂ
// pluginå¼Â头çÂÂæ¯æÂÂ件类åÂÂ
// è¿ÂæÂÂä¸Âç§Âå½¢å¼ÂæÂ¥èªnpmÃ¥ÂÂ
çÂÂå½¢å¼Âï¼Âå®Âæ¹è§Âå®ÂnpmÃ¥ÂÂ
çÂÂæ©å±Âå¿Â
须以esling-config-å¼Â头ï¼Â使ç¨æ¶å¯以çÂÂçÂ¥å¼Â头ï¼Âå¦Âeslint-config-react-app,ç´æÂ¥åÂÂæÂÂreact-app
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:react/recommended', 'plugin:react/jsx-runtime', 'prettier'],
// æÂÂ件
plugins: ['@typescript-eslint'],
//
rules: {}
};
/node_modules
/dist
/*.js
æ»ç»Â
æ¬ç¯ÂæÂÂç« ä»Âç»ÂäºÂä»Â0å°1å¦Âä½ÂæÂÂ建ä¸Â个reactçÂÂÃ¥ÂÂ端å¼ÂÃ¥ÂÂæ¡Âæ¶并éÂÂæÂÂtypescriptãÂÂeslintãÂÂprettierçÂÂçÂÂ综åÂÂé Âç½®ï¼Âç®ÂÃ¥ÂÂä»Âç»ÂäºÂå¨é Âç½®æ¯Â个åÂÂè½è¿Âç¨Âä¸ÂéÂÂè¦Âå®Â裠ç¨å°ä¾ÂèµÂå 以åÂÂå çÂÂä½Âç¨ãÂÂtypescriptãÂÂeslintãÂÂprettierå¨è¿Âç¯ÂæÂÂ章并没æÂÂè¿Âè¡Â详ç»ÂçÂÂ说æÂÂï¼ÂÃ¥ÂÂç»Âå¯è½ä¼Âç»Âæ¯Âä¸Â个åÂÂçÂŒÂÂå°ä¸Âç¯ÂæÂÂç« ä¸Âå»详ç»ÂçÂÂ讲解ãÂÂå¦ÂæÂÂæÂÂé®é¢Âï¼Â欢è¿Âè¯Â论åº交æµÂãÂÂ