ionic-framework: bug: source maps are not loaded when debugging with chrome dev tools on device

Bug Report

Ionic Info

Ionic:

   ionic (Ionic CLI)             : 4.4.0 (/usr/local/lib/node_modules/ionic)
   Ionic Framework               : @ionic/angular 4.0.0-beta.16
   @angular-devkit/build-angular : 0.10.6
   @angular-devkit/schematics    : 7.0.6
   @angular/cli                  : 7.0.6
   @ionic/angular-toolkit        : 1.2.0

Cordova:

   cordova (Cordova CLI) : 8.1.2 (cordova-lib@8.1.1)
   Cordova Platforms     : android 7.1.4
   Cordova Plugins       : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 2.2.5, (and 4 other plugins)

System:

   Android SDK Tools : 26.1.1 (/Users/kelchen/Library/Android/sdk)
   ios-deploy        : 2.0.0
   ios-sim           : 7.0.0
   NodeJS            : v10.13.0 (/usr/local/bin/node)
   npm               : 6.4.1
   OS                : macOS
   Xcode             : Xcode 10.1 Build version 10B61

Describe the Bug TypeScript source maps are not present when debugging on an Android device/emulator.

Steps to Reproduce Steps to reproduce the behavior:

  1. Start a new project with ionic start sourcemaps blank --type=angular.
  2. Path into the project directory and run ionic cordova prepare android. Say Y to the prompt to install the Android platform.
  3. Run ionic cordova prepare android again. It will download/install the Cordova plugins that are part of the template.
  4. Run ionic cordova run android. This will build the app and deploy it to an Android emulator. You could also choose to deploy to a device by connecting a device configured for debugging and passing the --device flag to this command.
  5. After you get the app deployed and running on the emulator, in a Google Chrome tab go to chrome://inspect/#devices and inspect the Ionic app.
  6. In the Chrome DevTools under Sources use Cmd + P to search for the source file home.page.ts. It will not be found.

image

Related Code If you are able to illustrate the bug with an example, please provide a sample application via an online code collaborator such as StackBlitz, or GitHub.

Expected Behavior I expected the TypeScript source files to be present and debuggable with breakpoints in the Chrome DevTools.

Additional Context This is the same issue as #15152 which has since been closed and locked. While the OP of that issue decided to use Ionic DevApp as a workaround, our application uses a number of additional and different Cordova plugins that make using DevApp unsuitable. I would expect the browser dev tools to work like they have previously in Ionic 3 and like they currently do with iOS.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 18
  • Comments: 51 (8 by maintainers)

Commits related to this issue

Most upvoted comments

I’ve successfully got source maps on my device with following workaround:

add following to your ionic.config.json:

{
  [...],

  "hooks": {
    "build:after": "./attach-source-maps.js"
  }
}

Then create attach-source-maps.js in the root of your project with following content:

let fs = require('fs');
let path = require('path');

const TARGET_DIR = 'www';

module.exports = function (ctx) {
    console.log('=====================');
    console.log('attaching source maps');
    console.log('=====================');

    let files = fs.readdirSync(TARGET_DIR);

    files.forEach(file => {
        let mapFile = path.join(TARGET_DIR, file + '.map');
        let targetFile = path.join(TARGET_DIR, file);
        if (path.extname(file) === '.js' && fs.existsSync(mapFile)) {
            let bufMap = fs.readFileSync(mapFile).toString('base64');
            let bufFile = fs.readFileSync(targetFile, "utf8");
            let result = bufFile.replace('sourceMappingURL=' + file + '.map', 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + bufMap);
            fs.writeFileSync(targetFile, result);
        }
    });
};

At the end adjust script to your needs - eg disable it for prod build

https://github.com/ionic-team/ionic-framework/issues/16455#issuecomment-505397373 - This should be the accepted answer until the fix is provided by ionic team.

I have further enhanced @amb-jarek response to include SCSS sourcemaps as well, in case your angular app uses SASS like mine:

let fs = require('fs');
let path = require('path');

const TARGET_DIR = 'www';

module.exports = function (ctx) {
    console.warn('=====================');
    console.warn('WARNING: Sourcemaps have been manually added. Ensure this is disabled in production!');
    console.warn('=====================');

    let files = fs.readdirSync(TARGET_DIR);

    files.forEach(file => {
        let mapFile = path.join(TARGET_DIR, file + '.map');
        let targetFile = path.join(TARGET_DIR, file);
        if (path.extname(file) === '.js' && fs.existsSync(mapFile)
            || path.extname(file) === '.css' && fs.existsSync(mapFile)) {
            let bufMap = fs.readFileSync(mapFile).toString('base64');
            let bufFile = fs.readFileSync(targetFile, "utf8");
            let result = bufFile.replace('sourceMappingURL=' + file + '.map', 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + bufMap);
            fs.writeFileSync(targetFile, result);
        }
    });
};

Note: This fix increases your bundle size (apk) and should be manually disabled in production. Before taking a production build ensure the following hook scripts are removed from ionic.config.json file.

