Search code examples
angularsystemjs

How can I use require() in angular 2 using systemjs?


I'm trying to use relative paths for templates in my components to using systemjs. (The reason why I want to use relative paths is, that ng-xi18n can't deal with absolute paths at the moment.) I don't want to use this

moduleId: __moduleName

approach but rather something like:

templateUrl: require('../templates/app.html')

First the tsc marked an error that require is not defined and after a little research I found out that someone can include dependencies for @types/node to use the require function.

Now that I did this, tsc compiles without errors but if I open the app in the browser it shows the error:

__zone_symbol__error : Error: (SystemJS) require is not a function TypeError: require is not a function at execute

Since I can't find a solution for this I hope someone can help a frantic angular2 newbie to solve this problem.

Thanks in advance!!




Here are a few code snippets from my app.

package.json:

{
  "name": "test",
  "version": "0.0.1",
  "scripts": {
    "start": "concurrently \"npm run tsc:w\" \"gulp serve\" ",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "typings": "typings",
    "postinstall": "typings install",
    "i18n": "ng-xi18n -p ./tsconfig.json"
  },
  "dependencies": {
    "@angular/common": "~2.4.6",
    "@angular/compiler": "~2.4.6",
    "@angular/compiler-cli": "^2.4.6",
    "@angular/core": "~2.4.6",
    "@angular/forms": "~2.4.6",
    "@angular/http": "~2.4.6",
    "@angular/platform-browser": "~2.4.6",
    "@angular/platform-browser-dynamic": "~2.4.6",
    "@angular/platform-server": "^2.4.6",
    "@angular/router": "~3.4.6",
    "angular-in-memory-web-api": "~0.2.4",
    "core-js": "^2.4.1",
    "es6-shim": "^0.35.1",
    "rxjs": "5.0.1",
    "systemjs": "0.19.41",
    "zone.js": "^0.7.4"
  },
  "devDependencies": {
    "concurrently": "^3.1.0",
    "lite-server": "^2.2.2",
    "typescript": "^2.0.10",
    "typings": "^1.2.0",
    "gulp": "3.9.1",
    "gulp-connect": "3.2.1",
    "http-proxy-middleware": "0.13.0",
    "@types/node": "^7.0.0"
  }
}

tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "module": "system",
    "moduleResolution": "node",
    "outDir": "app/js",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false,
    "types": ["node"]
  },
  "exclude": [
    "node_modules",
    "typings/main",
    "typings/main.d.ts"
  ]
}

systemjs.config.js:

(function (global) {
    System.config({
        defaultJSExtension: true,
        paths: {
            'npm:': 'node_modules/'
        },
        map: {
            app: 'app',

            '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
            '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
            '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
            '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
            '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
            '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
            '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
            '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',

            'rxjs': 'npm:rxjs',
            'angular-in-memory-web-api':'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
        },

        packages: {
            app: {
                main: './main.js',
                defaultExtension: 'js'
            },
            rxjs: {
                defaultExtension: 'js'
            }
        }
    });
})(this);

app.component.ts:

import {Component} from '@angular/core';
import { LoginService } from '../services/login.service';
import { UserStatus } from '../models/userStatus';
import {SessionService} from "../services/session.service";
import {UserService} from "../services/user.service";
import {Router} from '@angular/router';

@Component({
    selector: 'main-app',
    template: require('../templates/app.html')

})

export class AppComponent {

}

Solution

  • According to the SystemJS author:

    A require statement is not defined to work inside ES modules, globals or System.register in SystemJS, as that is something specifically for the CommonJS module format.

    Instead, you could use the SystemJS text plugin to import any text file in an ES6 style. So the component would look like this:

    import { Component } from '@angular/core';
    import template from '../templates/app.html!text';
    
    @Component({
        selector: 'main-app',
        template: template
    })
    export class AppComponent {}