如何使用create-react-app(不弹出)导入共享的打字稿代码? [英] How to import shared typescript code using create-react-app (no eject)?
问题描述
我试图在非弹出模式下的create-react-app中实现TypeScript代码共享,但是我遇到了臭名昭著的限制,即在 src $ c $之外导入c>不允许:
您尝试导入../../common/src/lib。 ts不在项目src /目录中。 [...]
对于非TypeScript情况,这是
我已经验证了 .ts
本身也可以:复制到 ./ src
并从那里导入可以正常工作。
我还将 ../../ common / src
文件夹添加到<$ c $中的 includes
列表中c> ts-config.json 。
我的猜测是,webpack加载器配置中有一条规则会阻止TypeScript加载器来传输文件与预期的路径模式不匹配。
符号链接也不起作用-同样是同样的问题。可能是因为webpack在内部解析了符号链接,并在不适用常规加载程序规则的路径中看到了文件。
基于弹出式的解决方案:我想暂时不弹出,但是我尝试了,基本上又遇到了同样的问题。
我ve还发现了其他听起来相关但未解决问题的问题:
- 在Monorepo代码共享中创建React App +打字稿:听起来基本上是相同的问题,但并非如此,因为它要求退出的React应用程序。
- 在使用TypeScript和webpack的项目之间共享代码:还解决了代码共享问题,但没有解决特定于create-react-app,我不知道该解决方案是否可以转移到create-react-app,因为它需要手动进行webpack配置控制。
在单声道仓库中重新使用TypeScript输入似乎是一个相当合理的模式。我是否缺少某些东西,或者为什么create-react-app使它如此困难?
要重现:我的代码是基本上100%从
npx create-react-app my-app --template typescript
,并且向外部添加了一个导入。
您可以使用 craco (创建-
另外,您可以使用 ts-loader
来替换webpack配置(作为CRA的一部分)而不会弹出。直接在外部项目中引用未移植的ts代码(例如,如果您要引用/使用共享代码/ lib作为mono-repo的一部分)。
假定您的CRA应用程序位于 client
目录的项目结构如下:
client /
| --src /
| --package.json
shared /
| --package.json
|-(ts文件)
package.json
cd客户
毛线安装-D @ craco / craco ts-loader
- 在
client /
(CRA)目录中创建craco.config.js
文件 - 确保
craco.config.js
具有以下内容
const path = require( path);
module.exports = {
webpack:{
configure:webpackConfig => {
//必须使用ts-loader来引用外部打字稿项目/文件(非转译)
webpackConfig.module.rules.push({
test:/ \ .tsx?$ /,
loader:'ts-loader',
排除:/ node_modules /,
选项:{
transpileOnly:true,
configFile:' tsconfig.json',
},
})
return webpackConfig;
}
}
};
- 替换
反应脚本$
client / package.json
中的c $ c>命令与craco
/ * 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;
}
I'm trying to achieve TypeScript code sharing in a create-react-app in non-eject mode, but I'm running into the infamous restriction that imports outside of src
are not allowed:
You attempted to import ../../common/src/lib.ts which falls outside of the project src/ directory. [...]
For the non-TypeScript case this has been asked & answered here, but I can't get any of the solutions to work with TypeScript. Specifically the issues with the proposed solutions are:
Setting
baseDir
ints-config.json
: Here create-react-app complains about: Your project'sbaseUrl
can only be set tosrc
ornode_modules
. Create React App does not support other values at this time.Approaches based on react-app-rewired: More promising. Disabling the
ModuleScopePlugin
gets me past the "attempted import outside src" error, but the problem now is that the loader of typescript files doesn't play along:I have verified that the
.ts
itself is fine: Copying to./src
and importing it from there works fine.I have also added
../../common/src
folder to theincludes
list ints-config.json
.My guess is that somehow the webpack loader configuration has a rule that prevents the TypeScript loader to transpile files that don't match its expected path patterns. How can this be fixed using react-app-rewired?
Symlinking sources doesn't work either -- again with the same problem. Probably because webpack internally resolves the symlinks and sees the file in a path where the normal loader rules don't apply.
Eject based solutions: I'd like not to eject for now, but I tried and I'm basically running into the same problem again.
I've also found other questions that sounded related but didn't answer the problem:
- Create React App + Typescript In monorepo code sharing: Sounds basically like the same question, but it is not, because it is asking for the case of an ejected React app.
- Sharing code between projects using TypeScript and webpack: Also addresses the code sharing problem, but not create-react-app specific, and I don't know if the solution can be transferred to create-react-app, because it requires manual webpack config control.
Re-using TypeScript typings in a mono repo seems to be a fairly reasonable pattern. Am I missing something or why is the create-react-app making this so difficult?
To reproduce: My code is basically 100% what you get from
npx create-react-app my-app --template typescript
with one import to external added.
You could use craco (create-react-app config override) to override the webpack config (abstracted as part of CRA) without ejecting.
Additionally you could use ts-loader
to reference non-transpiled ts code directly in external projects (e.g. if you wanted to reference/use shared code/lib as part of a mono-repo).
Assuming your CRA app is in the client
directory your project structure is like the following:
client/
|--src/
|--package.json
shared/
|--package.json
|--(ts files)
package.json
cd client
yarn install -D @craco/craco ts-loader
- create a
craco.config.js
file in theclient/
(CRA) directory - ensure the
craco.config.js
has the following content
const path = require("path");
module.exports = {
webpack: {
configure: webpackConfig => {
// ts-loader is required to reference external typescript projects/files (non-transpiled)
webpackConfig.module.rules.push({
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
transpileOnly: true,
configFile: 'tsconfig.json',
},
})
return webpackConfig;
}
}
};
- Replace
react-scripts
commands inclient/package.json
withcraco
/* 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"
}
这篇关于如何使用create-react-app(不弹出)导入共享的打字稿代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!