今天在搞项目的时候,想要在React项目中fetch本地的json文件却一直报404。
网上的解决方案,差不多说地址都是相对于首页index.html而言,所以将json数据放在相对index.html上就好了。
可是鼓捣了个把小时还是没有解决问题。据我观察,网上的解决方案都是基于 create-react-app
的项目,而我的项目是自己集成的环境。
为了验证网上的解决方案的可行性,不多说新建一个 create-react-app
构建的demo开撸~
create-react-app 项目
在 APP.js
中 加入 fetch
的函数,比如就放在 componentWillMount
这个函数里好了
componentWillMount = () => {
fetch("./data.json")
.then(res => res.json())
.then(json => console.log(json))
}
然后,在 public 文件夹下,新建一个 data.json 文件看看能不能取到数据。
{
"test1": 1,
"test2": 2,
"test3": 3
}
刷新下页面,发现很轻松地就取到了数据,证明网上的解决方案都靠谱,不过都是基于 create-react-app 这个脚手架构建的项目是这样引的。
文件路径是这样的:
寻找原因
为什么我自己集成的环境会遇到BUG呢?好吧,直接忽略找的过程(虽然确实鼓捣了好久,还把项目移植到了 create-react-app
环境下),Webpack
中的 devServer 配置项就是引起这一切问题的原因,它的功能大概是这样:
- 在开发环境下,DevServer 提供虚拟服务器,让我们进行开发和调试;
- 提供实时重新加载。简直美滋滋。大大减少开发时间。
然而罪魁祸首是 contentBase 这个属性。(有兴趣的可以去了解,我这里给出BUG解决方案)
解决方案
在 webpack.config.js
中(或者是 webpack.dev.config.js
之类的,package.json
start 命令跑的是什么文件就是哪个)
const path = require("path")
module.exports = {
//其他配置不写了
...,
devServer: {
contentBase: path.join(__dirname, 'public')
}
}
然后再新建 public
文件夹,在把 json 文件和 index.html(因为它也是静态文件)都丢进去,最后终于拿到了我想要的数据~
再看 create-react-app
那么 create-react-app 肯定也在哪里设置了 contentBase 这个属性。
在 package.json
中,我们发现在 create-react-app
构建的项目 npm start
,跑的是 react-scripts start
,在 node_modules
文件夹中找到 react-scripts
文件夹,在里面搜索 contentBase
属性,果然我们在 react-scripts/config/webpackDevServer.config.js
文件中找到了
contentBase: paths.appPublic
paths.appPublic
是在别处的封装,但我们可以知道就是这条配置起的作用。
那么,之前网上找的答案给出的结论也是片面的,文件不是关于 index.html 的相对位置,是对于 public 文件夹的相对位置,并且只能读取 public 文件夹中的静态文件,所以对于 public 的同级上级是取不到的,就把静态文件放到 public 文件夹中吧,这也是一个很好的编码规范。