-
Notifications
You must be signed in to change notification settings - Fork 12.4k
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
Supports exports
pointing to a TypeScript file, which keeps consistent with main
#48369
Comments
ESM/packages support in TS is not shipping yet, but it's hopefully gonna ship in TypeScript 4.7. You can try it out by using In this specific case you might be wanting to use (based on the handbook description) the following to specify types: {
"exports": {
".": {
"types": "./src/index.ts"
}
}
} |
Thanks for providing the information! To clarify a little, I think the key point of this issue is consistency, because the IntelliSense works when the |
Currently TypeScript doesn't actually officially support importing modules with a The current advice in the handbook is for packages to use My guess is you're either wanting this behaviour for either usage in Deno or in something like |
@weswigham thoughts? |
Uhh, I mean, I guess it should work, given how our resolution historically proceeds, and currently doesn't. Workaround for now is just to say Fix is pretty simple for us - in |
Like, this is probably the change we'd need to make to support this, I suppose. |
Is this a possible foot-gun though? Is there a reason why this behavior is desirable? |
Just my 2 cents, but if you want to provide TS files as the entry point, just use |
{
"exports": {
"./subname": "./src/libs/subname-impl.ts"
}
} would presumably be supported as well. Although there is the question as to whether actually supporting this is a good idea or not, like the fact In either case, it would probably be worth making it so that resolution in node12/nodenext is at least consistent for both Existing resolution probably relies on it in places, so removing support there would probably not be a non-breaking change. Such places going forward though probably won't be able to rely on it with |
Same error over here. I actually cannot get anything to do with exports working with 4.7.0-beta. I have tried all iterations:
However main works fine. Has anyone got an example of the new PS. When importing I am using symlinked packages in |
@vjpr I got this to work rather easily as seen here: https://github.com/milesj/packemon/pull/122/files If you look at my test file here https://github.com/milesj/packemon/blob/master/tests/testPackemonImports.ts, you'll see that I'm importing from Be sure your It also depends on how you're trying to load the package and from what context/tool. |
@milesj Try removing the |
@milesj Your package is also set to |
After debugging the source code I now understand the issue better which is just as weswigham said:
Just to make it clear for anyone else: TypeScript/src/compiler/moduleNameResolver.ts Lines 1505 to 1525 in 3d3fa0c
The fix is just to remove Confusing:
|
else if (typeof target === "object" && target !== null) { // eslint-disable-line no-null/no-null | |
if (!Array.isArray(target)) { | |
for (const key of getOwnKeys(target as MapLike<unknown>)) { | |
if (key === "default" || state.conditions.indexOf(key) >= 0 || isApplicableVersionedTypesKey(state.conditions, key)) { | |
const subTarget = (target as MapLike<unknown>)[key]; | |
const result = loadModuleFromTargetImportOrExport(subTarget, subpath, pattern); | |
if (result) { | |
return result; | |
} | |
} | |
} | |
return undefined; | |
} | |
else { | |
if (!length(target)) { | |
if (state.traceEnabled) { | |
trace(state.host, Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName); | |
} | |
return toSearchResult(/*value*/ undefined); | |
} | |
for (const elem of target) { | |
const result = loadModuleFromTargetImportOrExport(elem, subpath, pattern); | |
if (result) { | |
return result; | |
} | |
} | |
} | |
} |
- Walks through keys in the export object in order.
- If key is 'default', uses that.
- If key is in
state.conditions
, uses that.conditions
can only be:- For EsmMode,
[node, import, types]
- For CommonJS,
[node, require, types]
- Also, conditions can vary per-package depending on the file format.
- For EsmMode,
- If there is a matching versioned types key (e.g.
{exports: {'./': {'types@4.7.0-beta': './lib/index.d.ts'
}}}`, use that.
Summary
For now, you will always need to add a special types
condition key pointing to a ts
file with the extension changed to js
.
Also note the need to include the '.js' extension in wildcards for types
...
{
"exports": {
".": {
"node": "./lib/index.js",
"types": "./src/index.js" <-- Even though the real file is `index.ts`.
},
"./shared/*": {
"browser": "./src/shared/*",
"types": "./src/shared/*"
}
}
}
Also note for webpack you need to use a plugin (https://github.com/softwareventures/resolve-typescript-plugin) that will try to resolve .js
files to .ts
.
All this should be documented better...
While digging deeper into my initial complain around nothing validating that TypeScript was importing `.js` files with an extension, I eventually came across this very helpful comment on a thread in the TypeScript issues: microsoft/TypeScript#48369 (comment) After setting the `moduleResolution` to `nodenext`, suddenly _exactly_ what I expected happens! - If no extension is provided at all, TypeScript fails to compile - If you accidentally provide the `.ts` extension, as you may be inclined to attempt, TypeScript fails to compile Vitest will allow you to run your tests without extensions in your imports, but a `tsc` pass on the files (from your editor's language server, perhaps) will complain
Bug Report
In some cases, we want to import from the source code instead of the compiled, which is perfectly implemented by the
main
field:While it seems not to work at the newly introduced
exports
field🔎 Search Terms
#46452
#48084
🕗 Version & Regression Information
⏯ Playground Link
This is about the package.json behavior, and the playground seems can't reproduce it.
💻 Code
🙁 Actual behavior
It would show a
ts2037
error message:🙂 Expected behavior
Works correctly, just like the
main
field's behavior.The text was updated successfully, but these errors were encountered: