我可以使用带有 create-react-app 的自定义 node_modules 路径吗

Posted

技术标签:

【中文标题】我可以使用带有 create-react-app 的自定义 node_modules 路径吗【英文标题】:Can I use a custom node_modules path with create-react-app 【发布时间】:2021-02-15 14:49:07 【问题描述】:

我正在一个虚拟机内的项目上工作(实际上是通过 vscode 远程容器在 Windows 上运行的 docker)。我想避免在$(pwd)/node_modules 上构建我的react 应用程序,因为$(pwd) 下的所有内容都会同步到我的Windows 文件系统,这会导致严重的性能问题。

总的来说,我对 nodejs 还很陌生,但我很惊讶这似乎很难弄清楚。

我成功地开始了这个:

yarn --modules-folder /tmp/vendor

这给了我一个/tmp/vendor 文件夹,其中列出了预期的依赖项。

对于下一步,我想运行开发服务器,所以我运行这个:

yarn --modules-folder /tmp/vendor start

我收到/bin/sh: react-scripts: command not found。我认为yarns --modules-folder 在运行命令时不会重新配置PATH 信息(yarn start 调用react-scripts start)。所以我只是添加了自己的 PATH 作为解决方法:

PATH=$PATH:/tmp/vendor/.bin/ yarn --modules-folder /tmp/vendor start

但现在我明白了:

[root@352b76226b83 owio]# PATH=$PATH:/tmp/vendor/.bin/ yarn --modules-folder /tmp/vendor start
yarn run v1.22.5
$ react-scripts start
internal/modules/cjs/loader.js:965
  throw err;
  ^

Error: Cannot find module 'react-dev-utils/crossSpawn'
Require stack:
- /tmp/vendor/react-scripts/bin/react-scripts.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:962:15)
    at Function.Module._load (internal/modules/cjs/loader.js:838:27)
    at Module.require (internal/modules/cjs/loader.js:1022:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at Object.<anonymous> (/tmp/vendor/react-scripts/bin/react-scripts.js:18:15)
    at Module._compile (internal/modules/cjs/loader.js:1118:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1138:10)
    at Module.load (internal/modules/cjs/loader.js:982:32)
    at Function.Module._load (internal/modules/cjs/loader.js:875:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12) 
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/tmp/vendor/react-scripts/bin/react-scripts.js' ]

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command

由于它抱怨缺少模块,我还设置了 NODE_PATH(我猜 yarn 也不转发这个变量):

NODE_PATH=/tmp/vendor PATH=$PATH:/tmp/vendor/.bin/ yarn --modules-folder /tmp/vendor start

有了这个,我得到:

./src/index.jsx
Line 0:  Parsing error: Cannot find module 'eslint-scope' from '/tmp/vendor/eslint/lib/api.js'

我被困在这里,因为eslint-scope确实存在,而且我已经可以解决路径问题。

我很想开始尝试 CRA 和 yarn 之外的其他工具,但我对生态系统的了解还不够深入,还不知道如何移植我的应用程序。任何建议将不胜感激。

编辑:

通过将vendor 更改为node_modules,我离得更近了。我想这个约定在某种程度上是必要的。我还将NODE_PATH=/tmp/node_modules 添加到.env 文件中,并将--modules-folder /tmp/node_modules 添加到.yarnrc 文件中。

编辑 2:

我按照建议为$(pwd)/node_modules -&gt; /tmp/node_modules 创建了一个符号链接,这一次似乎奏效了,因为我将 NODE_PATH 添加到.env

似乎所有的 react-script 东西现在都在工作,但是在编译 src/components/ 下的本地源文件时,我收到了关于没有从 /tmp/node_modules 解析确实存在的模块的错误。

【问题讨论】:

自定义文件夹的链接怎么样?它也会引起问题吗? 刚刚添加了一个EDIT 2。我之前尝试过这个并且遇到了问题,但是这次我看到了一个新的符号链接错误。 哦,等等,我在之前的命名约定中创建了错误的链接。 似乎花了些时间,谢谢。我想我早些时候尝试过这个,但没有在.env 中设置NODE_PATH,但它有问题。也许我会缩小我需要和不需要的范围并发布后续答案。 【参考方案1】:

在 Estus 的一些修补和支持后,我发现以下内容对我有用:

.env 带有NODE_PATH=/tmp/node_modules 的文件 .yarnrc 带有--modules-folder /tmp/node_modules 的文件 $(pwd)/node_modules -&gt; /tmp/node_modules 的符号链接

我不确定为什么需要符号链接,并且很想知道是否有人有类似.env 的解决方案。不管设置了NODE_PATH,我的本地源文件似乎都是针对这个文件夹编译的。

其他我不明白的怪事,但也许有人会:

我不能只是在我的yarn 命令中将NODE_PATH 作为变量。 .env 中的值似乎改变了 node_modules 中的模块的编译方式。

我不能使用node_modules 以外的名称。不知道为什么。

顺便说一句:

对于登陆这里遇到相同问题的任何人(Windows 或 Mac 上的 docker 性能缓慢),您可能需要确保您的编辑器没有索引 node_modules。例如,我在.vscode/settings.json 中设置了files.watcherExclude 以包含"**/node_modules": true,"

【讨论】:

以上是关于我可以使用带有 create-react-app 的自定义 node_modules 路径吗的主要内容,如果未能解决你的问题,请参考以下文章

如何在使用 create-react-app 创建的应用程序中使用带有访问令牌的 API

使用带有错误调用-ELIFECYCLE的create-react-app启动错误

如何在使用 TypeScript 的 create-react-app 中使用带有 babel 插件的样式化组件?

使用 create-react-app 构建开发/调试构建

将 create-react-app 从 javascript 迁移到 typescript

使用 create-react-app 创建自定义绝对路径