简体   繁体   English

React/Typescript /VScode - 导入路径不能以“.tsx”扩展名结尾

[英]React/Typescript /VScode - an import path cannot end with a '.tsx' extension

I have a series of react projects which I have converted to typescript. Some of these use webpack, and some of them just use babel as they're libraries which are consumed by the other (webpack) projects/actual applications.我有一系列已转换为 typescript 的反应项目。其中一些使用 webpack,其中一些只使用 babel,因为它们是其他(webpack)项目/实际应用程序使用的库。

I've converted everything to typescript without problems, except in one non-webpack project, where I receive the error 'an import path cannot end with a.tsx extension', for example on我已经毫无问题地将所有内容转换为 typescript,除了在一个非 webpack 项目中,我收到错误消息“导入路径不能以 a.tsx 扩展名结尾”,例如

import LoadingLogo from '../ui/LoadingLogo.tsx';

I can get round this by omitting the extension, or using // @ts-ignore, but neither of these are optimal solutions, since the project will be a mix of jsx and tsx while it is being refactored and I'd like to be able to see at a glance which file type is being used in the import.我可以通过省略扩展名或使用 // @ts-ignore 来解决这个问题,但这都不是最佳解决方案,因为该项目在重构时将是 jsx 和 tsx 的混合体,我想成为能够一眼看出导入中使用的是哪种文件类型。

The steps I've taken to convert the project to typescript are我将项目转换为 typescript 的步骤是

  1. Install typescript安装 typescript
  2. Install @babel/preset-typescript安装@babel/preset-typescript
  3. add添加
presets: [ @babel/preset-typescript ]

to my babel.config.js到我的 babel.config.js

To make matters even more confusing, in one of the other (non-webpack) apps, I've got the same babel setup running and I'm not seeing this issue.更令人困惑的是,在其他(非 webpack)应用程序之一中,我运行了相同的 babel 设置,但我没有看到这个问题。 Is there something obvious I'm missing?有什么明显的我想念的吗? For reference, my babel.config in the project with the issue looks like this作为参考,我在有问题的项目中的 babel.config 看起来像这样

module.exports = function(api) {
  api.cache(true);

  return {
    ignore: ['node_modules/**/*'],
    presets: [
      ['@babel/preset-typescript'],
      [
        '@babel/preset-env',
        {
          loose: true,
          targets: {
            node: 'current'
          }
        }
      ],
      '@babel/preset-react'
    ],
    env: {
      translations: {
        plugins: [
          'syntax-async-functions',
          '@babel/plugin-syntax-dynamic-import',
          'dynamic-import-node',
          [
            'react-intl',
            {
              messagesDir: './messages',
              enforceDescriptions: false
            }
          ]
        ]
      },
      production: {
        plugins: [
          'jsx-strip-ext',
          [
            'babel-plugin-styled-components',
            {
              ssr: true
            }
          ],
          'syntax-async-functions',
          '@babel/plugin-syntax-dynamic-import',
          'dynamic-import-node'
        ]
      },
      development: {
        plugins: [
          [
            'babel-plugin-styled-components',
            {
              ssr: true
            }
          ],
          'syntax-async-functions',
          '@babel/plugin-syntax-dynamic-import',
          'dynamic-import-node'
        ]
      }
    },
    plugins: [
      '@babel/plugin-transform-runtime',
      '@babel/plugin-syntax-dynamic-import',
      '@babel/plugin-syntax-import-meta',
      '@babel/plugin-proposal-class-properties',
      '@babel/plugin-proposal-json-strings',
      '@babel/plugin-transform-classes'
    ]
  };
};

and my babel config in the non-webpack project without the issue looks like this我在没有问题的非 webpack 项目中的 babel 配置看起来像这样

module.exports = function(api) {
  api.cache(true);

  return {
    presets: ['@babel/preset-typescript'],
    ignore: ['node_modules/**/*'],
    extends: 'myProject/babel.config.js',
    env: {
      production: {
        plugins: [
          [
            'module-resolver',
            {
              alias: {
                '^myProject/src/(.+)': 'myProject/lib/\\1'
              },
              extensions: ['.js', '.jsx'],
              stripExtensions: ['.js', '.jsx']
            }
          ],
          [
            'babel-plugin-styled-components',
            {
              ssr: true
            }
          ],
          'syntax-async-functions',
          '@babel/plugin-syntax-dynamic-import',
          'dynamic-import-node'
        ]
      },
      development: {
        plugins: [
          [
            'babel-plugin-styled-components',
            {
              ssr: true
            }
          ],
          'syntax-async-functions',
          '@babel/plugin-syntax-dynamic-import',
          'dynamic-import-node'
        ]
      }
    }
  };
};

