Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

--moduleResolution minimal #50153

Closed

Conversation

andrewbranch
Copy link
Member

@andrewbranch andrewbranch commented Aug 2, 2022

--moduleResolution minimal is a new module resolution mode that only allows relative paths with file extensions in module specifiers. This means no node_modules, no dropping extensions, no special meaning for files named index.js. This mode is suitable (though incomplete, without support for HTTP imports and import maps) for browser-native ESM. It’s also the common denominator in resolution features between the browser, Node, Deno, and bundlers (they don’t agree on much, so not much is included here).

Importing from ./node_modules not allowed

I’ve decided to disallow relative imports into node_modules at least for now. The problem is that if you have

import * as Three from "./node_modules/three/src/Three.js";

it would be safe, correct, and useful for us to type that module by pulling types from ./node_modules/@types/three/src/Three.d.ts (which is not handled by any existing behavior—only sibling .d.ts files are looked up for relative imports). But it’s not clear that such a mapping is always correct or even possible. If a library uses typesVersions or exports, the types may be nested in a subfolder. If those options don’t include a wildcard mapping, then it’s impossible to import arbitrary files from the package in Node-style resolution, which makes any attempt to infer a mapping from an arbitrary relative import of an implementation file to its type definition in some other folder feel highly suspect and fragile. The more you think about it, the more it feels like looking at package.json files or trying @types violates the expectations for relative imports and one of the core assumptions of this resolution mode: that node_modules isn’t special.

We could decide to truly give node_modules no special behavior, perhaps with the one concession that (non-type-only) imports from node_modules/@types are not allowed. For now I’ve chosen not to block resolution, but to issue an error in the checker when a relative import includes /node_modules/ in its module specifier. This keeps options open for us in the future.

Folks using this for the browser probably will need a way to specify typings for their vendored dependencies, which I assume they will drop in a folder not called node_modules. #50600 tracks this feature request (and it need not be specific to --moduleResolution minimal).

Importing "*.ts" allowed

Also included is a new compiler option allowImportingTsExtensions, which can be enabled only in --moduleResolution minimal (though the planned --moduleResolution hybrid will support it as well) and when --noEmit or --emitDeclarationOnly is set. When these conditions are met, imports will be allowed to use the extension of the target input file (.ts, .tsx, .mts) rather than the output extension (.js, .mjs). Additionally, type-only imports under these options are allowed to use a .d.ts suffix when resolving to a .d.ts file. To help with portability, declaration files themselves are not subject to the --allowImportingTsExtensions and --noEmit requirements.

// ok as long as
// - `moduleResolution` is `minimal`
// - `allowImportingTsExtensions` is set
// - `noEmit` or `emitDeclarationOnly` is set
// - the specified files exist
import {} from "./a.ts"
import type {} from "./types.d.ts"

URL handling not implemented yet

One thing that’s missing here is URL decoding. However, this is also missing from node16 and nodenext in ESM mode, and I think it would be a lot of noise to introduce it here in the same PR. I’d like to do that in a follow-up PR.

Part of #50152
Closes #11979

@typescript-bot typescript-bot added Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels Sep 26, 2022
@andrewbranch andrewbranch marked this pull request as ready for review September 27, 2022 17:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

module_resolution=none or =explicit
2 participants