Typescript: Node browser resolution strategy

Created on 31 Mar 2016  ·  9Comments  ·  Source: microsoft/TypeScript

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 https://github.com/blakeembrey/popsicle/pull/47.

Awaiting More Feedback Suggestion

Most helpful comment

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

All 9 comments

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.

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.

+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

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

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

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.

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

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.

:+1: for this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dlaberge picture dlaberge  ·  3Comments

fwanicka picture fwanicka  ·  3Comments

zhuravlikjb picture zhuravlikjb  ·  3Comments

MartynasZilinskas picture MartynasZilinskas  ·  3Comments

uber5001 picture uber5001  ·  3Comments