欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

node搭建react-router开发环境

程序员文章站 2022-07-02 19:18:10
...

自己搭的脚手架,因为一些原因没使用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