flaviait / ng2-jspm-template

A template for a quick development workflow with angular 2 and jspm
MIT License
14 stars 3 forks source link

Update to angular rc.6 #28

Closed svi3c closed 8 years ago

svi3c commented 8 years ago

Blocked by https://github.com/frankwallis/plugin-typescript/issues/154

svi3c commented 8 years ago

At the moment I get an error like this:

err  Error on fetch for npm:@angular/core@2.0.0-rc.6/testing.js at file:///home/sven/dev/projects/open-source/ng2-jspm-template/jspm_packages/npm/@angular/core@2.0.0-rc.6/testing.js
  Loading src/app/todos/todo.service.spec.ts
  Error: ENOENT: no such file or directory, open '/home/sven/dev/projects/open-source/ng2-jspm-template/jspm_packages/npm/@angular/core@2.0.0-rc.6/testing.js'
    at Error (native)

I'm not sure how to fix it.

DorianGrey commented 8 years ago

testing is a package inside @angular/core (and within @angular/platform-browser-dynamic as well). We're currently using

import {
  TestBed,
  inject
} from "@angular/core/testing";

which, in general, should automatically refer to the index.js within this package. It seems that this mechanism does not work.

Might be a side-effect of the recent changes in plugin-typescript. Suppose it's a bug, since referencing the testing module this way still works fine in webpack. Or maybe we need even more specialized configuration for this case, so that @angular/core/testing is referred to as a package?

svi3c commented 8 years ago

I'm not sure about that. I tried to only update jspm, plugin-typescript and typescript. This works without any problems.

I noticed that with rc6 the bundles are loaded instead of the single files, but overwriting this in package.json ja no effect on the error.

DorianGrey commented 8 years ago

Hm... this might refer to the way the angular package is published on npm - it has changed with rc.6: https://github.com/angular/angular/pull/11120 (now contains both a UMD-bundle and the seperate files).

Just to get that straight - What we're doing:

import {...} from "@angular/core/testing";

File that should be referred to:

ng2-jspm-template/jspm_packages/npm/@angular/core@2.0.0-rc.6/testing/index.js

File that is referred to by resolution:

ng2-jspm-template/jspm_packages/npm/@angular/core@2.0.0-rc.6/testing.js

It might be a problem that testing is not a "real" package, i.e. it does not contain a package.json. However, since the import refers to a directory, looking for the index.js should always be the first approach when bundling. Or - is there a configuration option to define a package to be within another package, and what its main file is? Otherwise, this issue definitely looks like a bug within the resolution mechanism, i.e. either in plugin-typescript or jspm.

svi3c commented 8 years ago

Right, the resolution is jspm_packages/npm/@angular/core@2.0.0-rc.6/testing.js instead of jspm_packages/npm/@angular/core@2.0.0-rc.6/testing/index.js.

I think the problem with the resolution not working out of the box has to do with the client side build. We don't want to have a bunch of 404 responses when looking for a potential match to import.

The package configuration did not work for me, but mappings like this did:

'@angular/core/testing': 'npm:@angular/core@2.0.0-rc.6/testing/index',
'@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic@2.0.0-rc.6/testing/index'

It looks quite hacky to me anyways.

I'm wondering: Why this worked with rc.5? @frankwallis can you provide an answer to this question?

frankwallis commented 8 years ago

I don't think SystemJS is able to import directories containing an index.js because of the browser loading requirement and 404 responses, as you say. You can probably solve it with some map configuration @angular/core/testing: @angular/core/testing/index.js? or by importing the index.js directly.

Defaulting to searching for index.js is nodejs specific, not part of the es module spec.

svi3c commented 8 years ago

Thanks @frankwallis, so the manual mapping seems to be necessary.

You are right about the es module spec, but the typescript module resolution is more complex and kind-of mimics the node.js module resolution. However, tsc is expected to run at build time / server-side. So this module resolution process is not portable to plugin-typescript which is expected to run on the server as well as on the client.

@DorianGrey Correct me if I'm wrong, but AFAIK Webpack compiles always server-side, even with the hot-reloading. This way the index.ts should be correctly resolved. There are node.js middlewares used to achieve this.

I also found out why this was working before: actually there was a testing.ts file in rc.5 placed in @angular/core. This has been changed in rc.6.

