Debug: Importing debug in angular 2 app with system.js

Created on 23 Sep 2016  Â·  17Comments  Â·  Source: visionmedia/debug

I am working on a MEAN stack app with Angular 2 frontend. I have successfully used debug in the express app. However I am unable to cleanly import debug in app.components.ts or main.module.ts. Any idea on how to proceed?

  • <script src="/node_modules/debug/debug.js"></script> Results in error: Uncaught ReferenceError: module is not defined
  • <script>System.import('./node_modules/debug/debug.js');</script> Not good either: zone.js:101 GET http://localhost:8002/ms.js 404 (Not Found) Some dependency script not able to load.
  • import { debug } from '../../../node_modules/debug/debug.js'; inside any app file also gives error: zone.js:101 GET http://localhost:8002/ms.js 404 (Not Found); (index):25 Error: Error: XHR error (404 Not Found) loading http://localhost:8002/ms.js(…)

Most helpful comment

Using the Angular CLI 1.0.0 (which uses Webpack) I got debug working using the following steps:

First of, nstalling and configuring the debug library for angular (see also CLI wiki entry)

  • npm install debug --save
  • npm install @types/debug --save-dev
  • add "debug" to the "types": [ ] in src/tsconfig.app.json

Then in any ts file use (import and define namespace) it as following:

import { Injectable } from '@angular/core';

import * as Debug from 'debug';
const debug = Debug('app:auth');

@Injectable()
export class AuthService {

  constructor() { }

  login() {
    debug('Login please...');
  }

}

Finally to enable the debug in the console, type the following in the console (see also NPM debug package page)

  • localStorage.debug = 'app:*'
  • or using the Chrome Developer Tool, go to the 'Application' tab, expand the 'Local Storage' entry, select the domain which you are working on and add debug as key and app:* as value.

Differences with the initial suggestion:

  • No need to edit node_modules/debug/debug.js
  • No need to assign the debugApp to the global window

I'm not 100% sure if this is the correct way, but it works.

All 17 comments

I took some inspiration from Importing lodash into angular2 + typescript application and finally figured out how to import it. No console errors and no compiler errors this time.

First I should mention: when upgrading from typescript 1 to typescript 2 the typings tool gets deprecated. Instead, npm package manager is used to install type definitions.

I followed these steps:

  • npm install debug --save
  • npm install @types/debug --save
  • Mapped debug in system.config.js

system.config.js:

map: {
    'debug': '../node_modules/debug/browser.js',
    ...
}
  • Import in any .ts file you need: import * as debug from 'debug';
  • Optionally, if needed in index.html use: <script>System.import('debug');</script>

Untill now this should work, however a pesky error persists: GET http://localhost:8002/ms.js 404 (Not Found). I fixed this by editing node_modules/debug/debug.js.

  • Replace line 14: exports.humanize = require('ms'); with exports.humanize = require('node_modules/ms/index');.

I am not sure what this implies for other use cases of debug. If you have any suggestions on how to improve this solution so it is not necessary to edit inside node_modules/debug/debug.js write a comment.

Usage in browser

Preferably in app.component.ts or main.module.ts write:

// Expose debugsApp in window object in order to access it from the console. 
// window.debug is already used by chrome. 
import * as debug from 'debug';
(<any>window).debugApp = debug;  // The typescript way to extend window

In any other .ts file:

import * as Debug from 'debug';

var debug = Debug('app:someModule');
debug('Some message');

Finally in the console type as you need:

// Business as usual
debugApp.enable('*'); // Enable all
debugApp.enable('app'); // Enable app debugger
debugApp.enable('app:*'); // Enable app debuggers if they are namespaced
debugApp.enable('app:someModule'); // Enable someModule
debugApp.disable('*'); // Disable all

SOLVED
P.S. Please provide an example in documentation that covers this issue. It is not obvious at all for newcomers how to solve this issue.

Further issues

I had an unexpected issue with this method. I could either load the server path or the frontend path for the debug script. So I had to do another improvisation.

node_modules/debug/debug.js - Line 14

