Closed guybedford closed 8 years ago
A little bit of background on TypeScript typings - originally .d.ts files were included using /// reference path="./typings/angular.d.ts"
comments in the source files which needed them. These ambient declaration files contain module definitions like this:
declare module "angular" {
function bootstrap(modules: Module[]);
}
When you do import angular from "angular"
TypeScript then finds the "angular' module declaration and uses that for type-checking. This is quite straightforward for the plugin as it knows all the files which it needs to load to type-check a source file.
Recently there has been change so that you can deliver external declaration files, these are a little different to the one above because the file itself is the module, so the one above would look like:
export function bootstrap(modules: Module[]);
and when you do import angular from "angular"
TypeScript will see that the "angular" package has a typings file and use that when type-checking the file. So how does it know whether the angular package has a typings file? Well the algorithm goes something like:
a) Look in package.json for "typings" field. If found use that. b) Resolve the imported .js file using node.js resolution and see if there is a .d.ts file of the same name
Rule (b) also applies when doing import router from "angular/router"
. The exact algorithm is described here
So this is the difficulty when loading tin the browser, because the plugin doesn't know which packages have typings files. SystemJS resolution can't be used because that needs to resolve to the .js file.
Angular2 delivers multiple typings files in the npm package and this makes it impossible to type-check in the browser unless you switch back to using one of the old-style ambient declaration files. Solving the angular2 problem ought to be the priority here I think.
If jspm could record any .d.ts files it finds when installing packages so that they were available somewhere in the runtime config then that might work, could jspm-npm do that? Otherwise the typings project may be able to provide this information but its not quite clear how that is going to pan out right now.
I hope this is clearer and we can find a way forward.
edit: updated the terminology to be in line with the rest of the thread.
bit more info for background - there are two types of typings files now - "ambient" and "external" - angular2 uses the externals (they are basically es6 modules, more or less) and effectively its a reasonable guarantee that there's 1 .d.ts
file per .js
file - this is how typescript outputs them.
its unlikely we'll switch back to the old style (ambient) any time soon / ever, and ideally we'd like to not have to tell consumers of NG2 to do the same.
the typings project is for ambient modules only (afaik) and thus we won't be delivering the typings to it's registry for angular2.
@guybedford @frankwallis happy to have a pow-wow if you guys want to work through this.
see also https://github.com/Microsoft/TypeScript/issues/6012 - and as of TS 1.8 there's a new (configurable) resolution strategy which is ~mostly JSPM style.
@robwormald yes maybe I am using wrong terminology so the first example above is "ambient" and the second one "external".
In the angular2 case, then, a simple boolean flag to say the package does have external typings would be enough. The plugin would always resolve and fetch external typings for files inside that package. That flag could go in:
typings: true
(probably illegal)So to account for most common scenarios, jspm could retrieve the value of typings
from package,json and make it available to the plugin in runtime configuration. This field (or some other flag) would also be settable in the jspm registry and setting it to true
would mean resolve external typings for all modules. Does this sound possible?
@robwormald I don't think I am able to use the new algorithm in the browser, because it needs to search for files. It solves the issue of missing intellisense and being able to use tsc with jspm and external typings though, which is progress.
@frankwallis let me see what we can do about your first question, we should be able to make one of those options work.
The second though - assuming you know that there are typings, no search should be needed, as they are 1 to 1 for the actual source files. (that is, foo.ts becomes foo.js and foo.d.ts on npm) - or am i misunderstanding you?
@robwormald thanks, I'm really keen to get this working.
I need to have a look at the how this new paths
compiler option is implemented and how it interacts with moduleResolution: node
, but yes I suppose my point is more about implementing moduleResolution: node
without doing nodejs file-system calls.
@frankwallis @robwormald thanks for the clear descriptions here. It does sound like Angular would be the nice case to crack here to set the precedent.
@robwormald did you say we really can assume the convention then that the typing file for a fully-resolved .../full/path/to/module.js
is located at .../full/path/to/module.d.ts
? Or would such a convention have edge case limitations when scaling over npm?
@ximenean as I understand it the aim of the typings project is to allow ambient modules to co-exist with external modules until everything has been moved to external modules. It's all rather confusing though...
Some new docs have just arrived on the subject: https://github.com/typings/typings/blob/master/docs/how-typings-makes-external-modules-first-class.md
@guybedford that is only true for the angular2 package.
As an example of another sort of package angular/zone.js
contains a typings
field in package.json (https://github.com/angular/zone.js/blob/master/package.json#L6)
{
"name": "zone.js",
"version": "0.5.13",
"description": "Zones for JavaScript",
"main": "build/lib/zone.js",
"typings": "build/lib/core.d.ts",
This file (build/lib/core.d.ts) will contain bundled typings for the whole package.
@frankwallis as far as I can tell zone.js
does use the same convention within in its file structure. It does seem a very sensible convention that would be easily compatible with SystemJS if this is the way things are moving.
@guybedford yes and in fact the core.d.ts typings
entry in package.json looks incorrect to me, it should point to zone.d.ts. Another example is RxJS, which in 5.0.0-beta also follows the same convention.
I think it is quite likely that packages which are developed in TypeScript will follow this convention, but packages which are developed in JavaScript may choose to have a single bundled typings file.
I have managed to get the angular2 example type-checking by telling the plugin which packages have typings files, the configuration looks like this currently:
typingsMap: {
angular2: true,
rxjs: true
}
This works because all imports from these packages specify the module name to be imported (ie import {bootstrap} from "angular2/boostrap"
. I don't know how to find out the main
of a package within SystemJS, so import {bootstrap} from "angular2"
would not currently work.
In jspm 0.17, the main entry point problem here goes away because the main is resolved as part of the normalize step instead of fetched through a pointer module. In cases where you don't have a true value for the typingsMap, perhaps you can just infer from the fact that the plugin fetch hook is being called for a source and load the typing file in parallel at that point (even if it is a 404)?
@guybedford that's good news about the main entry point issue in 0.17, and I was hoping you would say that! Unfortunately I don't think the plugin fetch hook will always be called in this situation, as the actual file will resolve to a .js file, but TBH I don't think it's a big deal if it can't be fully supported until 0.17, as long as angular2 works.
What are your thoughts about putting this configuration into the package config? I am happy to do a PR if you point me in the right direction.
I would propose that:
typings
field would be loaded package.json when availbleDoes this sound ok?
@frankwallis I'd strongly suggest moving on the 0.17 upgrade path and encouraging users here to as well. I would have published it as stable already, but am going slowly on the stable branch rather to give users time, but individual projects should push forward.
The only way to handle a custom field through the package configuration is through meta exactly as in https://github.com/frankwallis/plugin-typescript/issues/96 -
{
"meta": {
"*.ts": {
"loader": "typescript",
"typescriptOptions": {
"typings": {...}
}
}
}
}
Would you still consider that if a TypeScript file is run through the fetch hook, the loader would request the typing by default? If the fetch hook is not run for that specific file (eg for 0.16 mains), then a field like this makes sense certainly. It could potentially also act as an opt-out for the automatic typing loading if that is implemented.
My biggest concern is what normalization space this field is acting in? Multiple plain names can refer to the same module, so you'd need to run that name through System.normalizeSync
or System.decanonicalize
to get into URL space for name comparison (the only space in which comparison is unique). normalizeSync probably gives the most naming flexibility handling all the many-to-one options.
The other thing is even if using normalizeSync, it should probably be a contextual normalization as well to get all the contextual package maps. It's not completely clear though which contextual parent is intended for such an unnormalized typing (with System.normalizeSync(typingName, whichParentName?)
)
If it's a typescript file we don't need any typings, the typings files are only needed for packages delivered as .js files.
The plugin needs to know:
a) the value of the typings
field in package.json if there is one
b) a flag to tell it that a package provides typings files alongside all of its js files
So the typings
field in package config would either be a string for situation (a) or true for situation (b). The plugin handles all the normalization stuff already I think.
I have put in the typingsMap
field into typescriptOptions so that I could see if this was going to work, but it is really meant as a stopgap until this configuration can come from the packages themselves.
Ahh, right, thanks for bearing with - sorry it's my distance from these workflows showing in these simple errors. I'm really so grateful you are working all of this out!
So the '.js' file has matching '.d.ts' typings usually when it was compiled from TypeScript as separate files then? And thats what Angular and Rxjs do? Is there any indication in the source code of those .js
files that these typings files exist? You mentioned the comment method previously?
Would a TypeScript package ever have a typings field for its dependencies? Or is the point here that we associate all typings through overrides to the underlying files?
So in jspm 0.17 "meta" can be provided as a field in the package.json (along with all other SystemJS package config options). The code example in my previous comment could be the package.json file itself or the override.
Thinking further, could you not just do something like:
{
"meta": {
"*.js": {
typings: true
}
}
}
So that we use the individual metadata per-module to indicate which files have associated typings?
might be better with "external" vs "ambient" to denote parallel typings (external)?
hey no problem, I just want to make sure we get to the right place.
So, yes, angular2 and rxjs provide .d.ts files alongside their .js files, but there is no way to figure this out without looking at the files which are in the package.
Some other packages can populate a typings
field in package.json which will point to a single .d.ts fie which corresponds to their main file. It remains to be seen how much this will be used.
I'm not quite clear on your question, but I think the answer is that a TypeScript package would not have typings for it's dependencies - the plugin should automatically locate those typings in the dependency package if they exist, and feed them into the compiler. This is why it is important for the plugin to know what typings are present.
Providing this information in the meta might work, if I can access it at the right time. As an example:
somefile.ts:
import {boostrap} from "angular/bootstrap"
...
At this point I normalize "angular/bootstrap" -> "http://jspm_packages/.../bootstrap.js" and I then need to get the meta for that file. I'm not quite sure how to do that?
I will have a play around with this and report back. If it works then I think we will have a solution as this meta can be added into the jspm registry presumably, or put in the angular2 package.json file?
There's a hack that can be used to get the metadata for a package, but it won't work in future versions when the locate hook is deprecated. We can make sure the use case sticks around somehow though.
Basically you can do:
var metadata = {};
System.locate({ name: 'http://jspm_packages/.../bootstrap.js', metadata: metadata })
.then(function(address) {
// metadata.typings, metadata.typescriptOptions etc should all now be populated correctly,
// respecting the composition of all global metadata, wildcard metadata and package metadata correctly
});
Yes meta can be in the original package.json or the jspm registry. I hate to be introducing "another" way of doing this stuff, but we do just need to let these metadata conventions all fight it out in the wild for a bit I think.
ok I'll give that a try and report back. I also think that this stuff is likely to change on the typescript side (see https://github.com/Microsoft/TypeScript/issues/6950 for example), so I agree it's good not to be over committed at this time.
@robwormald I don't understand - can you clarify?
I have added support for specifying typings
configuration in metadata and it is released in 4.0.0. The angular2 project now type-checks as I have added packages
configuration here:
"angular2": {
"meta": {
"*.js": {
"typings": true
}
}
},
"rxjs": {
"meta": {
"*.js": {
"typings": true
}
}
}
Would it be possible to add this meta information to the packages overrides in the jspm registry? So that the consumer of the library doesn't have to set this in his jspm.config.js
.
@frederikschubert yes that is the plan, I just need to get it working with a manual override first to verify.
Awesome! Please keep me posted if you hit any further issues with this approach.
@guybedford thanks, I now want to add the packages configuration above into the jspm registry. It is using wildcards as metadata keys to match all the js files in the package - is it ok to use wildcards for metadata in the registry because I don't think they work for overrides?
@frankwallis yes this is perfectly fine and the way things are going. A "meta" property in overrides and the registry is supported, but only in jspm 0.17.
@frankwallis I just tried to use the config you have in the examples for angular2. I am using reflect-metadata
and when I use the following config:
SystemJS.config({
transpiler: "ts",
typescriptOptions: {
"typeCheck": true,
"tsconfig": true
},
packages: {
"src": {
"defaultExtension": "ts",
"meta": {
"*.ts": {
"loader": "ts"
}
}
},
"npm:reflect-metadata@0.1.3": {
"meta": {
"*.js": {
"typings": true
}
}
},
"npm:rxjs@5.0.0-beta.2": {
"meta": {
"*.js": {
"typings": true
}
}
}
}
});
It fails to load Reflect.d.ts
. I am using karma-jspm and this plugin for running tests on .ts
files and I get the following:
Chrome 49.0.2623 (Mac OS X 10.11.3) ERROR: 'TypeScript', Error{originalErr: Error{}}
Chrome 49.0.2623 (Mac OS X 10.11.3) ERROR: 'Potentially unhandled rejection [4] Error: XHR error (404 Not Found) loading http://localhost:9876/jspm_packages/npm/reflect-metadata@0.1.3/Reflect.d.ts
Error loading http://localhost:9876/jspm_packages/npm/reflect-metadata@0.1.3/Reflect.d.ts!http://localhost:9876/jspm_packages/github/frankwallis/plugin-typescript@4.0.2/plugin.js'
I am not sure why it tries to load that file, maybe because when import 'reflect-metadata';
it actually loads Reflect.js
?
I can also see that there is a Reflect.ts
which contains typing definitions, maybe it's a mistake on their behalf and should have been Reflect.d.ts
?
By setting typings: true
the plugin will try to load typings for all js files with the same name as the js file but with a .d.ts extension. To load typings from a different file, specify the filename of the typings file, so I think the config should be:
"npm:reflect-metadata@0.1.3": {
"meta": {
"Reflect.js": {
"typings": "typings.d.ts"
}
}
},
That gives me:
Chrome 49.0.2623 (Mac OS X 10.11.3) ERROR: 'TypeScript', Error{originalErr: Error{}}
Chrome 49.0.2623 (Mac OS X 10.11.3) ERROR: 'Potentially unhandled rejection [4] Error: http://localhost:9876/jspm_packages/npm/reflect-metadata@0.1.3/typings.d.ts!http://localhost:9876/jspm_packages/github/frankwallis/plugin-typescript@4.0.2/plugin.js detected as esm but didn't execute.
at tryCatchReject (http://localhost:9876/base/jspm_packages/system-polyfills.src.js?3aa57969dce4ecea4c51aab540f372d15cc886b6:1252:30)
at runContinuation1 (http://localhost:9876/base/jspm_packages/system-polyfills.src.js?3aa57969dce4ecea4c51aab540f372d15cc886b6:1211:4)
at Fulfilled.when (http://localhost:9876/base/jspm_packages/system-polyfills.src.js?3aa57969dce4ecea4c51aab540f372d15cc886b6:999:4)
at Pending.run (http://localhost:9876/base/jspm_packages/system-polyfills.src.js?3aa57969dce4ecea4c51aab540f372d15cc886b6:890:13)
Error loading http://localhost:9876/jspm_packages/npm/reflect-metadata@0.1.3/typings.d.ts!http://localhost:9876/jspm_packages/github/frankwallis/plugin-typescript@4.0.2/plugin.js'
And the reflect-metadata@1.3.0.json
generated by JSPM looks like:
{
"main": "Reflect.js",
"map": {
"crypto": "@empty"
},
"format": "cjs",
"meta": {
"*": {
"globals": {
"process": "process"
}
},
"*.json": {
"format": "json"
},
"typings.d.ts": {
"format": "esm"
}
}
}
So maybe that is not the right config?
Yeah, so the right way for this is:
"npm:reflect-metadata@0.1.3": {
"meta": {
"Reflect.js": {
"typings": "Reflect.ts"
}
}
}
Maybe this should be reported as Reflect.ts
should probably be Reflect.d.ts
.
What is the current status of this issue?
As far as I tested, typeCheck
works on server side compilation, but not yet on client side.
At least when using external dependencies I get errors:
logger.js:17 TypeScript http://localhost:9987/jspm_packages/npm/@ngrx/store@1.5.0/interfaces.d.ts:1:28Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module 'rxjs/Observable'. (TS2307)Logger.error @ logger.js:17(anonymous function) @ format-errors.js:20formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript http://localhost:9987/jspm_packages/npm/@ngrx/store@1.5.0/store.d.ts:1:28Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module 'rxjs/Observable'. (TS2307)Logger.error @ logger.js:17(anonymous function) @ format-errors.js:20formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript http://localhost:9987/jspm_packages/npm/@ngrx/store@1.5.0/store.d.ts:2:33Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module 'rxjs/BehaviorSubject'. (TS2307)Logger.error @ logger.js:17(anonymous function) @ format-errors.js:20formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript http://localhost:9987/jspm_packages/npm/@ngrx/store@1.5.0/dispatcher.d.ts:1:25Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module 'rxjs/Subject'. (TS2307)Logger.error @ logger.js:17(anonymous function) @ format-errors.js:20formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript http://localhost:9987/jspm_packages/npm/@ngrx/store@1.5.0/ng2.d.ts:1:39Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module '@angular/core'. (TS2307)Logger.error @ logger.js:17(anonymous function) @ format-errors.js:20formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript http://localhost:9987/src/app/pages/test1.component.ts:1:25Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module '@angular/core'. (TS2307)Logger.error @ logger.js:17(anonymous function) @ format-errors.js:20formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript http://localhost:9987/src/app/pages/test1.component.ts:2:31Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module '@angular/common'. (TS2307)Logger.error @ logger.js:17(anonymous function) @ format-errors.js:20formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript http://localhost:9987/src/dev/main.dev.ts:7:25Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module '@angular/platform-browser-dynamic'. (TS2307)Logger.error @ logger.js:17(anonymous function) @ format-errors.js:20formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript http://localhost:9987/src/dev/main.dev.ts:10:32Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module '@angular/router-deprecated'. (TS2307)Logger.error @ logger.js:17(anonymous function) @ format-errors.js:20formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript http://localhost:9987/src/app/app.ts:1:25Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module '@angular/core'. (TS2307)Logger.error @ logger.js:17(anonymous function) @ format-errors.js:20formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript http://localhost:9987/src/app/app.ts:2:46Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module '@angular/router-deprecated'. (TS2307)Logger.error @ logger.js:17(anonymous function) @ format-errors.js:20formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript http://localhost:9987/src/app/todos/todo.service.ts:4:26Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module '@angular/core'. (TS2307)Logger.error @ logger.js:17(anonymous function) @ format-errors.js:20formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript http://localhost:9987/src/app/todos/todo.service.ts:5:26Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module 'rxjs/Observable'. (TS2307)Logger.error @ logger.js:17(anonymous function) @ format-errors.js:20formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript http://localhost:9987/src/app/todos/todo.service.ts:6:20Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module 'immutable'. (TS2307)Logger.error @ logger.js:17(anonymous function) @ format-errors.js:20formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript http://localhost:9987/src/app/todos/todos.store.ts:2:20Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module 'immutable'. (TS2307)Logger.error @ logger.js:17(anonymous function) @ format-errors.js:20formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript http://localhost:9987/src/app/pages/test2.component.ts:1:25Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module '@angular/core'. (TS2307)Logger.error @ logger.js:17(anonymous function) @ format-errors.js:20formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript http://localhost:9987/src/app/pages/test2.component.ts:2:31Logger.error @ logger.js:17(anonymous function) @ format-errors.js:13formatErrors @ format-errors.js:7(anonymous function) @ plugin.js:39
logger.js:17 TypeScript Cannot find module '@angular/common'. (TS2307)
Ambient dependencies seem not to cause problems. I'm using lodash in the sources and the matching ambient typings are loaded.
What I would like to achieve in my setup is typescript compilation with typeCheck
on client side in combination with hot-module-replacement. This is a promising workflow :)
There is another ticket disabling me on this setup. But I'm not totally sure whether this is a problem with the systemjs-hot-reloader or anything else.
I think this is working, see the angular2 example
What version of jspm are you using?
I'm using "jspm": "^0.17.0-beta.13"
.
Which version was used for the example? It's not listed in the package.json
It's the same version, it's listed in the root package.json.
If you can provide a repro I will take a look.
I have tried example with Angular2 RC and it won't work. Maybe I'm doing something wrong. Please could you update example to Angular2 RC?
Hi @frankwallis, sorry for the late response. I recently published ng2-jspm-template. Here the problem ocurrs when you turn on typeCheck
inside jspm.conf.js and trigger TypeScript compilation inside the browser (for example via hot-module-replacement or starting without development bundling).
@svi3c thanks for sharing your project.
The issue with Cannot find module 'rxjs/Observable'
can be resolved by changing the packages configuration in jspm.config.js:
"rxjs": {
"meta": {
"*.js": {
"typings": true
}
}
}
becomes
"npm:rxjs@5.0.0-beta.6": {
"meta": {
"*.js": {
"typings": true
}
}
}
It seems that when the packages configuration and map entry for a package happen in different System.config
calls then the metadata is not being found. In your case the typings: true
metadata is found for @ngrx but not found for rxjs or @angular/*. This could well be related to https://github.com/systemjs/systemjs/issues/1255
Really this configuration should be setup in the jspm registry but that has not happened yet. In the typescript example project I have moved this configuration into package.json which means that jspm writes it to the config file with the map configuration and makes it easier when updating versions.
Update: Moving the typings metadta to package.json does fix this issue, the metadata does not get written to the config file though it gets written to jspm_packages/npm/rxjs@5.0.0-beta3.js
(for example)
The error with the hot reloader trying to reload files is happening because the files were originally coming from the bundle and then trying to be reloaded with the file://
extension. I think that plugin-typescript should not be writing the file:///
extension to the bundles, so I need to investigate that. The hot-reloading should work when not using the bundles configuration though?
@sokolovstas the angular2 example is now using rc1
Thanks for the clarification and support, @frankwallis! Yes, without using bundles, the hmr works in combination with typeCheck
.
@frankwallis I'm having a similar (?) problem in CockroachDB. Two of our dependencies (redux and reselect) now ship with external typings, so we want plugin-typescript to load them rather than using typings
to fetch these files. It doesn't work (no attempt is made to load the .d.ts
files). I've tried the workaround you describe here to no avail - jspm install
removes the overrides. All the work is here https://github.com/cockroachdb/cockroach/compare/master...tamird:ui-next-update
Any ideas?
EDIT: one thing I noticed while debugging this is that metadata
(in Resolver.prototype.lookupTyping
) is an empty object for these dependencies.
EDIT: both packages specify typings
in their package.json
files.
I haven't tried it yet (it's late here) but on quick inspection the override should be:
"npm:redux@3.4.0": {
"meta": {
"dist/redux.js": {
"typings": "index.d.ts"
}
}
},
Note the version does not have the ^
it is the actual installed version. typings: true
means that all js files will have a corresponding .d.ts file with the same name (like angular2), for bundled typings like redux it should contain the path of the bundle.
Hopefully this will fix it, if not I will take another look.
@frankwallis updated, but that didn't fix it =/
metadata is still an empty object, too.
Ok, that configuration only works in jspm@0.17, but in 0.16 you can achieve the same thing by adding global meta configuration in config.js
:
transpiler: "ts",
typescriptOptions: {
"typeCheck": "strict",
"tsconfig": true,
"targetLib": "ES5"
},
meta: {
"reselect": {
"typings": "src/reselect.d.ts"
}
},
Alternatively you can also install them using the typings
tool apparently see this comment which would give intellisense support (I haven't actually tried this though...)
Indeed, both of the solutions you mention work, thanks.
However, why is it that this doesn't "Just Work" given that the information is already in reselect's package.json
?
The plugin does not have access to the package.json, and even if it did there are some packages which contain typings and do not have a typings
entry in packages.json. The algorithm TypeScript uses for finding external typings cannot be used from within a browser as it involves trawling the file system, so when external typings exist the plugin needs to know that they do exist and their exact location.
I agree that the configuration is painful, and I am open to better solutions but I just don't see any at the moment. Ideally this configuration will get added into the central jspm registry and then things will "Just Work" for those packages.
It sounds like the resolution problems tackled in https://github.com/typings/typings/issues/123 are critical to this plugin's type checking feature. I'd be really interested to see what can be done to make this work, if you don't mind helping me understand this area a little better.
Firstly, jspm-npm will handle conversion of npm packages converting the Node resolution algorithm into the SystemJS resolution algorithm.
Are you saying that typings themselves are written assuming the Node resolution algorithm? Which assumptions are these usually based on? For example, are extensions usually used? Do directory requires or json requires get used? How exactly does SystemJS's naive import not work with this resolution currently?