当前位置: 首页 > 知识库问答 >
问题:

如何使用create react app(无弹出)导入共享类型脚本代码?

堵彬彬
2023-03-14

我试图在非弹出模式下的create react应用程序中实现TypeScript代码共享,但我遇到了一个臭名昭著的限制,即不允许在src之外导入:

您试图导入项目src/目录之外的.../.../public/src/lib.ts。[...]

对于非TypeScript的情况,已经问过这个问题

>

基于react应用重新布线的方法:更有前景。禁用ModuleScopePlugin可以让我通过“试图在src之外导入”错误,但现在的问题是,typescript文件的加载程序无法正常运行:

我已经验证了。ts本身没有问题:复制到/src并从那里导入它很好。

我还添加了。//公共/src文件夹,位于配置中的包含列表中。json

我的猜测是,不知何故,网页包加载器配置有一条规则,防止TypeScript加载器传输与其预期路径模式不匹配的文件。如何使用react应用程序重新布线修复此问题?

符号链接源也不起作用——同样存在同样的问题。可能是因为webpack在内部解析符号链接,并在普通加载程序规则不适用的路径中查看文件。

基于弹出的解决方案:我现在不想弹出,但我试过了,我基本上又遇到了同样的问题。

我还发现了其他听起来相关但没有回答问题的问题:

  • 在monorepo代码共享中创建React应用程序类型脚本:听起来基本上是同一个问题,但事实并非如此,因为它要求的是弹出的React应用程序的情况
  • 使用TypeScript和webpack在项目之间共享代码:也解决了代码共享问题,但不是特定于create react app,我不知道该解决方案是否可以转移到create react app,因为它需要手动webpack配置控制

在mono repo中重用TypeScript类型似乎是一种相当合理的模式。我是否遗漏了什么,或者为什么create-react-app使这变得如此困难?

复制:我的代码基本上是您从中获得的100%

npx create-react-app my-app --template typescript

将一个导入添加到外部。


共有3个答案

尹英华
2023-03-14
匿名用户

craco或重新布线的create react app的别名解决方案是系统的react app别名:craco、react app rewired、customize cra

根据上述系统的文档替换package.json中的react-script并配置下一步:

// config-overrides.js
const {aliasWebpack, aliasJest} = require('react-app-alias')

const options = {} // default is empty for most cases

module.exports = aliasWebpack(options)
module.exports.jest = aliasJest(options)
// craco.config.js
const {CracoAliasPlugin} = require('react-app-alias')

module.exports = {
  plugins: [
    {
      plugin: CracoAliasPlugin,
      options: {}
    }
  ]
}

在json中配置别名,如下所示:

// tsconfig.paths.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "example/*": ["example/src/*"],
      "@library/*": ["library/src/*"]
    }
  }
}

并将此文件添加到主类型脚本配置文件的扩展部分:

// tsconfig.json
{
  "extends": "./tsconfig.paths.json",
  // ...
}

咸浩初
2023-03-14

更新:由于react-app-rewire只是被动维护,不支持CRA版本2(在撰写本文时我们是三个主要版本),因此我不再推荐这种方法。

在对GitHub问题进行了更多的实验和阅读之后,我终于找到了一个有效的解决方案。非常感谢BirukDmitry在GitHub上发表了这篇非常有用的帖子。逐步指南:

>

  • 安装react应用程序重新布线并定制cra

     npm i react-app-rewired customize-cra --save-dev
    

    使用最小的配置覆盖配置react app Reward。js像这样:

    const { removeModuleScopePlugin, override, babelInclude } = require("customize-cra");
    const path = require("path");
    
    module.exports = override(
      removeModuleScopePlugin(),        // (1)
      babelInclude([
        path.resolve("src"),
        path.resolve("../common/src"),  // (2)
      ])
    );
    

    设置(1)与一般情况下绕过src限制之外的导入所需的类似(参见链接问题)。

    尽管设置(2)对其他路径启用巴别塔透明(因此,我认为包括TS型剥离)至关重要。在这里,您必须添加要导入的路径。

    tsconfig无需进行任何修改。json

    使用相对路径导入,例如,从'.../.../public/src/mymodor'导入*作为mymodor。

  • 蔺弘
    2023-03-14

    您可以使用craco(创建react应用程序配置覆盖)覆盖网页包配置(抽象为CRA的一部分),而无需弹出
    此外,您还可以使用ts loader在外部项目中直接引用未传输的ts代码(例如,如果您希望在mono repo中引用/使用共享代码/lib)。

    假设您的CRA应用程序位于客户端目录下,您的项目结构如下所示:

    client/
    |--src/
    |--package.json
    shared/
    |--package.json
    |--(ts files)
    package.json
    
    cd client
    yarn add -D @craco/craco ts-loader
    
    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;
        }
      }
    };
    
    /* 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"
    }
    
     类似资料:
    • 我试图在我的主文件。 entry.ts位于src/js/entry, ts,vue的类型定义位于src/js/lib/baul/vue/type/index.d.ts 编译此文件时,输出如下。顺便说一句,typescript的目标是es6和es6模块。 JQuery工作正常(看起来像),所以我用导入替换了对vue类型定义的引用。 它编译得很好,下面是输出: 问题是没有删除类型定义的import语句

    • hybris6.3.0.2 我创建了一个AfterSaveListener,它在保存项目后执行一些自定义逻辑。 *AfterSaveListener- 创建了一个新的项目类型“AttributeFormat”,我正在根据它更新产品特征数据。 如果我从后台更新或创建属性格式,此侦听器可以正常工作,但当通过Impx导入数据时,它不能按预期工作。 弹劾- 当我导入这个Impex时,调用将转到AfterS

    • 问题内容: 我使用Windows Host上的RVDS编译器使用目标代码文件(C源代码)创建了一个共享库()。 我将此共享库与一个应用程序链接(用于Linux主机上的ARM目标)并获得一个可执行文件,该可执行文件在运行时会产生分段错误。(我知道我必须调试它!) 如果不创建共享库,而是创建具有相同源文件的静态库,然后与该应用程序链接,然后执行该应用程序,则可以正常运行。 所以我的问题是: 我是否需要

    • 问题内容: 我被要求使用php脚本而不是phpmyadmin创建一个将其结构和数据导出并导入mysql数据库的.sql文件,以使用户能够备份其数据? 有人知道该怎么做吗? 提前致谢 问题答案: http://www.php-mysql-tutorial.com/wikis/mysql-tutorials/using-php-to-backup- mysql-databases.aspx 要么 要么

    • 对于上面的导入语句,我想知道协议如何知道在哪里可以找到该原型文件,因为它显然不在我的的某个地方。 我有一个共享的。proto在某些包中,可以被许多项目引用,因此我无法将其放在某个项目级别以共享相同的protp\u路径。我的问题是如何像导入