"hooks": {
    "build:after": "./attach-source-maps.js"
  }

Hi everyone,

As @dtarnawsky mentioned in https://github.com/ionic-team/ionic-framework/issues/16455#issuecomment-1220050827, Capacitor 4.1.0 added a new option to inline all source maps when syncing. This makes it possible to get the latest source maps when debugging in a Chromium-based browser. As a result, I am going to close this issue.

See Damian’s comment above for more information.

I have this problem too. I am only able to debug by putting in console.log statements. Please fix this!

In Capacitor 4.1.0 there is now an option that allows debugging the Android Web View in Chrome/Edge. You run: npx cap sync --inline

The argument –inline makes sure the source maps are inlined and you can use chrome://inspect/ or edge://inspect/ to debug into your Typescript code (under the webpack:// tree). debug-android-webview

Struggled with the same issues as described here but didn’t want to use ngx-build plus, because the build times increased a lot. Just got it to work however using capacitors live reload tool, which additionally adds the advantage of live reloading on the device. When I use ionic cap run android -l --address=my.local.ip --source-map (where my.local.ip is the local ip of the pc running the build server) to deploy to the android device, the source maps are available to the debugger. I guess thats because they aren’t loaded of the device anymore but rather from the development server. More on Capacitor live reloading here.

Having this too, just bumping the issue…

$ ionic info

Ionic:

   Ionic CLI                     : 5.0.3 (C:\Users\maxim\AppData\Roaming\npm\node_modules\ionic)
   Ionic Framework               : @ionic/angular 4.5.0
   @angular-devkit/build-angular : 0.13.9
   @angular-devkit/schematics    : 7.2.4
   @angular/cli                  : 7.3.9
   @ionic/angular-toolkit        : 1.5.1

Cordova:

   Cordova CLI       : 9.0.0 (cordova-lib@9.0.1)
   Cordova Platforms : android 8.0.0
   Cordova Plugins   : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 3.1.2, (and 18 other plugins)

Utility:

   cordova-res : 0.3.0
   native-run  : 0.2.5

System:

   Android SDK Tools : 26.1.1 (C:/Users/maxim/AppData/Local/Android/Sdk)
   NodeJS            : v10.15.3 (C:\Program Files\nodejs\node.exe)
   npm               : 6.9.0
   OS                : Windows 10

Added to my package.json:

  "config": {
    "ionic_bundler": "webpack",
    "ionic_source_map_type": "#inline-source-map"
  },

Running ionic cordova run android --livereload --ssl --source-map, I can’t see any source maps, can’t access them on the server and they are not referenced in the JS files.

Running ionic cordova run android --source-map, I can see source maps created, they are copied to the phone and they are references in the JS files. But I still can’t see any webpack:// folder in the Sources tab of Chrome Dev Tools.

Any updates on this? It is very annoying

@itziksha : thank-you for bringing that up. I 100% agree with you and started discussing that with the Capacitor team this morning. They have asked me to open an internal Jira ticket for them to track. If you do create a feature request as @liamdebeasi suggested, please let me know and I will attach it to the internal Jira ticket.

@kensodemann @liamdebeasi

I opened a feature request here - https://github.com/ionic-team/capacitor/issues/5900

Thanks.

Hi there,

I do not work on the Capacitor project, so I am unable to assist with this feature request. I recommend opening a feature request on the Capacitor repo.

Hi everyone,

As @dtarnawsky mentioned in #16455 (comment), Capacitor 4.1.0 added a new option to inline all source maps when syncing. This makes it possible to get the latest source maps when debugging in a Chromium-based browser. As a result, I am going to close this issue.

See Damian’s comment above for more information.

@liamdebeasi liamdebeasi Thanks for the update! Is it possible to add the ‘inline’ option also to ‘copy’ command, for example: “npx cap copy --inline”? I guess that copy command is being used much more often than sync (at least I use it much more for fast sync of the web folder) Since ‘inline’ related to source maps, I think it’s usable to have it in this command. Thanks 😃

I’m not sure if it’s changed recently, but using Capacitor with Live Reload will result in source maps working on Android (at least it does for us).

I know that doesn’t help if the app is using Cordova or there’s a desire to not use Live Reload though.

Hope that could help!

To whom it may concern, here is the approach I implemented to enable debugging with source maps support on Android devices

  • install ngx-build-plus by running npx ng add ngx-build-plus This will install the required npm package and update angular.json as required For more details please see https://github.com/manfredsteyer/ngx-build-plus
  • create new file build-customization-plugin.js in the project root directory and add the below content in this file
var merge = require('webpack-merge');

exports.default = {
    config: function (cfg) {
        const strategy = merge.strategy({
            'devtool': 'replace',
        });

        return strategy(cfg, {
            devtool: 'inline-source-map'
        });
    }
}
  • run ng build --eval-source-map --plugin ~build-customization-plugin.js from the root directory to build the project with source maps to debug on Android devices

