首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在CRA中实现allowNamespaces?

如何在CRA中实现allowNamespaces?
EN

Stack Overflow用户
提问于 2020-04-16 00:14:03
回答 3查看 3.5K关注 0票数 3

我创建了一个TypeScript React应用程序,它使用:

代码语言:javascript
复制
yarn create react-app my-app --template typescript

这样,我的项目是用巴贝尔编译的,然后由webpack捆绑。现在我想使用TypeScript 命名空间,默认情况下它在Babel中不受支持,但是它们是可以启用。我安装了所有必需的软件包:

package.json中,我将react-scripts start改为react-app-rewired start

最后,我创建了一个config-overrides.js文件:

代码语言:javascript
复制
const {
    override,
    addExternalBabelPlugin
  } = require("customize-cra");

module.exports = override(
    addExternalBabelPlugin([
        "@babel/plugin-transform-typescript",
        { allowNamespaces: true }
    ])
);

但是,编译仍然会引发语法错误,就好像没有启用插件一样:

SyntaxError: /home/m93a/my-app/script.ts:名称空间未标记为类型-仅声明。在Babel中,非声明性命名空间仅在实验上被支持。若要启用和检查注意事项,请参阅:https://babeljs.io/docs/en/babel-plugin-transform-typescript

如何正确设置项目,以便编译甚至非声明性命名空间?

编辑:我的项目没有工作的原因实际上与我想的完全不同。查看我自己的答案,以获得更多细节。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-04-20 22:08:21

您必须使用addBabelPlugin而不是addExternalBabelPlugin

tl;dr

如果我们检查这些文件,我们会看到:

addExternalBabelPlugin(plugin) create-react-appbabel-loader配置实际上有两条规则:一条用于addSrc中的代码(默认情况下为src/),另一条用于文件夹中的代码external (如node_modules)。您可以使用externaladdExternalBabelPlugin加载器添加插件,就像使用addBabelPlugin一样。

如果我们检查react-scripts/config/webpack.config.js内部,我们可以看到这两个babel-loader条目:

  1. webpack.config.js#L396中,有include: paths.appSrc\.(js|mjs|jsx|ts|tsx)$/babel-loaderaddBabelPlugin为其添加插件,并附有注释: //使用Babel处理应用程序JS。//预置包括JSX、Flow、TypeScript和一些ESnext特性。
  2. webpack.config.js#L452babel-loader for /\.(js|mjs)$/addExternalBabelPlugin为其添加插件,并附有注释: //使用Babel处理应用程序之外的任何JS。//与应用程序JS不同,我们只编译标准ES特性。

我们希望@babel/plugin-transform-typescript应用于关于应用程序src文件夹的第一个addBabelPlugin,因此我们必须使用应用于该babel-loader配置的addBabelPlugin

最后但并非最不重要的一点是,确保您已经更新了package.json脚本以从react-app-rewired运行。

代码语言:javascript
复制
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"

您可以在这里使用名称空间中的一个类检查一个非常简单的CRA类型记录项目:https://github.com/clytras/cra-ts-namespaces

票数 5
EN

Stack Overflow用户

发布于 2020-04-18 12:08:00

使用重新描述来覆盖Babel配置,因此遵循以下步骤:

  1. 使用create-react-app my-app --template=typescript创建新应用程序或使用现有应用程序
  2. 重写本安装npm i -D @rescripts/cli
  3. package.json中用rescripts替换-脚本,就像在重新编写文档中一样
  4. 安装babel config @rescripts/rescript-use-babel-config的rescript插件
  5. 将此片段添加到您的package.json文件中
代码语言:javascript
复制
"rescripts": [
    [
        "use-babel-config",
            {
                "presets": [
                    "react-app",
                    [
                        "@babel/preset-typescript",
                        {
                            "allowNamespaces": true
                        }
                    ]
                ]
            }
        ]
    ]

Rescript将使用插件,这将扩展babel配置。我们扩展默认的react app babel配置,这样我们就不会破坏任何东西。然后我们覆盖预置(已经由react安装),但是我们设置了allowNamespaces标志。

票数 1
EN

Stack Overflow用户

发布于 2020-04-21 23:03:31

在我的特殊情况下,即使我听从别人的建议,也无法使它正常工作,原因是: Babel中有一个bug,阻止它合并enumnamespace。例如,这段代码不起作用:

代码语言:javascript
复制
export enum Foo
{
    a, b, c, d
}

export namespace Foo
{
  export function bar()
  {
    return "bar"
  }
}

但是由于一些奇怪的原因,Babel在遇到以下代码时会抛出一个非常误导的错误:

SyntaxError: script.ts:名称空间未标记为只类型声明。在Babel中,非声明性命名空间仅在实验上被支持。若要启用和检查注意事项,请参阅:https://babeljs.io/docs/en/babel-plugin-transform-typescript

我提交了问题文件,所以希望这个bug能很快得到修复,或者至少得到一条不错的错误消息。在此期间,可以使用演练:

代码语言:javascript
复制
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"
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61240655

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档