2

I have this simple TypeScript Angular 2 example:

test.ts

import {Component} from 'angular2/core';

@Component({
    selector: 'my-app',
    template: '<div>Test</div>'
})

export class TestComponent {}

main.ts

import {bootstrap} from 'angular2/platform/browser'
import {TestComponent} from './components/test.component/test'

bootstrap(TestComponent);

index.html

<html>
    <head>
        <title>This is an Angular 2 test</title>

        <!-- Angular dependencies -->
        <script src="/node_modules/es6-shim/es6-shim.js"></script>
        <script src="/node_modules/systemjs/dist/system-polyfills.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>

        <!-- App -->
        <script>

            System.config({
                packages: {
                    '/': {
                        format: 'register',
                        defaultExtension: 'js'
                    }
                }
            });

            System.import('main').then(null, console.error.bind(console));

        </script>

    </head>
    <body>
        <my-app></my-app>
    </body>
</html>

And finally when I run 'tsc' and my deploy scripts the node_modules/angular2, node_modules/systemjs, node_modules/rxjs and node_modules/es6-shim folders are copied together with the compiled JavaSciprt files. Then when I try to open index.html all I get is this:

Uncaught ReferenceError: require is not defined(anonymous function) @ browser.ts:1

angular2-polyfills.js:138 Error: http://localhost:8080/node_modules/angular2/platform/browser.js did not call System.register or AMD define. If loading a global module configure the global name via the meta exports property for script injection support.(…)run @ angular2-polyfills.js:138zoneBoundFn @ angular2-polyfills.js:111lib$es6$promise$$internal$$tryCatch @ angular2-polyfills.js:1511lib$es6$promise$$internal$$invokeCallback @ angular2-polyfills.js:1523lib$es6$promise$$internal$$publish @ angular2-polyfills.js:1494lib$es6$promise$$internal$$publishRejection @ angular2-polyfills.js:1444(anonymous function) @ angular2-polyfills.js:243run @ angular2-polyfills.js:138zoneBoundFn @ angular2-polyfills.js:111lib$es6$promise$asap$$flush @ angular2-polyfills.js:1305

core.ts:6 Uncaught ReferenceError: require is not defined

Can someone pls give me a hand with this. I seem to be doing more or less the same thing as the Angular2 5-minute quickstart (https://angular.io/guide/quickstart) and it just refuses to work for me.

It feels like I'd need to also add the dependency libraries to systemjs but I'm not sure what would be the right way to do it and how did the angular2 guys get their quistart demo to work with simple <script></script> tags instead.

tsconfig.json

{
    "compilerOptions": {
        "target": "ES5",
        "module": "system",
        "moduleResolution" : "node",
        "sourceMap": true,
        "emitDecoratorMetadata": false,
        "experimentalDecorators": false,
        "removeComments": true,
        "noImplicitAny": true,
        "noEmitOnError": true,
        "outDir": "build"
    },

    "exclude": [
        "build",
        "bundle",
        "node_modules",
        "public",
        "scss",
        "html",
        "templates",
        ".sass-cache"
    ]
}
0

1 Answer 1

2

I think the problem is at the level of your SystemJS configuration:

System.config({
  packages: {
    '/': { <----------------
      format: 'register',
      defaultExtension: 'js'
    }
  }
});

You should update this using the sub folder containing your TypeScript source files. Something like that:

  System.config({
    packages: {        
      app: {
        format: 'register',
        defaultExtension: 'js'
      }
    }
  });

Hope it helps you, Thierry

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks a lot! Your change didn't fix my issue completely. My deployment had a different structure (it didn't have the /app folder) and that's why I was using the '/' package name. Once I changed my grunt tasks to deploy everything to /app instead of / and then I also made the change you suggested above and finally I changed System.import('main') to System.import('app/main'). I have no idea why the app folder was so necessary but whatever. Thanks again for your help!
You're welcome! In fact, modules like angular2/* are already packaged into single files like angular2-dev.js so your configuration { format: 'register', defaultExtension: 'js' } shouldn't apply in suc cases. Using / makes the configuration apply for everything...
Speaking of which, one extra thing I had to add to the systemjs was 'node_modules': {format: 'cjs', defaultExtension: 'js' } Otherwise I was getting errors that it can't find angular2/browser when in reality it was looking for angular2/browser.js. The problem that I have now, however, is Error: No Directive annotation found on TestComponent So I'm not sure whether I fixed anything or I just broke it further ..
Strange. In fact the angular2/browser/platform module is contained in the node_modules/angular2/bundles/angular2.dev.js file... Adding the file in a <script> should be enough ;-)
I figured it out - apparently importing "angular2/core" and "../node_modules/angular2/core" in TypeScript are 2 very different cases. When I did the former, it finally all worked (after adding the /app folder as explained earlier). But before when I had the "node_modules" in the import statement Angular ended up loading all libraries from scratch using ajax calls to retrieve each and every script and this ended up exploding in my face with the "No Directive annotation" error I mentioned.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.