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

Node browser resolution strategy #7753

Closed
blakeembrey opened this issue Mar 31, 2016 · 11 comments
Closed

Node browser resolution strategy #7753

blakeembrey opened this issue Mar 31, 2016 · 11 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@blakeembrey
Copy link
Contributor

I'd like to propose a new resolution strategy that builds upon node resolution to support https://github.com/defunctzombie/package-browser-field-spec - node+browser. The core differences is that it reads package.json/browser to select the entry point or module "aliases". For example, browser can point to a string that is used in place of main when resolving or specific a map of keys to values - where the key is a relative path or a module name and the value is a boolean, relative path or module name.

This module resolution is used in Browserify by default, and can be enabled in Webpack using https://webpack.github.io/docs/configuration.html#resolve-packagealias. It's the primary way to develop and distribute universal packages that work on node and in browsers.

Edit: It would also be amazing to have the compiler handle this when developing packages so that the aliases are type-checked to be compatible in both environments. For example, it could catch serviejs/popsicle#47.

@DanielRosenwasser DanielRosenwasser added the Suggestion An idea for TypeScript label Apr 1, 2016
@ivogabe
Copy link
Contributor

ivogabe commented Apr 1, 2016

Wouldn't it be common that the node and browser version have the same types? Some implementations might differ, but API should behave the same.

@blakeembrey
Copy link
Contributor Author

blakeembrey commented Apr 1, 2016

Ideally, yes. That's the best way to implement universal packages. There's still enough difference if you need to do browser that there's probably some API differences - especially with environment features/APIs.

@PatrickJS
Copy link

+1
We need this for Universal Angular 2. Universal provides a ton of helpers for node in order to connect the two worlds (server/browser) in a seamless way. This involves writing similar types that have different dependencies depending on which environment you're currently in. Right now, if you use the browser version of universal you're presented with types that do not exist yet TypeScript is suggesting that it's valid

@blakeembrey
Copy link
Contributor Author

Starting to see it in some other universal projects (aside from my own), most notably the AWS SDK (aws/aws-sdk-js#1228).

@PatrickJS
Copy link

PatrickJS commented Nov 16, 2016

This is also a problem for Angular's use of Ahead of Time compiler which uses TypeScript's extensibility feature. When splitting code per platform there must be two paths created

angular2-universal/browser
angular2-universal/node

https://github.com/angular/universal-starter/blob/master/src/app/app.browser.module.ts#L3

@diestrin
Copy link

Nothing new here? I'm trying to make AoT working with package.json main/browser split and it's almost imposible.
I'm feeling tempted to write my own hack around here or even contribute if the team is willing to accept a PR

Maybe a tsconfig with the array of fields to lookup in order would be nice, if not provided TS can always use the defaults.

@PatrickJS
Copy link

sadly you have to create 3 code paths

import 'your-package' <-- universal interface
import 'your-package/browser' <-- browser interface
import 'your-package/server' <-- server interface

@blakeembrey
Copy link
Contributor Author

blakeembrey commented Jun 27, 2017

We just ran into this again with TypeDoc. We're using the Handlebars type definitions which relies on DOM typings, but none of the package runs in the browser so won't need DOM types.

@daprahamian
Copy link

👍 for this.

@eritbh
Copy link

eritbh commented Oct 9, 2021

I would also like to see this. I'm writing a library that has a slightly lighter API for the browser than for Node, and while the Node typings of my library are a strict superset of the browser typings in my specific case, I'm still concerned that consumers targeting browsers may infer an incorrect API based on being presented with Node types. (This would be a much bigger concern for libraries where the browser API is larger than the Node API, since browser consumers would be missing types for supported API features unless they manually remapped the library types themselves.)

Supporting the browser field would mean Typescript could automatically present the same view of a package's API that common bundlers use:

I've never contributed to Typescript before, but I think this is something I'd be willing to work on, if nobody else is already working on anything in this area. Is there anything I should know or anything about this feature we'd want to flesh out before starting?

@RyanCavanaugh
Copy link
Member

I can barely make sense of things written in the module landscape of 2016 anymore, but I think this effectively solved with us supporting custom conditions in package.json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

8 participants