18
votes

I am having some trouble understanding how to import classes from Modules in TypeScript, specifically for Angular 2 in Visual Studio 2015 (update 1) with TypeScript 1.7.

Everywhere in the Angular 2 documentation I see import statements such as: import {Component} from 'angular2/core';. These files are in node_modules/angular2/*. What makes just angular2/* work?

I can only get rid of the errors in Visual Studio when I have a relative path from the app directory such as: ./../node_modules/angular2/platform/browser';. This fixes the Visual Studio build errors, but when I try and run the app with System.import('app/boot') I get a bunch of errors like this:

system.src.js:1049 GET http://localhost:8080/node_modules/angular2/platform/browser 404 (Not Found)

Another issue is being able to use statements such as: import {SearchComponent} from './Components/Search/search.component'; in Visual Studio, but then when I run it there are a lot of GET errors at system.src.js:2476.

I thought that setting the defaultExtension: 'js' for System.config should have taken care of that issue.

UPDATE Here are all the files that I think are relevant:

views/home/index.html

<script src="node_modules/es6-shim/es6-shim.js"></script>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
System.config({
        packages: {
            app: {
                format: 'register',
                defaultExtension: 'js'
            }
        }
    });
System.import('app/app')
    .then(null, console.error.bind(console));

test.csproj

<TypeScriptToolsVersion>1.7</TypeScriptToolsVersion>
<TypeScriptExperimentalDecorators>True</TypeScriptExperimentalDecorators>
<TypeScriptModuleResolution>Node</TypeScriptModuleResolution>
<TypeScriptTarget>ES5</TypeScriptTarget>
<TypeScriptJSXEmit>None</TypeScriptJSXEmit>
<TypeScriptCompileOnSaveEnabled>True</TypeScriptCompileOnSaveEnabled>
<TypeScriptNoImplicitAny>False</TypeScriptNoImplicitAny>
<TypeScriptModuleKind>CommonJS</TypeScriptModuleKind>
<TypeScriptRemoveComments>False</TypeScriptRemoveComments>
<TypeScriptOutFile />
<TypeScriptOutDir />
<TypeScriptGeneratesDeclarations>False</TypeScriptGeneratesDeclarations>
<TypeScriptNoEmitOnError>True</TypeScriptNoEmitOnError>
<TypeScriptSourceMap>True</TypeScriptSourceMap>
<TypeScriptMapRoot />
<TypeScriptSourceRoot />

typings/tsd.d.ts

export * from './../node_modules/angular2/core';
export * from './../node_modules/angular2/common';
export * from './../node_modules/angular2/http';
export * from './../node_modules/angular2/router';
export * from './../node_modules/angular2/platform/browser';

File structure:

app/
    app.ts
    components/
    models/
    services/
node_modules/ (npm install using Angular 2 quickstart's package.json)
    angular2/ (not all the files listed)
        bundles/ (not all the files listed)
            angular2.dev.js
        platform/
        src/
        ts/
        typings/
        common.d.ts
        core.d.ts
        http.d.ts
        router.d.ts
    es6-module-loader/
    es6-promise/
    es6-shim/
    rxjs/
    systemjs/
    zone.js/
    typescript/ (not sure if this needs to be here)

I am unfamiliar with TypeScript, could there be an error caused by different Typescript module systems? Angular 2 recommended System.config be set with format: 'register' but https://www.npmjs.com/package/angular2 says that the files can be consumed using CommonJs.

With these files, I get these two console errors:

app.ts:1 Uncaught ReferenceError: require is not defined(anonymous function) @ app.ts:1
angular2-polyfills.js:143 Uncaught TypeError: Cannot read property 'split' of undefined
5
There's so much about your setup that isn't shown here, but aside from that I don't get the sense that you're loading the built Angular 2 library. It looks like you're still trying to load the unbuilt source files into your document which you shouldn't be doing. That map business you have above is not needed because like I said before SystemJS knows how to load the correct module out of the built library.pe8ter
I tried to add some more information to make it as clear as possible. I'm sorry if I'm being incoherent.Adam Hitchens
Have you installed typings for SystemJS using tsd?pe8ter
I have now, but it has not changed anything. I'm guessing that is because I only call System in index.html. Thanks for all your help so far.Adam Hitchens
Were you able to find a proper solution?Ufuk Hacıoğulları

5 Answers

5
votes

I had to make a couple edits to the 5 minute quickstart to get it working with MAMP.

You've got to tell SystemJS where to find your custom modules, but you can't set baseURL to do it. Setting baseURL seems to mess up module resolution for the node modules(like angular). Add this to your systemjs config instead:

map: {
    app: 'path/to/app/folder'
},

But don't change the angular import statements. Those aren't paths, they're module names and systemjs should resolve them just fine if you've included angular2.dev.js in a head script tag, as you have.

You also may have to include:

///<reference path="../node_modules/angular2/typings/browser.d.ts"/>

at the top of your app.ts(or wherever you call bootstrap)

0
votes

How does your HTML file load the Angular 2 library? It should be as simple as

<script src="path/to/my/libs/angular2.dev.js"></script>

You'll notice that file contains the entirety of the built/concatenated Angular 2 library. You shouldn't point your web page at the raw source files.

SystemJS knows what angular2/core means because the built library defines what that pattern means. Although it appears to be some directory structure (which it probably is in the unbuilt library) it's actually just some name for a module the built library. Search for this text in the built library and you'll see it defined:

System.register("angular2/core", ...

0
votes

The little red squiggly lines are probably because of your tsconfig.json. At least that is what caused the problem for me. The problem I had was I was using both files[] and excludes[]. This doesn't work as expected and is not a valid config.

I resolved this problem but I still have the "Uncaught ReferenceError: require is not defined " problem.

0
votes

"I resolved this problem but I still have the "Uncaught ReferenceError: require is not defined " problem."

systemjs can be configured to use require format:

System.config({
  packages: {
    app: {   // must be replaced 
      format: 'amd'
    }
  }
});

but if it is in your own code typescript compiler output can be set in tsconfig:

{
  "compilerOptions": {
    ...
    "module": "system"
    ... 
  }
}

in your visual studio configuration file it might means:

<TypeScriptModuleKind>system</TypeScriptModuleKind>
0
votes

The following worked for me.

System.config({    
          transpiler: 'typescript', 
          typescriptOptions: { emitDecoratorMetadata: true }, 
          packages: {       
          app: {
              defaultExtension: 'ts'
          }
        }
      });

I also included the typescript int the header

<script src="https://code.angularjs.org/tools/typescript.js"></script>