如何配置 react-script 使其不会在“开始”时覆盖 tsconfig.json
Posted
技术标签:
【中文标题】如何配置 react-script 使其不会在“开始”时覆盖 tsconfig.json【英文标题】:How to configure react-script so that it doesn't override tsconfig.json on 'start' 【发布时间】:2019-05-16 14:51:10 【问题描述】:我目前正在使用create-react-app
来引导我的一个项目。基本上,我试图通过将这些添加到 create-react-app 生成的默认 tsconfig.json 中来在 tsconfig.json 中设置路径:
"baseUrl": "./src",
"paths":
"interfaces/*": [
"common/interfaces/*",
],
"components/*": [
"common/components/*",
],
,
但是,每次我运行基本上运行react-scripts start
的yarn start
时,它都会删除我的更改并再次生成默认配置。
如何告诉 create-react-app 使用我的自定义配置?
【问题讨论】:
来自文档,> 您不需要制作 tsconfig.json 文件,将为您制作一个。您可以编辑生成的 TypeScript 配置。 不幸的是,如果您编辑文件,它会被 yarn start 覆盖,从而丢弃所有更改。 github.com/facebook/create-react-app/issues/… 正如@Glenn 所说,tsconfig 文件会重置。即使在 tsconfig.json 文件中使用“扩展”,智能问题得到了解决,但编译失败。所以我尝试了thetopsites.net/article/58558041.shtml 步骤,发现工作正常 【参考方案1】:在 Botpress(使用 react-scripts 4.0.3)上,我们结合使用 2 个技巧来使用路径,而无需弹出或修补代码。正如 Glenn 和 Microcipcip 所说,第一步是扩展 tsconfig.json 文件
tsconfig.path.json
"compilerOptions":
"baseUrl": "./",
"paths":
"~/*": ["src/*"],
"common/*": ["../bp/src/common/*"]
tsconfig.json
...
"extends": "./tsconfig.paths.json"
然后让它在后台工作,使用包react-app-rewired
。它允许在不实际弹出 CRA 的情况下对 webpack 配置进行微调。
config-overrides.js
module.exports =
webpack: (config, env) =>
config.resolve.alias['common'] = path.join(__dirname, '../bp/dist/common')
config.resolve.alias['~'] = path.join(__dirname, './src')
要查看完整代码,可以查看github仓库https://github.com/botpress/botpress/tree/master/packages/ui-admin
【讨论】:
【参考方案2】:转到 node_modules/react-scripts/scripts/utils/verifyTypeScriptSetup.js 并替换
const compilerOptions =
...
;
通过
const compilerOptions = ;
【讨论】:
考虑到 node_modules 没有在源代码管理中维护,其他开发人员必须记住在他们的机器上做同样的事情,我不认为更改 node_modules 中的文件应该是前进的方向。 当然,永远不要接触 node_modules,也不要给其他开发人员带来压力。那么请享受通过npm install
进入那里的垃圾,np【参考方案3】:
对我来说,问题在于 VSCode 使用的是旧版本的 typescript (4.0.3),而项目附带的 typescript 版本是 (4.1.2)。
以下内容对我有用:
-
转到命令面板 CTRL+Shift+P。
选择“TypeScript:选择 TypeScript 版本...”。
选择“使用工作区版本”。
【讨论】:
【参考方案4】:对于 macOS,此解决方法应该有效。
package.json
"scripts":
"start": "osascript -e 'tell app \"Terminal\" to do script \"cd $PATH_TO_REACT_APP && node ./setNoEmitFalse\"' && react-scripts start",
...
,
...
setNoEmitFalse.js
const fs = require('fs');
const sleep = require('sleep')
const path = './tsconfig.json'
const run = async () =>
sleep(2)
const tsconfig = fs.readFileSync(path, 'utf-8');
const fixed = tsconfig.replace('"noEmit": true', '"noEmit": false');
fs.writeFileSync(path, fixed)
run()
在单独的终端 (osascript) 中执行 javascript 文件可为原始终端中的 react-scripts 提供正常输出。
【讨论】:
【参考方案5】:如果您像我一样使用 react-scripts 4.0.0,那么您需要做的就是删除该行(在我这边大约第 160 行):
paths: value: undefined, reason: 'aliased imports are not supported'
来自文件node_modules/react-scripts/scripts/utils/verifyTypeScriptSetup.js
我能够直接将我的 baseUrl 和路径配置添加到我的 tsconfig.json
文件中,如下所示:
"compilerOptions":
"baseUrl": ".",
"paths":
"@domain/*": ["../src/domain/*"],
,
最后编译并继续我的生活。
按照惯例,YMMV。请测试你的东西。这显然是一个 hack,但它对我有用,所以我在这里发帖以防它帮助某人。
如果您想与您的团队分享,这里有一个补丁:
diff --git a/node_modules/react-scripts/scripts/utils/verifyTypeScriptSetup.js b/node_modules/react-scripts/scripts/utils/verifyTypeScriptSetup.js
index 00139ee..5ccf099 100644
--- a/node_modules/react-scripts/scripts/utils/verifyTypeScriptSetup.js
+++ b/node_modules/react-scripts/scripts/utils/verifyTypeScriptSetup.js
@@ -156,7 +156,8 @@ function verifyTypeScriptSetup()
: 'react',
reason: 'to support the new JSX transform in React 17',
,
- paths: value: undefined, reason: 'aliased imports are not supported' ,
+ // Removed this line so I can add paths to my tsconfig file
+ // paths: value: undefined, reason: 'aliased imports are not supported' ,
;
编辑
根据 cmets 线程中的 @Bartekus 深思熟虑的建议,当我需要(可能)将此类临时更改添加到 npm 包时,我正在添加有关我使用的包的信息:patch-package
包本质上提供了一种以更简洁的方式对包进行更改的方法。特别是当您考虑协作时,直接更改 npm 文件并继续前进会变得非常麻烦。下次您更新该软件包时,甚至当您开始在新机器上开发并运行npm install
时,您的更改都将丢失。此外,如果您有团队成员在同一个项目上工作,他们将永远不会继承所做的更改。
实质上,您要通过以下步骤来修补软件包:
# fix a bug in one of your dependencies
vim node_modules/react-scripts/scripts/utils/verifyTypeScriptSetup.js
# run patch-package to create a .patch file
npx patch-package react-scripts
# commit the patch file to share the fix with your team
git add patches/react-scripts+4.0.0.patch
git commit -m "Enable aliased imports in react-scripts"
下次有人签出项目并安装它时,由于您在设置过程中添加的安装后脚本,补丁将自动应用:
"scripts":
+ "postinstall": "patch-package"
查看package's documentation中的最新说明
【讨论】:
一个讨厌的临时黑客。几乎更好地弹出? 你为什么觉得它很讨厌? IMO Facebook 的人可能已经添加了这条线,因为他们不想支持这一点。并不意味着它不适用于大多数情况。但你是对的,我可能会退出生产。我在一个我只需要完成的原型中使用了这个 hack,它运行良好。甚至在 docker 里面。 没有一个 node_modules 被签入,所以代码会被其他签出 repo 的人破坏?最好 fork react-scripts 并使用您的版本(您可以同时发送 PR!)。但很高兴你能找到修复它的地方。 啊,我现在明白你的意思了。一个有效的问题。我使用了一个方便的 npm 模块来调用补丁包。您更改 node_modules 文件,运行命令并生成补丁。然后,您将相同的命令添加到安装后的 npm 脚本,它每次都会重新修补(例如,当团队成员运行 npm i 时,因为此修补程序文件将在源代码控制中)。我仍然同意你的观点,分离会更好,但在某些特定情况下,它可能是值得的。 @avlnx 您应该在答案中添加有关patch-package
的信息,因为这是解决方案可行的关键部分。否则人们不会理解为什么有人会提议修改 node_modules 中的任何内容。对于其他想知道的人来说,是的,使用patch-package
是合法且理智的提议,用于处理必须处理的第三方依赖项的临时(或非)更改。【参考方案6】:
我遇到了与这个一般问题类似的问题(CRA 覆盖了我正在处理的 React 库的 tsconfig.json
中的 "noEmit": false
,其中我有两个单独的构建,一个用于本地开发,另一个用于构建生产带打字的图书馆)。简单的解决方案:在package.json
的postbuild
脚本中使用sed
。例如:In-place edits with sed on OS X。
...
"scripts":
...
"postbuild": "sed -i '' 's/THING CRA IS REPLACING/WHAT YOU ACTUALLY WANT/g' tsconfig.json # CRA is too opinionated on this one.",
...
...
但是,这种方法不是跨平台的(与 rimraf
是 rm -rf
的跨平台替代方案不同)。
【讨论】:
【参考方案7】:Create React App 目前不支持baseUrl
。但是有一种解决方法...要为 webpack 和 IDE 设置 baseUrl
,您必须执行以下操作:
-
使用以下代码创建
.env
文件:
NODE_PATH=./
-
创建一个
tsconfig.paths.json
文件,其中包含以下代码:
"compilerOptions":
"baseUrl": "src",
"paths":
"src/*": ["*"]
-
将以下行添加到
tsconfig.json
"extends": "./tsconfig.paths.json",
...
【讨论】:
如何导入文件? 看来我的配置不好。它现在可以工作(即使我有关于 tsconfig.json 的警告:“正在对您的 tsconfig.json 文件进行以下更改 [..]”。 很高兴你把它整理出来。警告是预期的,我也明白了。 这似乎适用于最新的 Create React App。我不需要 NODE_PATH 部分。 @Microcipcip 我无法在 react-scripts v3 或 v4 中使用它:(【参考方案8】:你不能,我不确定你什么时候可以。我一直在尝试使用 baseUrl 和路径,这样我就可以避免相对导入,但正如您所见,它们是故意删除某些值。 “(还)”令人鼓舞,但(叹息)谁知道他们什么时候会正式支持它。我建议subscribing to this github 问题在这种情况发生变化时发出警报。
The following changes are being made to your tsconfig.json file:
- compilerOptions.baseUrl must not be set (absolute imports are not supported (yet))
- compilerOptions.paths must not be set (aliased imports are not supported)
【讨论】:
【参考方案9】:通过使用this issue 的建议,我能够做到这一点。
将 react 脚本喜欢删除的配置选项放在一个单独的文件中(例如 paths.json),并通过 extends 指令从 tsconfig.json 中引用它。
paths.json:
"compilerOptions":
"baseUrl": "./src",
"paths":
"interfaces/*": [ "common/interfaces/*"],
"components/*": [ "common/components/*"],
tsconfig.json
"extends": "./paths.json"
...rest of tsconfig.json
【讨论】:
似乎这不再适用于较新版本的 react-scripts 为什么他们会这样做?真是烦死了@TranquilMarmot 你找到解决方案了吗? 看起来唯一的选择是降级或弹出。 CRA 维护者对社区的蔑视非常令人沮丧 我只是因为这个而弹出。任何人都有 PR 或者我应该开始深入研究代码以找到更改它的位置? 它看起来仍然有效,但仍然抱怨compilerOptions.paths must not be set (aliased imports are not supported)
。以上是关于如何配置 react-script 使其不会在“开始”时覆盖 tsconfig.json的主要内容,如果未能解决你的问题,请参考以下文章
react-scripts build 不会转换模板文字,应用程序在 IE 中不起作用
如何修复 react-scripts 启动时的“错误监视文件以进行更改:ECONNRESET”错误?
带有craco的故事书-叫一个不同版本的react-scripts