如何允许 CRA 中的命名空间?
How to allowNamespaces in CRA?
我使用以下方法创建了一个 TypeScript React 应用程序:
yarn create react-app my-app --template typescript
这样,我的项目就用Babel and then bundled by webpack. Now I want to use TypeScript namespaces, which aren't supported in Babel by default, but they can be enabled编译了。我安装了所有必要的软件包:
在 package.json
中我将 react-scripts start
更改为 react-app-rewired start
。
最后,我创建了一个 config-overrides.js
文件:
const {
override,
addExternalBabelPlugin
} = require("customize-cra");
module.exports = override(
addExternalBabelPlugin([
"@babel/plugin-transform-typescript",
{ allowNamespaces: true }
])
);
但是编译还是报语法错误,好像没有启用插件:
SyntaxError: /home/m93a/my-app/script.ts: Namespace not marked type-only declare. Non-declarative namespaces are only supported experimentally in Babel. To enable and review caveats see: https://babeljs.io/docs/en/babel-plugin-transform-typescript
如何正确设置我的项目,以便它甚至编译非声明性名称空间?
EDIT: 我的项目没有运行的原因实际上和我想的大不相同。查看我自己的答案以获取更多详细信息。
使用rescripts覆盖Babel配置
请按照以下步骤操作:
- 使用
create-react-app my-app --template=typescript
创建新应用或使用现有应用
- 安装 rescripts 和
npm i -D @rescripts/cli
- 用
package.json
中的 rescripts 替换 react-scripts 就像 rescripts docs
- 为 babel 配置安装 rescript 插件
@rescripts/rescript-use-babel-config
- 将此 snipper 添加到您的
package.json
文件
"rescripts": [
[
"use-babel-config",
{
"presets": [
"react-app",
[
"@babel/preset-typescript",
{
"allowNamespaces": true
}
]
]
}
]
]
Rescripts 将使用插件,这将扩展 babel 配置。我们扩展了默认的 react-app babel 配置,所以我们不会破坏任何东西。然后我们覆盖预设(已经由 react-app 安装),但是我们设置了 allowNamespaces
标志。
你必须使用 addBabelPlugin
instead of addExternalBabelPlugin
.
tl;博士
如果我们查看文档,我们会看到:
addExternalBabelPlugin(plugin)
create-react-app
actually has two rules in its webpack
config for babel-loader
: one for code in addSrc
(src/
by default) and the other for code external
to that folder (like node_modules
). You can add plugins to the external
loader using addExternalBabelPlugin
in the same way you'd use addBabelPlugin
.
如果我们检查 react-scripts/config/webpack.config.js
内部,我们可以看到这两个 babel-loader
条目:
在 webpack.config.js#L396
there is the babel-loader
for the include: paths.appSrc
and for \.(js|mjs|jsx|ts|tsx)$/
which addBabelPlugin
添加插件,注释为:
// Process application JS with Babel.
// The preset includes JSX, Flow, TypeScript, and some ESnext features.
在 webpack.config.js#L452
is the babel-loader
for /\.(js|mjs)$/
which addExternalBabelPlugin
添加插件,注释为:
// Process any JS outside of the app with Babel.
// Unlike the application JS, we only compile the standard ES features.
我们希望 @babel/plugin-transform-typescript
to apply to the first babel-loader
regarding application src
folder so we have to use addBabelPlugin
适用于 babel-loader
配置。
最后但同样重要的是,确保您已将 package.json
脚本从 react-app-rewired
:
更新为 运行
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
您可以使用来自此处命名空间的 class 检查一个非常简单的 CRA Typescript 项目:https://github.com/clytras/cra-ts-namespaces
在我的特殊情况下,即使我听从了其他人的建议,我也无法让它工作的原因如下:Babel 中有一个错误阻止它合并 enum
和namespace
。例如,这段代码是行不通的:
export enum Foo
{
a, b, c, d
}
export namespace Foo
{
export function bar()
{
return "bar"
}
}
但是由于一些奇怪的原因,Babel 在遇到这段代码时会抛出一个非常具有误导性的错误:
SyntaxError: script.ts: Namespace not marked type-only declare. Non-declarative namespaces are only supported experimentally in Babel. To enable and review caveats see: https://babeljs.io/docs/en/babel-plugin-transform-typescript
我提交了 an issue,所以希望这个错误能尽快得到修复,或者至少得到一个体面的错误消息。同时,可以使用一个变通方法:
export enum Foo_
{
a, b, c, d
}
export type Foo = Foo_
export namespace Foo
{
export const a = Foo_.a
export const b = Foo_.b
export const c = Foo_.c
export const d = Foo_.d
export function bar()
{
return "bar"
}
}
我使用以下方法创建了一个 TypeScript React 应用程序:
yarn create react-app my-app --template typescript
这样,我的项目就用Babel and then bundled by webpack. Now I want to use TypeScript namespaces, which aren't supported in Babel by default, but they can be enabled编译了。我安装了所有必要的软件包:
在 package.json
中我将 react-scripts start
更改为 react-app-rewired start
。
最后,我创建了一个 config-overrides.js
文件:
const {
override,
addExternalBabelPlugin
} = require("customize-cra");
module.exports = override(
addExternalBabelPlugin([
"@babel/plugin-transform-typescript",
{ allowNamespaces: true }
])
);
但是编译还是报语法错误,好像没有启用插件:
SyntaxError: /home/m93a/my-app/script.ts: Namespace not marked type-only declare. Non-declarative namespaces are only supported experimentally in Babel. To enable and review caveats see: https://babeljs.io/docs/en/babel-plugin-transform-typescript
如何正确设置我的项目,以便它甚至编译非声明性名称空间?
EDIT: 我的项目没有运行的原因实际上和我想的大不相同。查看我自己的答案以获取更多详细信息。
使用rescripts覆盖Babel配置 请按照以下步骤操作:
- 使用
create-react-app my-app --template=typescript
创建新应用或使用现有应用 - 安装 rescripts 和
npm i -D @rescripts/cli
- 用
package.json
中的 rescripts 替换 react-scripts 就像 rescripts docs - 为 babel 配置安装 rescript 插件
@rescripts/rescript-use-babel-config
- 将此 snipper 添加到您的
package.json
文件
"rescripts": [
[
"use-babel-config",
{
"presets": [
"react-app",
[
"@babel/preset-typescript",
{
"allowNamespaces": true
}
]
]
}
]
]
Rescripts 将使用插件,这将扩展 babel 配置。我们扩展了默认的 react-app babel 配置,所以我们不会破坏任何东西。然后我们覆盖预设(已经由 react-app 安装),但是我们设置了 allowNamespaces
标志。
你必须使用 addBabelPlugin
instead of addExternalBabelPlugin
.
tl;博士
如果我们查看文档,我们会看到:
addExternalBabelPlugin(plugin)
create-react-app
actually has two rules in itswebpack
config forbabel-loader
: one for code inaddSrc
(src/
by default) and the other for codeexternal
to that folder (likenode_modules
). You can add plugins to theexternal
loader usingaddExternalBabelPlugin
in the same way you'd useaddBabelPlugin
.
如果我们检查 react-scripts/config/webpack.config.js
内部,我们可以看到这两个 babel-loader
条目:
在
webpack.config.js#L396
there is thebabel-loader
for theinclude: paths.appSrc
and for\.(js|mjs|jsx|ts|tsx)$/
whichaddBabelPlugin
添加插件,注释为:// Process application JS with Babel. // The preset includes JSX, Flow, TypeScript, and some ESnext features.
在
webpack.config.js#L452
is thebabel-loader
for/\.(js|mjs)$/
whichaddExternalBabelPlugin
添加插件,注释为:// Process any JS outside of the app with Babel. // Unlike the application JS, we only compile the standard ES features.
我们希望 @babel/plugin-transform-typescript
to apply to the first babel-loader
regarding application src
folder so we have to use addBabelPlugin
适用于 babel-loader
配置。
最后但同样重要的是,确保您已将 package.json
脚本从 react-app-rewired
:
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
您可以使用来自此处命名空间的 class 检查一个非常简单的 CRA Typescript 项目:https://github.com/clytras/cra-ts-namespaces
在我的特殊情况下,即使我听从了其他人的建议,我也无法让它工作的原因如下:Babel 中有一个错误阻止它合并 enum
和namespace
。例如,这段代码是行不通的:
export enum Foo
{
a, b, c, d
}
export namespace Foo
{
export function bar()
{
return "bar"
}
}
但是由于一些奇怪的原因,Babel 在遇到这段代码时会抛出一个非常具有误导性的错误:
SyntaxError: script.ts: Namespace not marked type-only declare. Non-declarative namespaces are only supported experimentally in Babel. To enable and review caveats see: https://babeljs.io/docs/en/babel-plugin-transform-typescript
我提交了 an issue,所以希望这个错误能尽快得到修复,或者至少得到一个体面的错误消息。同时,可以使用一个变通方法:
export enum Foo_
{
a, b, c, d
}
export type Foo = Foo_
export namespace Foo
{
export const a = Foo_.a
export const b = Foo_.b
export const c = Foo_.c
export const d = Foo_.d
export function bar()
{
return "bar"
}
}