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

拟墨画扇 提交于 2020-06-27 12:36:56

问题


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.

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

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.

The steps I've taken to convert the project to typescript are

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

to my 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. Is there something obvious I'm missing? For reference, my babel.config in the project with the issue looks like this

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

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

{
  "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?


回答1:


I'm sorry to say that I doubt you are going to be able to resolve this in the way you desire. TypeScript 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. 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



来源:https://stackoverflow.com/questions/59756485/react-typescript-vscode-an-import-path-cannot-end-with-a-tsx-extension

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!