if (typeof process === 'undefined') {
  exports.humanize = require('node_modules/ms/index.js');
} else {
  exports.humanize = require('ms');
}

This triggers another issue on itself. System.js likes to parse ahead the exports so this leads to abnormal behavior when exports statement is combined with an if statement. More details here. Fortunately there is a fix. More details here thanks to @guybedford

In system.config.js add:

System.config({
    map: {
        ms: '@empty'
    }
});

In the end it's a patch-up job, but it works. Hopefully debug authors will suggest a better solution. Until then use this. It's a lot of effort to set up but in the end it pays off a lot. It is insanely useful to debug frontend apps in this manner.

I am having the same issue, but your suggestions didnt work

Can you offer some details? Where do you get stuck?

@adrian-moisa

npm install --save-dev @types/debug debug

import * as Debug from 'debug';

export class HomeComponent {
    constructor() {
        var debug = Debug('app:someModule');
        debug('Some message');
    }
}

I get

[19:30:14] Error: Cannot call a namespace ('Debug')

Your code sample seems legit. The error message doesn't ring any bells for me. Sorry, I can't help. I'm still waiting for some contributor to take part in the discussion...

got it @adrian-moisa

import debug from 'debug';
(<any>window).debug = debug;

export class HomeComponent {
    constructor() {
        debug.enable("cesco")
        debug("cesco")("HELLO")
    }
}

@cescoferraro Is the above a fix? Would you like to add documentation via a PR?

@thebigredgeek Well, I would stick with the first solution I written in the first reply. It did not need to instantiate globals to get the code working.

Concerning the PR: I am not confident enough that this is the best solution to pull. I thought maybe somebody with a lot more experience then me will improve on this ticket.

@adrian-moisa unfortunately the implementation you described is likely to break webpack, browserify, and others. It's definitely interesting that SystemJS has issues loading ms as a dependency. Usually when you want to import commonjs code into the browser, you use a module loader than can resolve the entire dependency tree for the commonjs dependency. Is it possible that some sort of mapping is missing? With systemjs, don't you need to tell the loader where ms lives?

Closing this for now. Will open it back up if anyone has further ideas.

@thebigredgeek I will send a PR later today

Using the Angular CLI 1.0.0 (which uses Webpack) I got debug working using the following steps:

First of, nstalling and configuring the debug library for angular (see also CLI wiki entry)

  • npm install debug --save
  • npm install @types/debug --save-dev
  • add "debug" to the "types": [ ] in src/tsconfig.app.json

Then in any ts file use (import and define namespace) it as following:

import { Injectable } from '@angular/core';

import * as Debug from 'debug';
const debug = Debug('app:auth');

@Injectable()
export class AuthService {

  constructor() { }

  login() {
    debug('Login please...');
  }

}

Finally to enable the debug in the console, type the following in the console (see also NPM debug package page)

  • localStorage.debug = 'app:*'
  • or using the Chrome Developer Tool, go to the 'Application' tab, expand the 'Local Storage' entry, select the domain which you are working on and add debug as key and app:* as value.

Differences with the initial suggestion:

  • No need to edit node_modules/debug/debug.js
  • No need to assign the debugApp to the global window

I'm not 100% sure if this is the correct way, but it works.

@Sjiep are you using rollup? There was another issue here that sounded like the same problem

@thebigredgeek not that I'm aware of. It looks like rollup is a JS bundler? I'm using the Angular CLI which uses Webpack for bundling.

@Sjiep weird. I am using webpack as well, and haven't had this issue. It looks like it is probably some sort of conflict with the @types namespace... not sure why

@thebigredgeek I'm not having any issue though. I just wanted to share a solution for using debug in Angular 2 that worked for me (which was a bit cleaner then the initial solution posted).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gdepouilly picture gdepouilly  Â·  6Comments

pavanjadhaw picture pavanjadhaw  Â·  5Comments

Qix- picture Qix-  Â·  7Comments

Qix- picture Qix-  Â·  7Comments

xkubow picture xkubow  Â·  4Comments