[译]基于create-react-app打造代码规范化的React项目

作者 杜梦杰 日期 2018-09-11
[译]基于create-react-app打造代码规范化的React项目

原文链接:https://medium.com/stephenkoo/how-to-set-up-create-react-app-redux-react-router-redux-thunk-prettier-scss-airbnb-eslint-dda0bba5616a

原文标题:Set up create-react-app with: Redux, React Router, Redux Thunk, Prettier, SCSS, Airbnb eslint, Standard stylelint, and CSS modules —— A (very) opinionated guide on setting up Create React App

原文作者:Stephen Koo

翻译:杜梦杰

前言:之前团队内经过讨论和沟通,确定了前端开发规范。规范的执行要由上到下,软硬兼施,除了要求成员们要有自觉性,最好在项目中配置代码规范化/格式化工具。我在配置这些工具时,踩了不少坑,后来有幸看到这篇文章。从头到尾,轻松地将所有工具配置好。本人对于这种规范化的项目比较推崇,拒绝杂乱无章的代码风格,之后的工作中会一直沿用,也推荐大家使用。Keep your code clean!

这是一篇在create-react-app中配置流行包的参考指南。

为了正确的安装这些包,我花了数小时来阅读文档和相关文章,写这篇文章的目的是节省大家的时间。

本指南假定您已经安装了brewnvmyarn。(译者注:原作者使用的是yarn,我在注释中写明了对应的npm命令)

0、安装Create React App

yarn global add create-react-app
// npm install create-react-app -g
create-react-app your-project-name
cd react-base
git init

1、配置SCSS

yarn add node-sass-chokidar npm-run-all
// npm install node-sass-chokidar npm-run-all --save-dev

package.json中添加:

"scripts": {
+ "build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/",
+ "watch-css": "npm run build-css && node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/ --watch --recursive",
+ "start-js": "react-scripts start",
+ "start": "npm-run-all -p watch-css start-js",
+ "build": "npm run build-css && react-scripts build",
"test": "react-scripts test --env=jsdom",

src/App.css 重命名为 src/App.scss

.gitignore中添加:

+# build products
+src/**/*.css

2、配置Prettier

yarn add husky lint-staged prettier
// npm install husky lint-staged prettier --save-dev

新建.prettierrc文件:

{
'singleQuote': true,
'trailingComma': 'es5',
}

package.json中添加:

+"lint-staged": {
+ "src/**/*.{js,jsx,json,scss,css}": [
+ "prettier --config .prettierrc --write",
+ "git add"
+ ]
+},
"scripts": {
+ "precommit": "lint-staged",
"build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/",

使用如下命令格式化整个项目:

./node_modules/.bin/prettier --config .prettierrc --write "src/**/*.{js,jsx,scss,css}"

编辑器中整合Prettier。(译者注:非常推荐安装编辑器插件,1+1>2)

3、配置eslint和eslint-config-airbnb

查看并安装eslint-config中的所有依赖:

npm info "eslint-config-airbnb@latest" peerDependencies

可以这样安装(Linux/OSX用户):

(
export PKG=eslint-config-airbnb;
npm info "$PKG@latest" peerDependencies --json | command sed 's/[\{\},]//g ; s/: /@/g' | xargs yarn add --dev "$PKG@latest"
)

或(Windows用户):

npm install -g install-peerdeps
install-peerdeps --dev eslint-config-airbnb

新建.eslintrc.js

module.exports = {
'env': {
'browser': true,
'jest': true,
'es6': true,
'node': true,
},
'extends': [
'airbnb',
'prettier',
],
'plugins': [
'prettier',
],
'rules': {
'prettier/prettier': ['error', {
'singleQuote': true,
'trailingComma': 'es5'
}],
},
'parserOptions': {
'ecmaFeatures': {
'jsx': true,
}
}
}

src/registerServiceWorker.js文件开头处添加:

+ /* eslint-disable no-console, no-param-reassign, no-use-before-define */
// In production, we register a service worker to serve assets from local cache.

检查现有代码

自动修复一些eslint问题:

node_modules/.bin/eslint --ext=js --ext=jsx --fix .

修改src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(React.createElement(App), document.getElementById('root'));
registerServiceWorker();

src/App.js 重命名为 src/App.jsx并修改:

import React from 'react';
import logo from './logo.svg';
import './App.css';
const App = () => (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
);
export default App;

src/App.test.js 重命名为 src/App.test.jsx并修改:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
});

4、配置stylelint和stylelint-config-standard

yarn add stylelint stylelint-config-standard --dev
// npm install stylelint-config-standard --save-dev

新建.stylelintrc

{
'extends': 'stylelint-config-standard',
}

5、配置eslint和stylelint命令

修改package.json

"lint-staged": {
+ "src/**/*.{js,jsx,json}": [
+ "eslint --fix",
+ "prettier --config .prettierrc --write",
+ "git add"
+ ],
+ "src/**/*.{scss,css}": [
+ "stylelint --config=.stylelintrc --fix",
+ "prettier --config .prettierrc --write",
+ "git add"
+ ]
},
"scripts": {
"precommit": "lint-staged",
"build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/",
"watch-css": "npm run build-css && node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/ --watch --recursive",
"start-js": "react-scripts start",
"start": "npm-run-all -p watch-css start-js",
"build": "npm run build-css && react-scripts build",
+ "test:lint:js": "eslint --ext=js --ext=jsx .",
+ "test:lint:scss": "stylelint --config=.stylelintrc '**/*.scss'",
+ "test:lint": "run-s test:lint:**",
+ "test:unit": "react-scripts test --env=jsdom",
+ "test": "run-s test:**",
"eject": "react-scripts eject",
"eslint-check": "eslint --print-config .eslintrc.js | eslint-config-prettier-check"
},

6、配置Redux、React Router和Redux Thunk

yarn add redux react-redux react-router-dom react-router-redux@next redux-thunk
// npm install react-redux react-router-dom react-router-redux@next redux-thunk --save

7、配置CSS Modules

  • 警告:本操作需要暴露(eject)create-react-app的配置
  • nulogycss-loader中的相关内容
yarn eject
// npm eject
yarn install
// npm install

修改config/webpack.config.dev.js

{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
+ modules: true,
+ localIdentName: "[name]__[local]--[hash:base64:5]"
},
},

修改config/webpack.config.prod.js

{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
+ modules: true,
minimize: true,
sourceMap: true,
},
},

修正现有CSS路径

删除css/scss文件类名中的 ‘-’ 。

修改 src/App.jsx

import React from 'react';
import logo from './logo.svg';
import styles from './App.css';
const App = () => (
<div className={styles.App}>
<div className={styles.header}>
<img src={logo} className={styles.logo} alt='logo' />
<h2>Welcome to React</h2>
</div>
<p className={styles.intro}>
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
);
export default App;

最终成果

最终成果在下面两个Github仓库中:

其他一些有用的包

你可能会用到下面的一些包:

下面列出了create-react-app已使用的包(eject后可以看到)做参考,不要重复安装:

“autoprefixer”: “7.1.2”,
“babel-core”: “6.25.0”,
“babel-eslint”: “7.2.3”,
“babel-jest”: “20.0.3”,
“babel-loader”: “7.1.1”,
“babel-preset-react-app”: “^3.0.2”,
“babel-runtime”: “6.26.0”,
“case-sensitive-paths-webpack-plugin”: “2.1.1”,
“chalk”: “1.1.3”,
“css-loader”: “0.28.4”,
“dotenv”: “4.0.0”,
“eslint”: “4.4.1”,
“eslint-config-react-app”: “².0.0”,
“eslint-loader”: “1.9.0”,
“eslint-plugin-flowtype”: “2.35.0”,
“eslint-plugin-import”: “2.7.0”,
“eslint-plugin-jsx-a11y”: “5.1.1”,
“eslint-plugin-react”: “7.1.0”,
“extract-text-webpack-plugin”: “3.0.0”,
“file-loader”: “0.11.2”,
“fs-extra”: “3.0.1”,
“html-webpack-plugin”: “2.29.0”,
“jest”: “20.0.4”,
“object-assign”: “4.1.1”,
“postcss-flexbugs-fixes”: “3.2.0”,
“postcss-loader”: “2.0.6”,
“promise”: “8.0.1”,
“react”: “^15.6.1”,
“react-dev-utils”: “⁴.0.1”,
“react-dom”: “^15.6.1”,
“style-loader”: “0.18.2”,
“sw-precache-webpack-plugin”: “0.11.4”,
“url-loader”: “0.5.9”,
“webpack”: “3.5.1”,
“webpack-dev-server”: “2.7.1”,
“webpack-manifest-plugin”: “1.2.1”,
“whatwg-fetch”: “2.0.3”