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" |