Missing TypeScript source files when using Browserify in Android

Hi,
I recently updated my Ionic 2 project written in TypeScript to the latest version (from beta 19 to beta 25), and I switched from webpack to browserify, too. While using webpack, I was able to debug the project using WebStorm and Chrome or the Chrome Developer Tools inspecting the WebView in a real Android device. However, using browserify, I cannot debug the project anymore on a real device. The source folder appears if the application is launched in Chrome or with the live reload mode in Android, but when using ionic run android the WebView inspected from the DevTools does not include/show source folder, so there is no way of placing breakpoints in TypeScript files.

Does anyone faced the same problem? How can I solve it? Any help would be really appreciated.

Thanks in advance,
Xavi

How to reproduce the problem:

  1. Create a new Ionic 2 project with --v2 --ts (for example with the tabs template).
  2. type:
    $ ionic platform add android
    $ ionic run android
  3. Open Chrome and go to this location:
    chrome://inspect/#devices
  4. Your real device name attached to a USB port should appear at this page, click on inspect to debug the WebView.
  5. source folder is missing and TypeScript files cannot be debugged.

Edit: I have updated my build and config files with the latest changes available at https://github.com/driftyco/ionic2-app-base/tree/typescript, but the problem still persists.

Additional information

My system information:

Cordova CLI: 6.1.1
Ionic Framework Version: 2.0.0-beta.6
Ionic CLI Version: 2.0.0-beta.25
Ionic App Lib Version: 2.0.0-beta.15
ios-deploy version: 1.8.6
ios-sim version: 5.0.8
OS: Mac OS X El Capitan
Node Version: v4.4.3
Xcode version: Xcode 7.2.1 Build version 7C1002

gulpfile.ts:

var gulp = require('gulp'),
    gulpWatch = require('gulp-watch'),
    del = require('del'),
    runSequence = require('run-sequence'),
    argv = process.argv;


/**
 * Ionic hooks
 * Add ':before' or ':after' to any Ionic project command name to run the specified
 * tasks before or after the command.
 */
gulp.task('serve:before', ['watch']);
gulp.task('emulate:before', ['build']);
gulp.task('deploy:before', ['build']);
gulp.task('build:before', ['build']);

// we want to 'watch' when livereloading
var shouldWatch = argv.indexOf('-l') > -1 || argv.indexOf('--livereload') > -1;
gulp.task('run:before', [shouldWatch ? 'watch' : 'build']);

/**
 * Ionic Gulp tasks, for more information on each see
 * https://github.com/driftyco/ionic-gulp-tasks
 *
 * Using these will allow you to stay up to date if the default Ionic 2 build
 * changes, but you are of course welcome (and encouraged) to customize your
 * build however you see fit.
 */
var buildBrowserify = require('ionic-gulp-browserify-typescript');
var buildSass = require('ionic-gulp-sass-build');
var copyHTML = require('ionic-gulp-html-copy');
var copyFonts = require('ionic-gulp-fonts-copy');
var copyScripts = require('ionic-gulp-scripts-copy');

var isRelease = argv.indexOf('--release') > -1;

gulp.task('watch', ['clean'], function(done){
    runSequence(
        ['sass', 'html', 'fonts', 'scripts'],
        function(){
            gulpWatch('app/**/*.scss', function(){ gulp.start('sass'); });
            gulpWatch('app/**/*.html', function(){ gulp.start('html'); });
            buildBrowserify({ watch: true }).on('end', done);
        }
    );
});

gulp.task('build', ['clean'], function(done){
    runSequence(
        ['sass', 'html', 'fonts', 'scripts'],
        function(){
            buildBrowserify({
                minify: isRelease,
                browserifyOptions: {
                    debug: !isRelease
                },
                uglifyOptions: {
                    mangle: false
                }
            }).on('end', done);
        }
    );
});

gulp.task('sass', buildSass);
gulp.task('html', copyHTML);
gulp.task('fonts', copyFonts);
gulp.task('scripts', copyScripts);
gulp.task('clean', function(){
    return del('www/build');
});

tsconfig.json (note that I removed sourceMap: true used by webpack):

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false
  },
  "filesGlob": [
    "**/*.ts",
    "!node_modules/**/*"
  ],
  "exclude": [
    "node_modules",
    "typings/main",
    "typings/main.d.ts"
  ],
  "compileOnSave": false,
  "atom": {
    "rewriteTsconfig": false
  }
}

