如何使用 create-react-app(无弹出)导入共享的打字稿代码?

blu*_*e10 13 javascript typescript reactjs webpack create-react-app

我正在尝试在非弹出模式下的 create-react-app 中实现 TypeScript 代码共享,但我遇到了臭名昭著的限制,即src不允许在外部导入:

You attempted to import ../../common/src/lib.ts which falls outside of the project src/ directory. [...]

对于非 TypeScript 的情况,这里已被询问并回答,但我无法获得任何使用 TypeScript 的解决方案。具体而言,所提出的解决方案存在的问题是:

  • 设置baseDirts-config.json:在这里创建反应的应用程序内抱怨:你的项目baseUrl只能被设置为srcnode_modules。Create React App 目前不支持其他值。

  • 基于 react-app-rewired 的方法:更有前途。禁用ModuleScopePlugin让我过去了“在 src 之外尝试导入”错误,但现在的问题是打字稿文件的加载器无法正常运行:

    在此处输入图片说明

    我已经验证它.ts本身没问题:./src从那里复制并导入它工作正常。

    我还增加了../../common/src文件夹添加到includes列表中ts-config.json

    我的猜测是 webpack 加载器配置以某种方式有一个规则,可以防止 TypeScript 加载器转译与其预期路径模式不匹配的文件。如何使用 react-app-rewired 解决这个问题?

  • 符号链接源也不起作用——同样的问题。可能是因为 webpack 在内部解析符号链接并在正常加载器规则不适用的路径中看到文件。

  • 基于弹出的解决方案:我现在不想弹出,但我尝试过,基本上又遇到了同样的问题。

我还发现了其他听起来相关但没有回答问题的问题:


在单存储库中重新使用 TypeScript 类型似乎是一个相当合理的模式。我是否遗漏了什么,或者为什么 create-react-app 使这变得如此困难?


重现:我的代码基本上是你从中得到的 100%

npx create-react-app my-app --template typescript
Run Code Online (Sandbox Code Playgroud)

添加了一个到外部的导入。

Zee*_*han 9

您可以使用craco(create-react-app 配置覆盖)来覆盖 webpack 配置(抽象为 CRA 的一部分)而不弹出。
此外,您可以使用ts-loader直接在外部项目中引用非转译的 ts 代码(例如,如果您想引用/使用共享代码/lib 作为单存储库的一部分)。

假设您的 CRA 应用程序位于client您的项目结构如下所示的目录中:

client/
|--src/
|--package.json
shared/
|--package.json
|--(ts files)
package.json
Run Code Online (Sandbox Code Playgroud)
client/
|--src/
|--package.json
shared/
|--package.json
|--(ts files)
package.json
Run Code Online (Sandbox Code Playgroud)
  1. craco.config.jsclient/(CRA) 目录中创建一个文件
  2. 确保craco.config.js有以下内容
cd client
yarn add -D @craco/craco ts-loader
Run Code Online (Sandbox Code Playgroud)
  1. react-scripts命令替换client/package.jsoncraco
/* client/package.json */

"scripts": {
-   "start": "react-scripts start",
+   "start": "craco start",
-   "build": "react-scripts build",
+   "build": "craco build"
-   "test": "react-scripts test",
+   "test": "craco test"
}
Run Code Online (Sandbox Code Playgroud)

  • CRACO 现在支持 CRA 4.*,但我与 ts-loader 发生冲突,ts-loader 具有更高版本的 webpack 作为依赖项。我没有添加规则并安装 ts-loader,而是修改了 CRA 自己的规则,使其不具有将其限制为“src”目录的“include”字段。您可能需要一些额外的检查,以防索引发生变化,但本质上是这样做而不是推送新规则:“delete webpackConfig.module.rules[1].oneOf[2].include;” (2认同)

blu*_*e10 6

更新:由于 react-app-rewired 只是被动维护并且不支持 CRA 版本 2+(在撰写本文时我们是三个主要版本),我不再推荐这种方法。


经过更多小时的试验和阅读 GitHub 问题,我终于有了一个可行的解决方案。非常感谢 BirukDmitry,他在 GitHub 上发表这篇非常有用的帖子。分步指南:

  1. 安装 react-app-rewired 和 custom-cra

     npm i react-app-rewired customize-cra --save-dev
    
    Run Code Online (Sandbox Code Playgroud)
  2. 用这样的最小值配置 react-app-rewird config-overrides.js

     npm i react-app-rewired customize-cra --save-dev
    
    Run Code Online (Sandbox Code Playgroud)

    设置 (1) 类似于一般绕过 import-outside-src 限制所需的设置(请参阅链接问题)。

    设置 (2) 对其他路径的启用 babel-transpilation(因此,包括我假设的 TS 类型剥离)至关重要。这是您必须添加要从中导入的路径的地方。

  3. 不需要调整tsconfig.json

  4. 使用相对路径导入,例如import * as mymodule from '../../common/src/mymodule'.