10

I have a Node.js & AngularJS app written in TypeScript, in which I'm trying to load modules using System.js.

It works fine if I only import a class to specify a type. e.g:

import {BlogModel} from  "./model"
var model: BlogModel;

However, when I try to instantiate a variable with an imported class, I get an exception at run-time. e.g:

import {BlogModel} from  "./model"
var model: BlogModel = new BlogModel();

Uncaught ReferenceError: require is not defined

I use CommonJS. I cannot use AMD because I have one project for both server side and client side. This is why I use System.js to load modules in the client.

This is my System.js definition:

 <script src="/assets/libs/systemjs-master/dist/system-polyfills.js"></script>
    <script src="/assets/libs/systemjs-master/dist/system.src.js"></script>

    <script>
        System.config({
            packages: {
                app: {
                    format: 'register',
                    defaultExtension: 'js'
                }
            }
        });
        System.import('classes.ts')
                .then(null, console.error.bind(console));
        System.import('model.ts')
                .then(null, console.error.bind(console));
    </script>

This is the content of model.ts file:

import {User} from "./classes";
import {Post} from "./classes";

export class BlogModel{
    private _currentUser: User;
    private _posts: Post[];

    get currentUser(){
        return this._currentUser;
    }

    set currentUser(value: User){
        this._currentUser = value;
    }

    get posts(){
        return this._posts;
    }

    set posts(value: Post[]){
        this._posts = value;
    }
}

And this is the JS line that produces the exception:

var model_1 = require("./model");

Uncaught ReferenceError: require is not defined

Any help will be profoundly appreciated!

Alon
  • 10,381
  • 23
  • 88
  • 152
  • i assume model.ts contains definition for `BlogModel`, can you share the code for that, also you must have imported systemjs in the main html page , can you share code for that too? Ideally you don't have to import all modules and it will be loaded as and when needed, so System.import('classes.ts') .then(null, console.error.bind(console)); should suffice, also you don't need ts extension, – Madhu Ranjan May 16 '16 at 23:58
  • @Madhu Ranjan I've edited the original question and added the content of model.ts and the script tags for System.js – Alon May 23 '16 at 19:31

1 Answers1

6

Lets try to simplify things a bit:

1) Configure your systemjs as following:

System.defaultJSExtensions = true;

2) Make sure that both your classes.ts and model.ts and bootstrap.ts (this is new file you should create, that will bootstrap your app) files are transpiled an located in the same directory as index.html (index.html should contain script to configure systemjs as specified above)

3) In bootstrap.ts:

import {BlogModel} from  "./model"
let model = new BlogModel();
console.log(model);

3) Bootstrap your application with single call to System.import:

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

Try these steps and I think you will solve your problem.

Amid
  • 21,508
  • 5
  • 57
  • 54
  • OK I did it, but now there is another problem: I use many ts files. I load them with script elements, so they are loaded before bootstrap.ts finishes loading the modules, therefore they all throw reference exceptions. I tried to solve it temporarily by copying all the file contents into bootstrap.ts and removing the script elements. However, I'm still getting an exception because I use angular.js which tries to find a module that's declared in the ng-app attribute of the html element. BTW It doesn't help if I put the script elements below the one in which I configure System.js. – Alon Jun 02 '16 at 11:55
  • Remove all script elements except the one for systemjs. All loading will be done by module loader (systemjs) according to your `import` statements starting from your bootstrap module (in your case it is bootstrap.ts). This is what modules in TS/JS all about. – Amid Jun 02 '16 at 11:58
  • But what am I supposed to do with third party libraries like angular.js? TypeScript compiler says: "TS2306: 'angular-1.4.7' is not a module". – Alon Jun 02 '16 at 12:25
  • They will be loaded automatically by the loader too. The only thing required is tell the systemjs in its configuration where to look for their files. Check this rep for example: https://github.com/swimlane/angular1-systemjs-seed – Amid Jun 02 '16 at 13:20
  • I posted a new question regarding System.js and got no answers. I'll be grateful if you can take a look on this question too: http://stackoverflow.com/questions/37641653/system-js-doesnt-display-full-stack-trace – Alon Jun 07 '16 at 19:28
  • I've also started a bounty for this question too. – Alon Jun 12 '16 at 20:46
  • In my case, system.import does load the js file, but does not bootstrap/kickstart the application. What is needed to start an app that uses systemjs modules? I don't use angular, just plain typescript files. I use TSC to bundle the typescript files into one bundle. – Kokodoko Jun 02 '17 at 13:18