tsconfig.json for both projects looks like this两个项目的 tsconfig.json 看起来像这样

{
  "compilerOptions": {
    "module": "esnext",
    "outDir": "dist/",
    "noImplicitAny": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "sourceMap": true,
    "target": "ESNext",
    "allowJs": true,
    "checkJs": false,
    "jsx": "react",
    "pretty": true,
    "skipLibCheck": true,
    "strict": true,
    "moduleResolution": "node",
    "esModuleInterop": true,
    "lib": ["dom", "dom.iterable", "ESNext"],
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "isolatedModules": true
  },
  "include": ["src"],
  "exclude": ["node_modules", "**/*.spec.ts"]
}

My first instinct was to look at the module resolver plugin, but that didn't seem to make any difference.我的第一直觉是查看模块解析器插件,但这似乎没有任何区别。 Is there something obvious I'm missing?有什么明显的我想念的吗?

I'm sorry to say that I doubt you are going to be able to resolve this in the way you desire.很抱歉,我怀疑您是否能够按照您希望的方式解决此问题。 TypeScript (specifically TSC) disallows explicit extensions for ts/tsx files... It has to do with implicit file extensions in imports, and how ts/tsx files are compiled down to js/jsx files. TypeScript(特别是 TSC)不允许对 ts/tsx 文件进行显式扩展……这与导入中的隐式文件扩展名以及 ts/tsx 文件如何编译为 js/jsx 文件有关。 The world may not be happy about it , but it seems to be the way that it is.世界可能对此不满意,但它似乎就是这样。

You could use // @ts-ignore , but then I think you would lose intellisense你可以使用// @ts-ignore ,但我认为你会失去智能感知

Update : it has come to my attention from comments below that some TypeScript tools do allow extensions.更新:我从下面的评论中注意到一些 TypeScript 工具确实允许扩展。 Evidently Deno requires them, though I have not worked with Deno.显然 Deno 需要它们,尽管我没有与 Deno 合作过。 The TSC compiler disallows them. TSC 编译器不允许它们。

To solve your problem, you need:要解决您的问题,您需要:

  1. Make sure that you have a tsconfig.json file in the project.json with code确保你在项目中有一个tsconfig.json文件。json代码

{ "compilerOptions": { "target": "es5", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "strict": true, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx" }, "include": ["src"] }

  1. Check or create a react-app-env.in.ts file with the code使用代码检查或创建一个react-app-env.in.ts文件

/// <reference types="react-scripts" />

It is this react-app-env.d.ts file that explains TypeScript how to work with ts, tsx, and so on file extensions正是这个 react-app-env.d.ts 文件解释了 TypeScript 如何使用 ts、tsx 等文件扩展名

在此处输入图像描述

  1. Remove tsx file extensions in imports.删除导入中的 tsx 文件扩展名。 Also remove all extensions that TypeScript will swear at还要删除 TypeScript 发誓的所有扩展名

For example before:比如之前:

import { Header } from "./Header.tsx";

This should be the case after removing extensions:删除扩展后应该是这样的:

import { Header } from "./Header";

  1. If you had a project running at the time of these changes, stop it and start it again.如果在进行这些更改时您有一个项目正在运行,请将其停止并重新启动。 Since these changes are applied only when the project is started at the compilation stage由于这些更改仅在项目在编译阶段启动时应用

I added this to my webpack.config.js and it helped我将此添加到我的 webpack.config.js 中,它有所帮助

module.exports = {
  //...
  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
  },
};

You might want to add '...' to the end of the array so that it can resolve other extensions.您可能希望将'...'添加到数组的末尾,以便它可以解析其他扩展名。 More info about webpack's resolve extension here:https://webpack.js.org/configuration/resolve/#resolveextensions有关 webpack 的解析扩展的更多信息,请访问:https ://webpack.js.org/configuration/resolve/#resolveextensions

有时可以通过在根级别创建 next.config.js 和 tsconfig.json 并重新运行应用程序来解决此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM