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

Create React App(含Craco)中require.context使用异常的排查与疑问

解决CRA+TypeScript中require.context的调用问题

先直接解答你最后发现的核心疑问:为什么直接在index.js里调用require.context正常,放在被导入的myfile.js里就失败? 这本质是Webpack对require.context的静态分析规则导致的,结合你之前的错误,咱们一步步拆解:

问题根源分析

CRA内置的Webpack原生支持require.context,但它是编译时静态特性,Webpack需要在编译阶段就能确定两个关键信息:

  1. 要扫描的目录路径(必须是静态字符串,不能是运行时动态计算的)
  2. 匹配的文件规则

你在myfile.js里的写法有两个致命问题:

const packagesDirectory = path.join(__dirname, '../../../../packages');
const textDataContext = require.context(packagesDirectory, true, /(\w+)\.(\w+)\.(mdx?)/);
  • path.join(__dirname, ...)是运行时动态计算的路径,Webpack编译时无法提前知晓这个路径的具体指向,因此没法静态扫描目录生成对应的context函数,最终导致运行时出现__webpack_require__(...).context is not a function错误。
  • 浏览器环境中根本没有__dirname和fs模块(你后来用babel插件出现fs.readdirSync错误,就是因为这个插件模拟的是Node环境的require.context,完全不兼容浏览器)。

而你在index.js里用的是静态相对路径:

const something = require.context('../../packages/', true, /(\w+)\.(\w+)\.(mdx?)/);

Webpack编译时能直接识别这个路径,扫描对应目录生成context函数,所以运行一切正常。

正确解决方案

方案1:使用静态相对路径(最推荐,符合Webpack设计)

把myfile.js里的动态路径改成相对于当前文件的静态字符串,比如:

// myfile.js
// 注意:路径是相对于myfile.js的位置,而非项目根目录
const textDataContext = require.context('../../../../packages', true, /(\w+)\.(\w+)\.(mdx?)/);

这样Webpack编译时就能扫描到目标目录,生成对应的context函数,运行时不会再报错。

方案2:如果必须动态指定路径(不推荐)

如果业务需求确实需要动态路径,那require.context就不再适用了,你可以改用Webpack的动态import结合glob(需要额外配置):

  1. 安装依赖:npm install glob --save-dev
  2. 在craco.config.js中配置webpack:
const CracoLessPlugin = require('craco-less');
const glob = require('glob');

module.exports = {
  plugins: [{ plugin: CracoLessPlugin }],
  webpack: {
    configure: (webpackConfig) => {
      // 添加glob相关解析逻辑
      return webpackConfig;
    }
  }
};
  1. 在代码中用glob动态获取文件路径,再用动态import加载:
import glob from 'glob';

// glob会在Webpack打包阶段处理路径,而非浏览器运行时
const files = glob.sync('../../../../packages/**/*.mdx', { cwd: __dirname });
files.forEach(file => {
  import(file).then(module => {
    // 处理加载的模块
  });
});

不过这种方式会失去Webpack的tree-shaking优化,除非必要不建议使用。

避坑总结

  • 不要使用babel-plugin-require-context-hook:它是为Node环境设计的,浏览器环境没有fs模块,必然报错。
  • 永远记住require.context的路径必须是静态字符串:Webpack的静态分析是核心,动态路径会直接导致它失效。
  • 浏览器环境没有__dirname:CRA打包后的代码运行在浏览器,Node的内置变量和模块都不可用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 10:22:47