3 React前端工程架构 - eslint & 其他优化
Thu, Sep 20, 2018
安装eslint:`npm i eslint -D`
创建eslint配置文件/.eslintrc
{ "extends": "standard" } |
client目录下,用到了jsx,需要另一套eslint规范
client/.eslintrc
{ "parser": "babel-eslint", "env": { "browser": true, "es6": true, "node": true }, "parserOptions": { "emacVersion": 6, "sourceType": "module" }, "extends": "airbnb", "rules": { "semi":[0] } } |
说明:eslint文档
- babel-eslint:指定用这个工具解析js代码,用这个是因为我们也用这个做编译
env - 指定环境:
- browser是告诉他我们在浏览器中,有document之类的,不然调document会报错
- 因为我们使用了webpack提供的部分api,所以可以把node的环境变量也包含进来
- parserOptions:
- emacVersion:定义使用的es版本 - es6
- sourceType:是使用模块的方式的,而不是传统的js引用方式
- extends:使用规则
- airbnb的规则很赞
- rules:配置自定义规则
webpack配置编译前检测 - webpack.config.client.js
... const config = { ... module: { rules: [ { enforce: "pre", test: /.(jsx|js)/, loader: 'eslint-loader', exclude: [ path.join(__dirname, '../node_modules') ] }, { test: /.jsx$/, loader: 'babel-loader', }, { test: /.js$/, loader: 'babel-loader', exclude: [ path.join(__dirname, '../node_modules') ] } ] }, ... } |
安装一大堆插件:
$ npm i babel-eslint eslint-config-airbnb eslint-config-standard eslint-loader eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-node eslint-plugin-promise eslint-plugin-react eslint-plugin-standard -D |
编译的时候会报一大堆错,没关系,先配置下格式化文件
.editorconfig
root = true [*] charset = utf-8 indent_style = space indent_size = 2 end_of_line = lf insert_final_new_line = true trim_trailing_whitespace = true |
禁止eslint检测的方法
import {AppContainer} from 'react-hot-loader' // eslint-disable-line |
"rules": { "semi":[0], "react/jsx-filename-extension":[0] } |
git-commit之前检测
工具:哈士奇
安装:`npm i husky -D`
定义npm script
package.json
{ ... "scripts": { ... "lint": "eslint --ext .js --ext .jsx client/", "precommit": "npm run lint" }, ... } |
说明:
- 定义lint方法 - 所有client文件夹下的js和jsx文件,都需要检测
- precommit这个东东,是哈士奇包里提供的git钩子,通过钩子,指定在commit之前强制运行lint方法
优化
webpack.config优化
client和server两个config中module有一些配置内容是一样,我们抽取baseConfig解决代码复用问题
说明:
- 工具:`npm i webpack-merge -D`
- 用webpackMerge串联两个配置 - 如果有冲突内容,后者覆盖前者
build/webpack.config.base.js
const path = require('path'); const config = { output: { filename: '[name].[hash].js', path: path.join(__dirname, '../dist'), publicPath: '/public/' }, module: { rules: [ { enforce: "pre", test: /.(jsx|js)/, loader: 'eslint-loader', exclude: [ path.join(__dirname, '../node_modules') ] }, { test: /.jsx$/, loader: 'babel-loader', }, { test: /.js$/, loader: 'babel-loader', exclude: [ path.join(__dirname, '../node_modules') ] } ] } }; module.exports = config; |
build/webpack.config.client.js
const path = require('path'); const HTMLPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); const webpackMerge = require('webpack-merge'); const baseConfig = require('./webpack.config.base'); const isDev = process.env.NODE_ENV === "development"; const config = webpackMerge(baseConfig,{ target: 'web', entry: { app: path.join(__dirname, '../client/app.js') }, output: { filename: '[name].[hash].js', }, plugins: [ new HTMLPlugin({ template: path.join(__dirname, '../client/template.html') }) ], mode: 'production' }); if (isDev) { config.entry = { app: [ 'react-hot-loader/patch', path.join(__dirname, '../client/app.js') ] }; config.devServer = { host: '0.0.0.0', port: '8787', contentBase: path.join(__dirname, '../dist'), hot: true, overlay: { error: true }, publicPath: '/public/', historyApiFallback: { index: '/public/index.html' }, }; config.mode = 'development'; config.plugins.push(new webpack.HotModuleReplacementPlugin()) } module.exports = config; |
build/webpack.config.server.js
const path = require('path'); const webpackMerge = require('webpack-merge'); const baseConfig = require('./webpack.config.base'); const config = webpackMerge(baseConfig, { target: 'node', entry: { app: path.join(__dirname, '../client/server-entry.js') }, output: { filename: 'server-entry.js', libraryTarget: 'commonjs2' } }); module.exports = config; |
站点图标的正确渲染
工具:`npm i serve-favicon -S`
server.js
... const favicon = require('serve-favicon'); ... app.use(favicon(path.join(__dirname, '../favicon.ico'))); ... |
web server实时更新
问题:服务端代码每次更新需要重启服务
解决方案:`npm i nodemon -D`
配置文件:nodemon.json
{ "restartable":"rs", "ignore": [ ".git", "node_modules/**/node_modules", ".eslintrc", "client", "build" ], "env": { "NODE_ENV": "development" }, "verbose": true, "ext": "js" } |
更新npm-script
"dev:web:start": "nodemon server/server.js" |