You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React项目(JavaScript及TypeScript版本)中正确使用fs模块?

为什么在Create React App里导入fs模块会失败?根源与解决办法

我来帮你拆解这个问题——你遇到的所有报错本质上都是同一个核心原因:Create React App(CRA)生成的是运行在浏览器中的Web应用,而fs是Node.js专属的文件系统核心模块,浏览器环境根本不存在这个模块。下面我会逐个解释错误原因,再给出对应场景的解决方案。

先理清楚错误的共同根源

浏览器环境和Node.js环境是完全隔离的:

  • 浏览器出于安全限制,没有访问本地文件系统的权限,也没有Node.js的fs模块实现
  • CRA默认的Webpack配置会把Node.js核心模块(比如fs、path)替换成空对象或者模拟实现,所以你导入的fs其实是个空架子,自然找不到readFile这类方法
  • require是Node.js的模块加载方式,浏览器原生不支持,window.require只有在Electron这类混合环境中才会存在

对应你遇到的每个错误:

  • TypeError: fs.readFile is not a function:Webpack把fs替换成了空对象,所以fs存在但没有任何方法
  • Uncaught TypeError: Object(...) is not a function:直接导入的readFile是undefined,当成函数调用就会报错
  • window.require is not a function:浏览器里本来就没有require方法,只有Node.js环境才有
  • fs__WEBPACK_IMPORTED_MODULE_1__.readFile is not a function:和第一个错误一致,打包后的fs是空对象,readFile不存在

不同需求下的解决方案

你需要先明确自己的真实需求,再选择对应的方案:

1. 需求:在浏览器端读取用户本地文件

这是最常见的场景,绝对不能用fs,得用浏览器原生的File API:通过<input type="file">让用户主动选择文件,再用FileReader读取内容。示例代码(React/TS通用):

function LocalFileReader() {
  const handleFileSelect = (e) => {
    const selectedFile = e.target.files?.[0];
    if (!selectedFile) return;

    const reader = new FileReader();
    reader.onload = (event) => {
      // 读取到的文件内容,根据读取方式不同可以是文本、ArrayBuffer等
      const fileContent = event.target.result;
      console.log('读取到的文件内容:', fileContent);
      // 这里可以把内容存入state或者做其他处理
    };
    // 读取为文本,也可以用readAsArrayBuffer、readAsDataURL等
    reader.readAsText(selectedFile);
  };

  return (
    <div>
      <p>选择本地文件读取:</p>
      <input type="file" onChange={handleFileSelect} />
    </div>
  );
}

2. 需求:在构建阶段读取本地文件(比如注入静态内容)

如果你是想在编译时读取本地文件的内容,注入到前端代码里,可以通过修改Webpack配置实现:

  • 方案一:使用react-app-rewired(无需eject)

    1. 安装依赖:
      npm install react-app-rewired raw-loader --save-dev
      
    2. 在项目根目录创建config-overrides.js:
      module.exports = function override(config, env) {
        // 添加规则,匹配你要读取的文件类型(比如.txt、.md)
        config.module.rules.push({
          test: /\.(txt|md)$/,
          use: 'raw-loader',
        });
        return config;
      };
      
    3. 修改package.json里的启动脚本:
      "scripts": {
        "start": "react-app-rewired start",
        "build": "react-app-rewired build",
        "test": "react-app-rewired test"
      }
      
    4. 然后就可以在代码里直接导入文件内容:
      import licenseText from './LICENSE.txt';
      console.log(licenseText);
      
  • 方案二:直接写Node.js脚本处理文件,把结果生成静态JSON,再在React里导入

3. 需求:开发Electron混合应用(同时用到Node.js和浏览器)

如果你的项目是Electron应用,CRA作为渲染进程,那么可以在Electron主进程中使用fs,再通过IPC通信让渲染进程调用:

  • 主进程代码(Node.js环境):
    const { app, BrowserWindow, ipcMain, fs } = require('electron');
    const path = require('path');
    
    function createWindow() {
      const mainWindow = new BrowserWindow({
        webPreferences: {
          preload: path.join(__dirname, 'preload.js'), // 推荐用preload脚本做IPC桥接
          contextIsolation: true, // 开启上下文隔离,更安全
          nodeIntegration: false, // 关闭直接的node集成
        },
      });
      mainWindow.loadURL('http://localhost:3000'); // 加载CRA开发服务
    }
    
    // 注册IPC处理函数,处理渲染进程的文件读取请求
    ipcMain.handle('read-local-file', async (event, filePath) => {
      try {
        return await fs.promises.readFile(filePath, 'utf8');
      } catch (err) {
        console.error('读取文件失败:', err);
        throw err;
      }
    });
    
    app.whenReady().then(createWindow);
    
  • Preload脚本(在渲染进程和主进程之间做桥接):
    const { contextBridge, ipcRenderer } = require('electron');
    
    contextBridge.exposeInMainWorld('electronAPI', {
      readFile: (filePath) => ipcRenderer.invoke('read-local-file', filePath),
    });
    
  • React渲染进程代码:
    async function readFileFromElectron() {
      try {
        // 通过暴露的electronAPI调用主进程的文件读取方法
        const content = await window.electronAPI.readFile('/path/to/your/file.txt');
        console.log(content);
      } catch (err) {
        console.error('读取失败:', err);
      }
    }
    

关于tsconfig.json的说明

这个问题和tsconfig.json没有直接关系,但如果是TypeScript项目,导入fs时会出现类型报错,那是因为没安装@types/node:

npm install @types/node --save-dev

但注意,安装类型只是解决编译时的类型提示,运行时还是会报错,因为浏览器环境没有fs模块。

内容的提问来源于stack exchange,提问作者Eternally_Ascend

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 21:38:11