react+webpack 搭建工程
具体工程可以看我的github
webpack.config.js
const path = require('path')
const webpack = require('webpack')
const HTMLPlugin = require('html-webpack-plugin')
//判断是否是开发环境
const isDev = process.env.NODE_ENV === 'development'
const config = {
//入口
entry: {
app: path.join(__dirname, '../client/app.js')
},
//出口
output: {
filename: '[name].[hash].js', // 文件更改后重新打包,hash值变化,从而刷新缓存
path: path.join(__dirname, '../dist'),
//很重要
publicPath: '/public/',
},
//解析
resolve: {
extensions: ['.js', '.jsx'], // 自动解析确定的扩展
},
module: {
rules: [
{
//前置(在执行编译之前去执行eslint-loader检查代码规范,有报错就不执行编译)
enforce: 'pre',
test: /.(js|jsx)$/,
loader: 'eslint-loader',
exclude: [
path.join(__dirname,'../node_modules')
]
},
{ //将jsx转换成 js
test: /.jsx$/,
loader: 'babel-loader'
},
{ //将ES6语法转成 低版本语法
test: /.js$/,
loader: 'babel-loader',
exclude: [//排除node_modules 下的js
path.join(__dirname,'../node_modules')
]
}
]
},
plugins: [
// 生成一个html页面,同时把所有 entry打包后的 output 文件全部注入到这个html页面
new HTMLPlugin({
template: path.join(__dirname, '../client/template.html')
})
],
//开发模式
mode: 'development'
}
if(isDev){
config.entry = [
'react-hot-loader/patch', //设置这里
path.join(__dirname, '../client/app.js')
]
config.devtool = '#cheap-module-eval-source-map' // source-map 方便排错
config.devServer = {
host: '127.0.0.1',
port: '8887',
contentBase: path.join(__dirname, '../dist'), //告诉服务器从哪个目录中提供内容
hot: true,//启用 webpack 的模块热替换特性
overlay: {//当出现编译器错误或警告时,就在网页上显示一层黑色的背景层和错误信息
errors: true
},
publicPath: '/public/',//webpack-dev-server打包的内容是放在内存中的,这些打包后的资源对外的的根目录就是publicPath,换句话说,这里我们设置的是打包后资源存放的位置
historyApiFallback: {
index: '/public/index.html'
}
}
config.plugins = [...config.plugins, new webpack.HotModuleReplacementPlugin() ]
}
module.exports = config
安装包依赖
# react
yarn add react react-dom
# webpack相关
yarn add webpack webpack-cli webpack-dev-server html-webpack-plugin --dev
# babel相关
yarn add babel-loader @babel/core @babel/preset-env @babel/preset-react
- babel-loader:使用 Babel 转换 JavaScript依赖关系的 Webpack 加载器
- @babel/core:即 babel-core,将 ES6 代码转换为 ES5
- @babel/preset-env:即 babel-preset-env,根据您要支持的浏览器,决定使用哪些 transformations / plugins 和 polyfills,例如为旧浏览器提供现代浏览器的新特性
- @babel/preset-react:即 babel-preset-react,针对所有 React 插件的 Babel 预设,例如将 JSX 转换为函数
.babelrc
{
"presets": [ "@babel/preset-env", "@babel/preset-react" ],
"plugins": [
"react-hot-loader/babel"
]
}
webpack-dev-server 配置
devServer = {
host: '127.0.0.1',
port: '8887',
contentBase: path.join(__dirname, '../dist'), //告诉服务器从哪个目录中提供内容
hot: true,//启用 webpack 的模块热替换特性
overlay: {//当出现编译器错误或警告时,就在网页上显示一层黑色的背景层和错误信息
errors: true
},
publicPath: '/public/',//webpack-dev-server打包的内容是放在内存中的,这些打包后的资源对外的的根目录就是publicPath,换句话说,这里我们设置的是打包后资源存放的位置
historyApiFallback: {// 404时页面跳转
index: '/public/index.html'
}
}

