如何配置 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 startyarn 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.jsonpostbuild 脚本中使用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.",
        ...
    
    ...

但是,这种方法不是跨平台的(与 rimrafrm -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

UITableView,如何修复页脚,使其在滚动时永远不会向上或向下移动?

如何放置时间戳以使其在保存时不会重复

如何使标记完美重叠,使其不会在同一端出现两次?