node搭建react-router开发环境
自己搭的脚手架,因为一些原因没使用webpack-dev-server,目录结构如下
|-src
|-page1
|-index.html
|-index.js
|-other.js
|-index.scss
然后写着写着发现一个问题,因为写的是多页面形式的工程,每个目录下有一个html模板,又没有实际在生产中使用,所以写的内容比较简单,都是自己写一些测试的东西,但是这个结构如果要用react-router,就麻烦了,因为针对目前这个结构,是直接使用了express的static中间件来对生成的文件进行返回,webpack打包出的文件生成在dist文件夹下面,然后启动这样一个node文件来监听
const express = require("express");
const app2 = express();
const port2 = 3002;
app2.use(express.static('project/'));
app2.listen(port2);
访问的时候,一般是输入localhost:3002/page1.html这样来访问的,但是用到react-router的时候,不能直接在浏览器里输入路径了,比如我输入localhost:3002/page1.html/main/api,静态文件代理就失效了,这个事情摸索了挺久,但是结果一说特别简单,就是起两个监听,一个监听html,一个监听js和css,webpack打包的时候,给output配置一个publicPath,配置成一个和html不一样的端口,比如html是在3003上监听,js和css在3002上监听,生成的html模板如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div id="app"></div>
// 注意下面这个script的src的路径
<script type="text/javascript" src="http://localhost:3002/dist/0708.js"></script>
</body>
</html>
node文件如下,
const express = require("express");
const fs = require("fs");
// 监听html
const app = express();
const port = 3003;
app.get("*", (req, res) => {
const url = req.originalUrl;
// 下面这行里readFileSync的路径可以自己改
res.send(fs.readFileSync(`project/dist/${url.split('/')[1]}.html`).toString());
});
app.listen(port);
// 监听js和css文件
const app2 = express();
const port2 = 3002;
app2.use(express.static('project'));
app2.listen(port2);
踩坑
这个摸索的过程里,还遇到了一些坑,
1.react-router 3和4的不同用法
react-router 3是这样写的,basename是为了上面的html文件名可以不用在route里面写了,注意react-router版本是3的话,history这个包的版本也要是3
import { Route, Router, useRouterHistory } from 'react-router';
import { createHistory } from 'history';
const browserHistory = useRouterHistory(createHistory)({
basename: '/app',
});
ReactDOM.render( (
<Router history={browserHistory}>
<Route path="/detail1" component={DetailPage} />
<Route path="/detail2" component={DetailPage2} />
</Router>
), document.getElementById('root'));
react-router 4是这样写的,注意react-router 4要安装的不是react-router,而是react-router-dom
import { Route, BrowserRouter } from 'react-router-dom';
const ddd = (
<BrowserRouter basename='/0708/main'>
<Route path="/detail1" component={DetailPage} />
<Route path="/detail2" component={DetailPage2} />
</BrowserRouter>
);
ReactDOM.render(ddd, document.getElementById("app"));
2.报错
如果写错了ReactDOM.render里面的document.getElementById的元素名称,会报这个,但是这个错,让人摸不着头脑Uncaught Invariant Violation: Minified React error #200; visit https://reactjs.org/docs/error-decoder.html?invariant=200 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
,不排除有别的情况会报这个,但是元素id写错了也是一种可能性
有兴趣可以看看我写的hellowebpack,相关代码都在里面
https://github.com/vzhufeng/helloWebpack