在 TypeScript 项目之间共享代码(使用 React)?
这个问题:找不到模块"使用 TypeScript 3 Project References 时出错 有点帮助.
This question: "Cannot find module" error when using TypeScript 3 Project References was somewhat helpful.
这个也是:TypeScript 3 中的项目引用,带有单独的 `outDir`
但是我仍然无法使用 VSCode 和 React 有效地实现这一点.
But I am still having trouble getting this working efficiently with VSCode and React.
项目结构:
- 客户端/src
- 常见
- 服务器/src
常见的 tsconfig:
common tsconfig:
{
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"rootDir": ".",
"composite": true,
"outDir": "build"
},
"references": []
}
客户端 tsconfig:
client tsconfig:
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
},
"include": [
"src",
],
"references": [
{
"path": "../common"
}
]
}
服务器 tsconfig
server tsconfig
{
"compilerOptions": {
"target": "es6",
"lib": [
"dom",
"esnext"
],
"module": "commonjs",
"sourceMap": true,
"outDir": "build",
"allowJs": true,
"moduleResolution": "node",
"strict": true,
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"baseUrl": ".",
},
"include": [
"src/**/*"
],
"references": [
{
"path": "../common"
}
]
}
我在 client
中使用 create-react-app.这导致了编译问题.我相信我已经用 create-app-rewired
和 customize-cra
解决了这个问题,将它用于 config-overrides.js
I am using create-react-app in client
. This has caused compilation issues. I believe I have solved this with create-app-rewired
and customize-cra
using this for config-overrides.js
const { override, removeModuleScopePlugin, getBabelLoader } = require("customize-cra");
const path = require("path");
const addCommon = (config) => {
const loader = getBabelLoader(config, false);
const commonPath = path.normalize(path.join(process.cwd(), "../common")).replace(/\\/g, "\\");
loader.include = [loader.include, commonPath];
return config;
};
module.exports = override(
addCommon,
removeModuleScopePlugin(),
);
通常,我创建了一个文件 index.ts
,它从每个文件中导出代码.
In common, I have created a file index.ts
which exports code from every file.
export * from "./messages/toServer/AuthMessage";
例如.
在前端和后端,我可以用手写的导入语句导入代码(使用):
On the front-end and back-end, I can import code (to use) with a handwritten import statement:
import { AuthMessage } from "../../../common/build/messages/toServer/AuthMessage";
VSCode 没有给出任何建议,但它接受导入语句,假设代码已构建.
VSCode doesn't give any suggestions, but it accepts the import statement assuming the code is built.
我共同运行 tsc -b -w
.这似乎适用于手动导入.
I run tsc -b -w
in common. This seems to work with manual imports.
可能有:
- IntelliSense/auto-import 写入
AuthMessage
等类型时 - 导入的可用代码.我见过支持类型的示例,但代码不是从 common 生成的.未经测试,但我认为这适用于公共目录中的接口
- React 的可用性.一些相关的 jabber:https://github.com/facebook/create-react-app/issues/6799.ts-loader 支持项目引用,但我不确定 babel-loader 的状态,据我所知,它是 CRA 使用的加载器.我使用上面提供的代码得到了部分解决方案.
- IntelliSense / auto-import When writing types such as
AuthMessage
- Usable code that is imported. I have seen examples where types are supported, but code is not generated from common. Untested, but I imagine this works well for interfaces in a common directory
- Usability with React. Some relevant jabber: https://github.com/facebook/create-react-app/issues/6799. ts-loader supports project references, but I am unsure the status of babel-loader, which to the best of my knowledge, is the loader used by CRA. I got a partial solution with the code I provided above.
此处的指南:https://www.typescriptlang.org/docs/handbook/project-references.html#guidance 非常令人困惑.感谢您对此处解释的任何帮助.
Guidance here: https://www.typescriptlang.org/docs/handbook/project-references.html#guidance is very confusing. Any help with an explanation here is appreciated.
其他解决方案?
- 我不想发布和更新私有 NPM 模块.
- 使用 dsynchronize 等程序:http://dimio.altervista.org/eng/如果代码在两个项目中重复,但包含在两个项目的
src
中,可能会更容易.它不干净,如果程序正在运行,我可以看到重构和 IDE 尝试重新协商导入路径的一些灾难......
- I don't want to publish and update a private NPM module.
- Using a program such as dsynchronize: http://dimio.altervista.org/eng/ might be easier where code is duplicated across two projects, but included in the
src
of both projects. It's not clean, and I can see some disasters with refactoring and an IDE attempting to re-negotiate import paths if the program is running...
感谢任何帮助.
它似乎有效.我采取的步骤...
It appears to be working. The steps I took...
在项目目录中创建一个基本的 tsconfig.(这是记录在案)
Create a base tsconfig in the project directory. (This is documented)
{
"references": [
{
"path": "./common"
}
],
"files": []
}
将 "extends": "../tsconfig"
添加到两个子项目 tsconfigs.
Add "extends": "../tsconfig"
to both sub project tsconfigs.
从 common/src
中的所有文件中导出所有内容.(使用 /common/index.ts
)将导入路径更新到公共目录 import { ClassName } from "../../common"
(不是单个构建文件夹)
export everything from all the files in common/src
. (using /common/index.ts
)
Update import paths to the common directory import { ClassName } from "../../common"
(not individual build folders)
在非 React 项目中运行 tsc -b
进行编译.经过非常简单的初始测试,看起来我重新连接的 React 配置只是选择了对 common
的更改.config-overrides.js
是必需的.
Run tsc -b
in non-react projects for compilation. After very simple initial testing, it looks like my rewired react config just picks up changes to common
. The config-overrides.js
is a necessity.
这似乎在 VSCode 中有效,但是,经过测试,我同意自动导入在 WebStorm 中更胜一筹.
This does appear to work in VSCode, however, after testing, I agree auto-import is superior in WebStorm.
在common
中创建新文件时,必须在/common/index.ts
中导出,WebStorm自动导入会给你提示,VSCode有点不太明显.
When creating new files in common
, they must be exported in /common/index.ts
WebStorm auto import will give you a clue, VSCode is a little less obvious.