react-hot-loader 热更替
步骤1 安装
yarn add react-hot-loader
步骤2
在 webpack.config.js 的 entry 值里加上 react-hot-loader/patch,一定要写在entry 的最前面
entry = [
'react-hot-loader/patch', //设置这里
path.join(__dirname, '../client/app.js')
]
步骤3
在 webpack.config.js 中设置 devServer 的 hot 为 true
步骤4
在 .babelrc 里添加 plugin
"plugins": [
"react-hot-loader/babel"
]
步骤5
在 webpack.config.js 的 plugins 里添加依赖的 HotModuleReplacement 插件
plugins: [
new HtmlWebpackPlugin({
template: __dirname + "/app/index.tmpl.html"
}),
new webpack.HotModuleReplacementPlugin() //设置这里
]
步骤6
最后这个操作就是在页面的主入口
import React from 'react';
import ReactDOM from 'react-dom';
import Greeter from './greeter';
import "./main.css";
import { AppContainer } from 'react-hot-loader'; //设置这里
const render = (App) => {
ReactDOM.render(
<AppContainer>
<App />
</AppContainer>,
document.getElementById('root')
)
}
render(Greeter)
// Hot Module Replacement API
if (module.hot) {
module.hot.accept('./greeter', () => {
render(require('./greeter').default)
})
}
使用eslint和editorconfig规范代码
为什么要使用这些?
- 规范代码有利于团队协作
- 纯手工规范时费力,而且不能保证准确性
- 能配合编辑自动提醒错误,提高开发效率
安装
yarn add eslint 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 --dev
.eslintrc
{
"parser": "babel-eslint",
"env": {
"browser": true,
"es6": true,
"node": true
},
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"extends": "airbnb",
"rules": {
"semi": [0],
"react/jsx-filename-extension": [0]
}
}
webpack.config.js 中新增配置
rules: [
{
//前置(在执行编译之前去执行eslint-loader检查代码规范,有报错就不执行编译)
enforce: 'pre',
test: /.(js|jsx)$/,
loader: 'eslint-loader',
exclude: [
path.join(__dirname,'../node_modules')
]
}
]
eslint 使用技巧
使用技巧
1 如果你不想让某一行被eslint检测,就在这行添加注释 eslint-disable-line
const NextApp = require('./App.jsx').default //eslint-disable-line
2 你也可以不采用某条校验规则
{
"rules": {
"semi": [0],
"react/jsx-filename-extension": [0]
}
}
3 ESLint 忽略特定的文件和目录
在项目根目录创建一个 .eslintignore 文件告诉 ESLint 去忽略特定的文件和目
build/*.js
4 eslint 配合git
在git commit代码的时候,使用git hook 调用eslint进行代码规范验证,不规范的代码无法提交到仓库
yarn add husky --dev
在package.json下新增两个 script
"scripts": {
"eslint": "eslint --ext .js --ext .jsx client/",
"precommit": "npm run lint"
}
.editorconfig
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_lint = lf
insert_final_newline = true
trim_trailing_whitespace = true
package.json 的scripts
"scripts": {
"clear": "rimraf dist",
"build:client": "webpack --config build/webpack.config.client.js",
"build:server": "webpack --config build/webpack.config.server.js",
"build": "npm run clear && npm run build:client && npm run build:server",
"dev:client": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.client.js",
"dev:server": "nodemon server/server.js",
"eslint": "eslint --ext .js --ext .jsx client/",
"precommit": "npm run eslint"
},
yarn add rimraf cross-env --dev
rimraf
rimraf 包的作用:以包的形式包装rm -rf命令,就是用来删除文件和文件夹的,不管文件夹是否为空,都可以删除
rimraf 要删除的目录
cross-env
这个迷你的包(cross-env)能够提供一个设置环境变量的scripts,让你能够以unix方式设置环境变量,然后在windows上也能兼容运行。解决跨平台设置NODE_ENV的问题
cross-env NODE_ENV=development