This is a better approach then changing angular/cli source 😃

The above does not work for the latest angular cli (@angular-devkit/* with version 0.1000.0 and above)

To enable this workaround again please update build-customization-plugin.js file in the project root directory to make it look as below

const merge = require('webpack-merge');
const webpack = require("webpack");

exports.default = {
    config: function (cfg) {

        // first, we replace devtool in the webpack used by the angular cli to have the value 'inline-source-map'
        const strategy = merge.strategy({
            'devtool': 'replace',
        });
        const result = strategy(cfg, {
            devtool: 'inline-source-map'
        });

        // then we find SourceMapDevToolPlugin and remove it
        // This is because we should never use both the devtool option and plugin together.
        // The devtool option adds the plugin internally so you would end up with the plugin applied twice.
        // See https://webpack.js.org/configuration/devtool/
        const index = result.plugins.findIndex((plugin) => {
            return plugin instanceof webpack.SourceMapDevToolPlugin;
        });
        result.plugins.splice(index, 1);

        return result;
    }
}

All the rest is the same

Is official Live Reload support planned? A full rebuild for every small change is the worst way to work.

I’m on Cordova + Angular 9 + Ionic stack, any kind of fast dev-work seems impossible.

https://github.com/ionic-team/ionic-app-scripts/issues/822 https://github.com/ionic-team/ionic-app-scripts/issues/1354

I hope this issue doesn’t get closed without a fix like the previous threads.

@y0nd0

  1. Finding a way to set the correct url of the device. Maybe a setting in Cordova? I don’t know. But I think, even if the url contains the ip address of the device, it will not work. Because it’s a local app. You cannot access app files through your network. Only if the app provides it using a server. Ideas are welcome. But I think that this possible solution will not work.

Serving the files from the computer is exatly what is happening with livereload as i mentioned here. You need to set the url to use by using the host flag (which has deprecated the address flag I described orginally). While using this I realized, that this run sets a server.url Parameter within the capacitor.config.json. Maybe this can be used without live-reload too.

Angular CLI will never allow devtools options for inline-source-maps. Search the Angular CLI issues. I cannot understand this decision. Anyway… The problem with the DevTools in Chromium (device inspect) is that the url of source maps refer to “localhost”. The localhost of the device. But the DevTools does not know the url of the device. So it is trying to fetch from the localhost of the computer. So, what can we do?

  1. Finding a way to set the correct url of the device. Maybe a setting in Cordova? I don’t know. But I think, even if the url contains the ip address of the device, it will not work. Because it’s a local app. You cannot access app files through your network. Only if the app provides it using a server. Ideas are welcome. But I think that this possible solution will not work.

  2. Tell Angular CLI to use inline-source-maps. But the Angular CLI developer team decided against this option. So you have to use 3rd party libs to get access to the webpack.config.js. Or reject the Angular CLI and use Webpack and build by your own scripts. That is probably very time-consuming and painful.

  3. Use a node script to add the map-files as base64 string to the js-files. Build your own inline-source-map assignment. This “hack” has limitations. But it might generally work with apk bundles. I think this does not work with live reload.

Conclusion: Sadly the Angular CLI team will not provide a inline source map option. See issue Life would be a lot easier with this option. … That is disappointing.

I’ve successfully got source maps on my device with following workaround:

I use Ionic V5 and React here some modification at your workaround.

I suggest to create the scripts on the root project and to put the attach-source-maps.js here so you must modify ionic.config.json:

   "hooks":{
     "build:after": "./scripts/attach-source-maps.js"
   },

const TARGET_DIR = ‘www’;

Then the TARGET_DIR dir on the script must be modified as follow:

const TARGET_DIR = 'build/static/js';

Then you must add on your tsconfig.json file:

  "include": [
    "src", "scripts"
  ]

At the end adjust script to your needs - eg disable it for prod build

This still valid.

To whom it may concern, here is the approach I implemented to enable debugging with source maps support on Android devices

  • install ngx-build-plus by running npx ng add ngx-build-plus
    This will install the required npm package and update angular.json as required For more details please see https://github.com/manfredsteyer/ngx-build-plus
  • create new file build-customization-plugin.js in the project root directory and add the below content in this file
var merge = require('webpack-merge');

exports.default = {
    config: function (cfg) {
        const strategy = merge.strategy({
            'devtool': 'replace',
        });

        return strategy(cfg, {
            devtool: 'inline-source-map'
        });
    }
}
  • run ng build --eval-source-map --plugin ~build-customization-plugin.js from the root directory to build the project with source maps to debug on Android devices

This is a better approach then changing angular/cli source 😃

Same problem. This occurs with either of Capacitor or Cordova wrapper.

Tried adding sourcemaps = 'inline-source-map'; to C:\dev\ionic\sqlite-test\node_modules\@angular-devkit\build-angular\src\angular-cli-files\models\webpack-configs\browser.js as suggested here, but did not help.

Debugging the TypeScript when running on an emulator (or device) is still very essential when the app replies on plugin(s)