packages.json:

{
  "dependencies": {
    "angular2": "2.0.0-beta.15",
    "es6-shim": "^0.35.0",
    "ionic-angular": "2.0.0-beta.6",
    "ionic-native": "^1.1.1",
    "ionicons": "3.0.0",
    "ng2-translate": "^1.11.1",
    "rxjs": "5.0.0-beta.2"
  },
  "devDependencies": {
    "del": "2.2.0",
    "gulp": "3.9.1",
    "gulp-watch": "4.3.5",
    "ionic-gulp-browserify-typescript": "^1.1.0",
    "ionic-gulp-fonts-copy": "^1.0.0",
    "ionic-gulp-html-copy": "^1.0.0",
    "ionic-gulp-sass-build": "^1.0.0",
    "ionic-gulp-scripts-copy": "^1.0.1",
    "run-sequence": "1.1.5"
  },
  "name": "demo",
  "description": "demo: An Ionic project",
  "cordovaPlugins": [
    "cordova-plugin-device",
    "cordova-plugin-console",
    "cordova-plugin-whitelist",
    "cordova-plugin-splashscreen",
    "cordova-plugin-statusbar",
    "ionic-plugin-keyboard",
    "cordova-plugin-inappbrowser",
    {
      "variables": {
        "SENDER_ID": "XXXXXX"
      },
      "locator": "https://github.com/phonegap/phonegap-plugin-push",
      "id": "phonegap-plugin-push"
    },
    "cordova-sqlite-storage",
    "cordova-plugin-file",
    "cordova-plugin-file-transfer"
  ],
  "cordovaPlatforms": [
    "ios",
    "android"
  ]
}

@xme The source-maps are generated in the same folder as the JS files, i.e. www/build/js. I’ll recommend you to check the settings of WebStorm and see if it can’t be configured to use them from this location. Otherwise you’ll need to modify your build process a bit and copy the source-maps to the desired folder after the build task is completed.

Hi,

@iignatov Probably I did not explained myself clearly. I would like to add some clarifications:

  1. The transpiled JavaScript is there, under www/build/js, and it can be debugged. However, I don’t want to debug the transpiled JavaScript, I want to debug the original TypeScript code.

  2. WebStorm can be safely ignored, because all what I am typing and doing is through the command line, and displayed at Chrome or a WebView, always debugged with the Chrome DevTools.

  3. The “package” generated for a browser with ionic serve, or ionic run browser and for a real device using live reload with ionic run android -l, contain a folder named source, where my original TypeScript files are available and they can be debugged. But, when running ionic run android, the apk package uploaded to the real device does not have this source folder.

  4. source folder has three folders inside: app, node_modules and typings.

  5. My project configuration may not be the problem, since this behaviour can be reproduced easily on a newly created project from scratch.

  6. Put it in another way, what I am suggesting is that, maybe, ionic-gulp-browserify-typescript or its default configuration in gulpfile.ts is doing something strange when generating the app for an Android device without live reload.

Regards,
Xavi

@xme Ok, now I understand. But actually when using ionic serve there’s neigther a “package” generated nor a folder source gets created. IMHO the folder source that you’re seeing in Chrome Dev Tools is a virtual folder (i.e. it doesn’t really exist) - notice that it looks different than the other folders and also if you open a .ts file you’ll notice at the bottom “(source mapped from app.bundle.js)”. I guess that Chrome uses the information in the source-map (.map) generated under www/build/js and shows it in a folder view.

I’m not quite sure why this doesn’t work when you use ionic run android though, as the source-map should be included by default if you haven’t specified the --release flag.

I can’t test it right now, but I’ll take a look at it later today or over the weekend.

@iignatov
Hi,
Thanks a lot for your time and patience. I’m new to the world of web development (I came from C++ and Java) and my knowledge and vocabulary it’s a bit limited.

  1. When I said “package”, I mean “the transpiled/compiled sources served to the browser or send to the device” as a general idea.
  2. I did not specify the --release flag.
  3. I will try to move the project to webpack in order to see what happens.
  4. You’re right, the source folder has another color and it seems to be some kind of virtual folder, but how it works is beyond the scope of my knowledge. I will try to find more information about it.

Thanks again :slight_smile:,
Xavi

@xme For moving to webpack check out the Browserify vs. webpack section in this forum topic.

@iignatov
Hi,
Thanks, for the information. I followed the steps, but I added "sourceMap": true to the tsconfig.json file and devtool: 'source-map' to the webpack.config.js file, as I did with Ionic 2 beta 19. Unfortunately, the result is exactly the same. The webpack//: entry in Chrome Dev Tools where the TypeScript sources are available, only appears at the browser or using live reload at the device. When a WebView without live reload is debugged, only the transpiled JavaScript is available under www/build/js.

Regards,
Xavi

@xme You can check if the source-maps are included in the APK files under:

APP_ROOT_PATH/platforms/android/build/outputs/apk

You should be able to open them with any program that supports ZIP files, e.g. 7-Zip.

If there is a source-map file under assets/www/build/js then it should work I guess.

Hi,
@iignatov
I uncompressed the apk and checked that the source map file app.bundle.s.map is under assets/www/build/js (its size is 7 MB), so the file is there. The problem maybe is how DevTools loads or access this map file. However, with Ionic 2 beta 19 and webpack there was no problem. I am running out of ideas and options…
Regards,
Xavi

Hi @xme

We have a sample that shows how to use Visual Studio with Ionic2 https://github.com/Microsoft/build2016-vsmobile

Hi,
@rido I am sorry, but I should have said that we develop on OS X, so I cannot use Visual Studio. Thanks anyway ;).
@iignatov I made no progress on this question. Since it is something that can be reproduced on a project created from scratch, shall I post this issue on a bug tracker or request as feature? If so, where? I am doing things with Cordova that do not support live reload (similar to this).
Regards,
Xavi

I also checked that the file is generated as expected but I haven’t got the chance to look closer into this so I have no idea what the problem might be.

You could try to compare the packages and see what is the difference between them.

Sure, you could create a new issue for either ionic-cli or ionic-gulp-tasks.

Same problem here, app.bundle.js.map is correctly included in apk in \platforms\android\build\outputs\apk\android-debug.apk\assets\www\build\js\ folder but the corresponding typescript source files are not available for debugging in chrome developer tools, only the transpiled js is. Does anyone know why yet?

Hi,
@iignatov @smblogic
I finally opened a ticked for the issue in ionic-gulp-tasks at GitHub.

@iignatov Anyway to use systemJS in ionic2 app

Hi,
@iignatov
The problem I described can be considered as solved or obsolete, because:

  1. I recently reinstalled my machine from scratch, with this configuration:

My system information:

Cordova CLI: 6.3.1
Ionic Framework Version: 2.0.0-beta.11
Ionic CLI Version: 2.0.0-beta.37
Ionic App Lib Version: 2.0.0-beta.20
ios-deploy version: 1.9.0 
ios-sim version: 5.0.11 
OS: Mac OS X El Capitan
Node Version: v4.6.2
Xcode version: Xcode 8.2 Build version 8C38 

packages:

{
  "dependencies": {
    "@angular/common": "2.0.0-rc.4",
    "@angular/compiler": "2.0.0-rc.4",
    "@angular/core": "2.0.0-rc.4",
    "@angular/platform-browser": "2.0.0-rc.4",
    "@angular/platform-browser-dynamic": "2.0.0-rc.4",
    "@angular/http": "2.0.0-rc.4",
    "@angular/forms": "0.2.0",
    "es6-shim": "0.35.1",
    "ionic-angular": "2.0.0-beta.11",
    "ionic-native": "1.3.21",
    "ionicons": "3.0.0",
    "reflect-metadata": "0.1.8",
    "rxjs": "5.0.0-beta.6",
    "zone.js": "0.6.12",
    "ng2-translate": "2.2.2"
  },
  "devDependencies": {
    "del": "2.2.0",
    "gulp": "3.9.1",
    "gulp-watch": "4.3.5",
    "ionic-gulp-browserify-typescript": "2.0.0",
    "ionic-gulp-fonts-copy": "^1.0.0",
    "ionic-gulp-html-copy": "^1.0.0",
    "ionic-gulp-sass-build": "^1.0.0",
    "ionic-gulp-scripts-copy": "^2.0.0",
    "ionic-gulp-tslint": "^1.0.0",
    "tslint-ionic-rules": "0.0.4",
    "run-sequence": "1.1.5"
  },
  ...and more
}

and using Chrome 55.0.2883.95 the problem is gone, I can debug Typescript files.

  1. The Ionic 2 RC build system is no longer using gulp.

Best,
Xavi

PS: I will close the ticked.