Debug Aurelia 2 framework from user app?

Hi guys,

Is it possible to debug Aurelia 2 from user application? For example - from “Hello World” get-started app build by make CLI?

Some kind of framework source map, or perhaps to user *.ts files from /src folders, instead of /dist/ems files?

1 Like

V2 is shipped with standard sourcemap, so it should theoretically be possible to debug from user app. Did you enable sourcemap in your bundler/built tool etc?

Hi, thanks for the reply.

I’m not too familiar with Webpack, but to me, basic source maps configuration seems fine. This line in particular:

devtool: production ? undefined : 'eval-cheap-source-map',

But let me explain. I used getting started example:

  1. npx makes aurelia
  2. Default TypeScript Aurelia 2 App
  3. npm start

And, before even trying to debug the my-app code in Chrome Dev tools, I tried to put breaking point in Aurelia 2 code. It does now show any Typescript maps.

But, on further inspection, even the app code does not contain correct source maps. For example, src/my-app.ts that I did not change from default:

export class MyApp {
  public message = 'Hello World!';
}

has a “map” like this:

var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import * as __au2ViewDef from './my-app.html';
import { customElement } from '@aurelia/runtime-html';
let MyApp = class MyApp {
    constructor() {
        this.message = 'Hello World!';
    }
};
MyApp = __decorate([
    customElement(__au2ViewDef)
], MyApp);
export { MyApp };

Dev tools confirm that - "source mapped from my-app.ts", when I try to put breaking point. So maps are there, but they are not correct.

It’s similar situation for Aurelia framework files, only that it says - "source mapped from index.js", and it shows already processed JavaScript in the map (variable names are lost). Small snipped of mapped code is here:

function o(t) {
    switch (typeof t) {
      case "number":
      case "bigint":
        return true;

      default:
        return false;
    }
}

So ideally, I would prefer debugging TypeScript source code, but it does not seem to work out of the box at all.

1 Like

There is a webpack loader for that source-map-loader | webpack

1 Like

I tried source-map-loader and did not achieve much. Now I see ES6+, but also processed JavaScript for framework sources. For example:

import { Metadata as t, Protocol as e, Registration as r, DI as s, firstDefined as i, mergeArrays as n, fromAnnotationOrDefinitionOrTypeOrDefault as o, isNumberOrBigInt as h, isStringOrDate as u, emptyArray as c, isArrayIndex as a, IPlatform as l, ILogger as f } from "@aurelia/kernel";

export { IPlatform } from "@aurelia/kernel";

export { Platform, Task, TaskAbortError, TaskQueue, TaskQueuePriority, TaskStatus } from "@aurelia/platform";

const d = t.getOwn;

const v = t.hasOwn;

const p = t.define;

const g = e.annotation.keyFor;

const b = e.resource.keyFor;

const w = e.resource.appendTo;

function m(...t) {
    return function(e) {
        const r = g("aliases");
        const s = d(r, e);
        if (void 0 === s) p(r, t, e); else s.push(...t);
    };
}

function E(t, e, s, i) {
    for (let n = 0, o = t.length; n < o; ++n) r.aliasTo(s, e.keyFrom(t[n])).register(i);
}

And my application files are not showing source code at all:

var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import * as __au2ViewDef from './my-app.html';
import { customElement } from '@aurelia/runtime-html';
let MyApp = class MyApp {
    constructor() {
        this.message = 'Hello World!';
    }
};
MyApp = __decorate([
    customElement(__au2ViewDef)
], MyApp);
export { MyApp };

Is there any chance that we get template in the CLI that is already setup and working, at least for application files debugging?

It’s time to try playing with Aurelia 2 and see if it’s feasible for some test projects. And it would help if template projects are in a better shape.

1 Like

The source loader definitely works in my au2 MDC demo app.
webpack.config.js
image

1 Like

@MaximBalaganskiy Your project is also showing intermediate ES-2017 JavaScript output in those source maps (like I described), not the TypeScript source code of the framework. For example, from runtime-html/dist/esm in your project:

function ot(t, e) {
    return function(i, s) {
        e(i, s, t);
    };
}

Only folder that shows proper TypeScript is one for kernel. So probably something to fix in framework build?

I’m trying to get here to the two issues:

  1. Project template Default TypeScript Aurelia 2 App is not configured correctly to support source debugging. Even of user’s own files in the project. That’s not good for Aurelia adoption.

So after adding "sourceMap": true in tsconfig.json in "compilerOptions" and switching Webpack from 'eval-cheap-source-map' to either 'inline-source-map' or 'source-map' I get almost OK source maps for my own project TypeScript files. For example, for:

export class MyApp {
  public message = 'Hello World!';
}

I get:

import * as __au2ViewDef from './my-app.html';
import { customElement } from '@aurelia/runtime-html';
@customElement(__au2ViewDef)
export class MyApp {
  public message = 'Hello World!';
}

So my guess is that ‘@aurelia/webpack-loader’ maybe interferes with source maps.

  1. I would like debug original framework files within the application context. This just for my own learning/curiosity and source-map-loader improved situation a bit for framework, but this maps are still off compared to original files. As I mentioned, kernel seems to work, but everything else is actually half-processed JavaScript, not TypeScript source.

I just added one aurelia package to the demo app loader config as a proof of concept. See my link to the webpack.config.js. Nothing wrong with the framework. Adding source maps comes with a price - no reason to include everything unless you actively debug other frameworks.

This is expected for your own view models source code - the loader does its magic and appends template import and some other code to your original TS. The rest of the files are not changed so nothing should prevent debugging. You can remove the au2 loader completely from your builds but you’ll have to add the missing code yourself.

Thank you! Having a reference config helped. I’ve added both @aurelia and aurelia folders. I’ll play around a bit more, but on the first look/debug it seems to be working fine.

That’s what I suspected. But, do you know - why Aurelia v1 (altough with aurelia-cli, not webpack) does not show any modifications in app.ts file? Is this approach of appending additional code to view-model .ts files new approach for v2? Can we just “ignore” change done by loader and debug source-map of original file?

V1 did its magic differently, v2 is more sustainable. It actually modifies your original TS files before transpiling and bundling them. If you managed somehow to keep source maps for original code it would not work well - they wouldn’t match the JS being executed.

Like I said, if this is critical, you can remove the loader and load templates and add decorators yourself but the end result would be the same code.