DorianGrey commented 8 years ago

Correct me if I'm wrong, but AFAIK Webpack compiles always server-side, even with the hot-reloading.

In general - yes.

I also found out why this was working before: actually there was a testing.ts file in rc.5 placed in @angular/core. This has been changed in rc.6.

It's still present, but is now placed in a particular directory.

I don't think SystemJS is able to import directories containing an index.js because of the browser loading requirement and 404 responses, as you say.

Well, SystemJS has to figure out the main file of a package or module somehow, otherwise, importing from e.g. @angular/core would be impossible. I still think the problem in this particular case is that neither @angular/core/testing nor @angular/platform-browser-dynamic/testing are "real" packages, i.e. different from @angular/core, they do not contain any kind of information about their main file, e.g. within a package.json file. So we have to point to this main file manually here. I've tried to manually define a main entry for @angular/core/testing in the jspm.config.js yesterday, but that didn't have any effect. Thus,if manual mappings work, I'd suggest it should be ok to use them - although you are right, it still looks a little bit ... odd.

svi3c commented 8 years ago

I am now mapping the @angular/*/testing modules to the bundles/*-testing.umd.js: https://github.com/flaviait/ng2-jspm-template/commit/49a283f33a603974c5b64720617734d3e0a1a25e

Now the problem is that no typings are found for the bundles:

err  Error on fetch for npm:@angular/core@2.0.0-rc.6/bundles/core-testing.umd.d.ts!github:frankwallis/plugin-typescript@5.1.1/plugin.js at [project-root]/jspm_packages/npm/@angular/core@2.0.0-rc.6/bundles/core-testing.umd.d.ts![project-root]/jspm_packages/github/frankwallis/plugin-typescript@5.1.1/plugin.js
  Loading src/app/todos/todo.service.spec.ts
  Error: ENOENT: no such file or directory, open '[project-root]/jspm_packages/npm/@angular/core@2.0.0-rc.6/bundles/core-testing.umd.d.ts'
    at Error (native)

I tried adding these lines to the typings section of jspm.config.js:

'@angular/core/testing': 'index.d.ts',
'@angular/core/bundles/core-testing.umd.js': '../testing/index.d.ts',
'jspm_packages/npm/@angular/core@2.0.0-rc.6/bundles/core-testing.umd.js': '../testing/index.d.ts',
'npm:@angular/core@2.0.0-rc.6/bundles/core-testing.umd.js': '../testing/index.d.ts',

without any success. I also tried to configure the typings via the package.json overrides like this:

"npm:@angular/core@2.0.0-rc.6": {
  "meta": {
    "src/*.js": {
      "deps": [
        "reflect-metadata",
        "zone.js"
      ]
    },
    "bundles/core-testing.umd.js": {
      "typings": "testing/index.d.ts"
    }
  }
}

This did not work eighter.

@frankwallis do you have an idea what I missed here?

frankwallis commented 8 years ago

@svi3c I have added a fix for this in 5.1.2 so this config should now work:

   '@angular/core': 'index.d.ts',
   '@angular/core/testing': 'testing/index.d.ts',

Hope that fixes it.

svi3c commented 8 years ago

@frankwallis thank you! :-) I had to use '@angular/core/testing': '../testing/index.d.ts' instead of '@angular/core/testing': 'testing/index.d.ts'. Otherwise I got this error:

err  Error on fetch for npm:@angular/core@2.0.0-rc.6/bundles/core-testing.umd.js/index.d.ts!github:frankwallis/plugin-typescript@5.1.2/plugin.js at [project-root]/jspm_packages/npm/@angular/core@2.0.0-rc.6/bundles/core-testing.umd.js/index.d.ts![project-root]/jspm_packages/github/frankwallis/plugin-typescript@5.1.2/plugin.js
  Loading src/app/todos/todo.service.spec.ts
  Error: ENOTDIR: not a directory, open '[project-root]/jspm_packages/npm/@angular/core@2.0.0-rc.6/bundles/core-testing.umd.js/index.d.ts'
    at Error (native)

It seems to me that the testing/ of '@angular/core/testing': 'testing/index.d.ts' is somehow mapped by the mapping '@angular/core/testing': 'npm:@angular/core@2.0.0-rc.6/bundles/core-testing.umd.js' before. Does this make sense?