metro
metro copied to clipboard
ESM TypeScript support in the metro-resolver
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
}
})
}
};
})();