react / react/metro

ESM TypeScript support in the metro-resolver

Open
#886 6 comments 0 reactions 1 assignee View on GitHub

@huntie is already working on this.

Since Nov 5, 2022.

Dominant language
JavaScript
Stars
5.6k
Forks
696
Avg merge
8m
Merged PRs (30d)
7

Description

Do you want to request a feature or report a bug?

Feature

What is the current behavior?

metro-resolver cannot resolve TypeScript imports that are in ESM format, e.g. have .js file extension in the import. It only adds extensions listed in sourceExts at the path, but does not consider situations where the original file extensions needs to be replaced.

What is the expected behavior?

metro-resolver should try to resolve TypeScript imports that are in ESM format. metro-resolver should try out the different file-extensions as it currently does, but in addition try out the file extensions also after removing the original file extension of the import. Example:

import {thing} from './something.js

Currently metro-resolver by default tries to resolve this as ./something.js, ./something.js.native, ./something.js.android.js, ./something.js.ts, ./something.js.android.ts, ... etc.

It should also try to resolve it as following: Currently metro-resolver by default tries to resolve this as ./something, ./something.native, ./something.android.js, ./something.ts, ./something.android.ts, ... etc. For my use case it should try to replace .js with .ts and .tsx, but there might be other use cases too.

Please provide your exact Metro configuration and mention your Metro, node, yarn/npm version and operating system.

Metro version: 0.67.0
Metro-resolver version: 0.67.0
Node version: 16.18.0
Yarn version: 1.22.4
Windows 11 and MacOS

// metro.config.js
const path = require('path');
const {getDefaultConfig} = require('metro-config');

module.exports = (async () => {
    const {
        resolver: { sourceExts, assetExts }
    } = await getDefaultConfig();

    return {
        projectRoot: path.resolve(__dirname, '.'),
        // watchFolders: [path.resolve(__dirname, './node_modules')],
        watchFolders: [
            path.resolve(__dirname, '../../node_modules'),
            path.resolve(__dirname, '../../packages/package1'),
            path.resolve(__dirname, '../../packages/package2'),
            path.resolve(__dirname, '../../packages/package3')
        ],
        resolver: {
            assetExts: assetExts.filter((ext) => ext !== 'svg'),
            // https://github.com/facebook/metro/issues/1#issuecomment-453450709
            extraNodeModules: new Proxy(
                {},
                {
                    get: (target, name) => path.join(process.cwd(), `node_modules/${name}`)
                }
            ),
            sourceExts: [...sourceExts, 'svg']
        },
        transformer: {
            babelTransformerPath: require.resolve('react-native-svg-transformer'),
            // eslint-disable-next-line require-await
            getTransformOptions: async () => ({
                transform: {
                    experimentalImportSupport: false,
                    inlineRequires: false
                }
            })
        }
    };
})();

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.