使用 TypeScript 和 NPM 链接创建 React 应用程序:导致模块解析失败的枚举
Posted
技术标签:
【中文标题】使用 TypeScript 和 NPM 链接创建 React 应用程序:导致模块解析失败的枚举【英文标题】:Create React App with TypeScript and NPM Link: Enums causing Module parse failed 【发布时间】:2021-04-29 18:58:42 【问题描述】:我有一个基本的create-react-app
TypeScript 项目 (client
)。只是目录,我有一个server
和一个shared
文件夹。在shared
文件夹中,我有一些interface
s 和enum
s 我在server
和client
之间共享。
我希望将此shared
文件夹链接到client
和server
包。
首先,我转到shared
并运行$ yarn link
,然后从client
和server
文件夹运行$ yarn link shared
。
服务器非常高兴,大部分情况下客户端也是如此。但是,一旦我使用client
中shared
目录中的enum
s 之一,我就会收到错误消息:
../shared/src/models/Roles.ts 4:0
Module parse failed: The keyword 'enum' is reserved (4:0)
File was processed with these loaders:
* ./node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js
You may need an additional loader to handle the result of these loaders.
| $RefreshSetup$(module.id);
|
> enum Roles
| RW_ORG = "rw_org", // can modifiy organization and it's users, nothing else
我是这样导入的:
import Roles from "shared";
但也尝试了许多其他方法。
我正在从 shared
index.ts
像这样导出它
import Roles from "./models/Roles";
export type
// all of my interfaces
;
export Roles
我所有的interface
s 都可以使用,所以我不明白。这到底是怎么回事?
【问题讨论】:
【参考方案1】:好吧,事实证明这些错误都是由 create-react-app 的默认 webpack.config.js
引起的。如果你导航到 code node_modules/react-scripts/config/webpack.config.js
你会找到一行 include: paths.appSrc
这基本上将 Babel 限制在 react 应用程序本身的 src/
文件夹中。
这意味着,如果你在它之外yarn link
ed 一个文件夹,Babel 不会将其转换为普通 JS,因此 React 无法使用它。
有两个 hacky 解决方案,但我想要一个更好的解决方案。
-
每次安装节点模块时手动(或通过构建脚本)从
react-scripts
中删除include: paths.appSrc
行
制作一个脚本,在每次修改外部目录时将外部目录复制到您的 React src
目录中。
我真的希望有一个官方的方法来解决这个问题......
【讨论】:
我遇到了类似的问题,并通过将 ORIGINAL(共享)文件夹放在 react 应用程序源中并将链接文件夹放在服务器中来解决它,它不关心这个作为 react-script确实:) @YochailLehman 是的,这是另一种可能的解决方案。老实说,最好的办法就是执行这些选项之一,直到您准备好将共享目录变成实际模块。此时,您应该在进行更改时构建共享模块并将其安装为本地包(或某处的托管包),而不是依赖链接或其他任何东西。 我用@craco/craco 自动化了它:gist.github.com/PhilippMolitor/00f427d12a9c5bca84309058d88846b7 你也可以使用include: [paths.appSrc, /\.(ts|tsx)$/]
【参考方案2】:
根据@foxtrotuniform6969 的回答,我创建了一个@cracro/craco
配置,它可以自行消除行为不端的设置。
module.exports =
webpack:
configure: (webpackConfig) => (
...webpackConfig,
module:
...webpackConfig.module,
rules: webpackConfig.module.rules.map((rule) =>
if (!rule.oneOf) return rule;
return
...rule,
oneOf: rule.oneOf.map((ruleObject) =>
if (
!new RegExp(ruleObject.test).test('.ts') ||
!ruleObject.include
)
return ruleObject;
return ...ruleObject, include: undefined ;
),
;
),
,
),
,
;
https://gist.github.com/PhilippMolitor/00f427d12a9c5bca84309058d88846b7
【讨论】:
我一定要尽可能地尝试一下,干得好 很好,这对我有用!【参考方案3】:可以使用react-app-rewired 自动删除other answer 中提到的包含路径设置。
以下config-overrides.js
适用于react-scripts:4.0.3
并导致 babel 也转译节点模块中的文件。
// config-overrides.js
module.exports = function override(config, env)
// This line might break with other react-script versions
delete config.module.rules[1].oneOf[2].include
return config
【讨论】:
看起来有点可疑......但我想没有多少选择。 确实,非常可疑。但可能比替代品更好......【参考方案4】:此问题的其他答案建议删除react-scripts
'webpack.config
中的include
(使用craco
或react-app-rewired
)。我发现这适用于 yarn start
,但是当我使用 yarn build
进行生产构建时,我在运行时收到错误 Uncaught ReferenceError: exports is not defined
。
除了删除现有的 src 目录之外,我还必须添加另一个项目的 src,而不是删除包含。
这是我的config-overrides.js
与react-app-rewired
一起使用。
对于react-scripts
4:
const path = require("path");
module.exports = function override(config)
// See https://***.com/questions/65893787/create-react-app-with-typescript-and-npm-link-enums-causing-module-parse-failed.
config.module.rules[1].oneOf[2].include = [
path.join(__dirname, './src'),
path.join(__dirname, '../backend/src')
];
return config
对于react-scripts
5:
const path = require("path");
module.exports = function override(config)
// See https://***.com/questions/65893787/create-react-app-with-typescript-and-npm-link-enums-causing-module-parse-failed.
config.module.rules[1].oneOf[3].include = [
path.join(__dirname, './src'),
path.join(__dirname, '../backend/src')
];
return config
【讨论】:
以上是关于使用 TypeScript 和 NPM 链接创建 React 应用程序:导致模块解析失败的枚举的主要内容,如果未能解决你的问题,请参考以下文章
通过 npm 链接和 typescript 本地开发的多模块
从使用 nestjs API 应用程序调试 npm 库(使用 noidejs、nestjs 和 typescript 构建)