-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Resolving multiple package.json "main" fields #21423
Comments
I think the monorepo scenario you have in mind is covered by #3469, but I think there's still room to discuss a The problem is that for every dependency that relies on that, the end consumer needs to cover each |
That's not going to work for many monorepos unless you can deal with circular dependencies somehow. It'd also mean that we'd have to duplicate the work of adding dependencies in our package.json and the tsconfig.json files. I'm also not sure how it'd work with our multiple build targets |
For providing intellisense, when no declarations are available, wouldn't it always be better to resolve to the source, if available, than to the compiled output and would that be true irrespective of the source being written in TypeScript? Even with Of course, it depends on the package, but when using say, "Go to Definition", it is very common to be taken to a UMD bundle and that is probably the least desirable result. Having said that, there are too many of these damn fields! Here is a totally non-exhaustive list of main fields that should be considered applicable
|
I have been hitting this issue in my Typescript/Webpack/Babel/React app (yes its a mix lol). Using the resolve.mainFields setting in webpack worked great with tree-shaking when writing a none-typescript app, as more and more libraries on NPM (including each of my own) are moving towards supporting the different entry points. I then moved back to Typescript I realised I lost all the benefits as I was stuck importing the full compiled library. I know the whole main/browser/module has been in flux for a while, especially with jsnext:main/es2015, but it seems to be solidifying around main/browser/module, with things such as unpkg being used for something very specific. Just my two pence obviously, to show there is a desire for this recommendation. This took 2 days of research just to find out I couldnt do the type of tree-shaking I can do relatively out of the box with webpack and JavaScript, meaning the mental energy used was actually working out the different behaviour in Typescript, rather than knowing about main fields. |
We have recently added support for building sourceMaps for declaration files, see #22658. We have also added support for tools to go through these declaration files and land on original sources. The net result here is you open a project, hit F12 on an imported declaration, and land in the source code for the referenced module. There are two main implications of loading of loading With the proposed solutions in #22658 and #3469, .d.ts files are still the main interface between projects, allowing for separate compilations and separate configurations. it also allows the tools to build logical boundaries between projects, and can independently jettison some of their state as needed to manage resource consumption. That said, this whole effort is just starting, we need to support other language service operations like find-all-references and rename on the mapped .d.ts files, we also need to find a way to keep these .d.ts files updated when the .ts files are updated to give the ideal experience. |
|
please add support for mainFields ... im trying to have vscode resolve to |
Has there been any progress on this issue? |
Oh! For now, I'm hacking. 😅 export default MyExport;
module.exports = exports.default; |
im also curious the progress on this |
Another alternative is for TypeScript to support source-maps and use the jsdoc annotation from the related source-locations. As has been mentioned before – often times an isomorphic libraries |
I am running into a similar issue. I have a package that has browser & node compatible versions in the dist directory. When I run my build, a version of the package is built for the browser (referencing dom/window etc) and a version is build for node.js The different versions (node vs browser) have different slightly different types. I have a "types" key set in the How can I get all files in my |
I hit the following issue which I think is related to this issue/proposal Quote from my Stackoverflow question Question: I used to have all shared modules to be precompiled into The problem that I've got tho, is that when I run
I added all sorts of glob patterns to My
Soultion: The only solution to this issue is to emit Maybe there is a way to filter files from being reported? Like TSWebpackForkPlugin does? E.g. |
The solution that worked for me is keeping both uncompiled and compiled files in the same folder ( TLDR: During development - all .js files are removed. During publishing - all .ts files are ignored. Here is the flow: For simplicity, let's consider our package has only one, I keep it in Than in package.json I pass During development - I have a script that clears all This makes typescript properly point to ts file. When releasing the package - I run build which will add In In 'production' - In |
Ideally, resolution configuration via both // package.json
{
"exports": {
"typings": {
"source": "./index.ts",
"default": "./index.d.ts"
},
"import": "./index.mjs",
"require": "./index.cjs",
}
}
// tsconfig.json
{
"compilerOptions": {
"resolveCustomConditions": ["source"],
"resolveMainFields": ["typings","module","main"]
}
} |
The X509Certificate class is now only used in the library where the compiler uses resolves the main entry to the correct js file. There is also another solution to fix the problem: delete the "browser" field in the x509 package.json (not really a clean solution...) Some links: https://webpack.js.org/configuration/entry-context/ microsoft/TypeScript#21423
I'm running into this issue. I've got a react-native app that I'd like to build with Obviously it would be better if react-native would not use non-standard fields for resolution but unfortunately that's just the way it is. |
Any solution to this? I'm also building a mono repo and want to be able to use intellisense without having to rebuild all of my sub repos each time. |
I shared some other suggestions for what this package.json convention might be in #51750 which I'm closing in favour of this long-lived issue. |
@jamiebuilds doesn't the use of an Also what problems have you encountered, if any, from distributing the |
I asked the question here if anyone can contribute... https://stackoverflow.com/questions/74688869/resolving-packages-directly-to-typescript-source-in-monorepo-package-json-files |
Have you managed to find a solution? |
I've been optimistic about https://www.typescriptlang.org/tsconfig#customConditions but that came too late for my own repository. I ended up 'leaning in' to the pattern that everything has to be built at all times, and adopting tooling to help with this. It's fully crazy complexity that I'd rather not have to manage and it's pointless (given all the source is Typescript) but there we are. Since restructuring the project to use |
I had similar issue and was able to solve it using Here is my {
"main": "src/index",
"publishConfig": {
"main": "dist/index",
"types": "dist/index"
}
} During local development, TS will us the When the package is published using {
"main": "dist/index",
"types": "dist/index"
} You will need to install yarn typescript plugin for the |
In pnpm this is also supported, but is ignored by npm :( |
Is there a conclusion to this question? |
My own conclusion was
I speculate that the original feature request (to have a unique resolution direct to typescript native files internally to monorepos) is directly fulfilled by the support for custom conditions. @jamiebuilds is that fair? |
TL;DR: A new compiler option
mainFields
for selecting multiple fields inpackage.json
instead of justpackage.json#main
.There are lots of related issues to this one (which I link to below), but I want to focus on just this specific proposal.
Packages often look like this:
Notice how we have multiple fields which specify multiple entry points. These entry points all refer to the same code, just in different compile states and configurations.
Many tools use these fields in order to find the entry point that they care about. For example, tools like Webpack and Rollup will use
package.json#module
in order to find ES modules. Other tools will use fields likepackage.json#source
(orsrc
) for local package development.While these fields aren't part of the official Node module resolution algorithm. They are a community convention which has proven to be useful in lots of scenarios.
For TypeScript, one such scenario that this would be useful for is with multi-package repos or "monorepos". These are repositories where the code for multiple npm packages exist and are symlinked together locally.
Inside each package, you'll generally have a
src/
directory that gets compiled todist/
Right now it is really painful to use TypeScript with one of these repos. This is because TypeScript will use the
package.json#main
to resolve to the packagesdist
folders. The problem with this is that thedist
folders might not exist and if they do exist they might not be compiled from the most recent version ofsrc
.To work around this today you can add a
index.ts
file in the root of each of your packages to point to the right location and make sure that the rootindex.ts
file does not get shipped to npm.It sucks that you need this file, and if you ever forget to create it in a new package, you'll revert back to really crap behavior.
If, instead of all that, TypeScript supported a new compiler option
mainFields
which looked like:You could add
package.json#source
(in addition topackage.json#main
) and resolve it to the right location locally.The algorithm would look like this:
For each
mainField
:package.json
has a field with that namemainField
mainField
I think this is the relevant code:
https://github.com/Microsoft/TypeScript/blob/b363f4f9cd6ef98f9451ccdcc7321d151195200b/src/compiler/moduleNameResolver.ts#L987-L1014
Related Issues:
.mjs
output #18442 "Support.mjs
output"The text was updated successfully, but these errors were encountered: