'Cannot read property 'browser' of undefined' in Nativescript + Angular using Apache thrift

Viewed 1642

I`m trying to use Apache Thrift with my Angular & Nativescript project, but by the 'tns preview --bundle' or any another tns command i get

TypeError: Cannot read property 'browser' of undefined
File: "<unknown>, line: 1, column: 265

Apache Thrift v. 0.11.0 / 1.0.0dev, Angular v. 7.1.0, Nativescript v. 5.1.0

In platforms/android/app/src/main/assets/app/vendor.js i can see:

/* istanbul ignore next */
if (undefined.browser) {
    defaultEncoding = 'utf-8'
} else {
    var pVersionMajor = parseInt(undefined.version.split('.')[0].slice(1), 10)

When i expected something like global.process.browser, than i can find at another peaces of vendor.js. And in another peaces i can see something like undefined.nextTick(...) etc. I know it is some kind of Babel problem, but i have no idea how to fix it.

I use thrift --gen js:node script to generate my thrift files (it doesn't make sense in error). Without them all works cool, but then i'm trying to execute any thrift-generated file/any module from thrift, i get an exception above. my_component.ts

import { Component, OnInit } from '@angular/core';
import { TJSONProtocol } from 'thrift'; // or anything else 

@Component({...});

export class MyComponent implements OnInit {
    ngOnInit () {
        // console.log(TJSONProtocol); // Uncomment this string to get an exception.
    }
    constructor() {...};
}

There is any problems provided by ng serve. I hope here is any way to fix this mistake and make thrift compatible with nativescript or any another way to use thrift with nativescript.

2 Answers

The problem was in default webpack.config.js, provided by Nativescript. At:

plugins: [
        // Define useful constants like TNS_WEBPACK
        new webpack.DefinePlugin({
            "global.TNS_WEBPACK": "true",
            "process": undefined,
        })

You need to remove line "process": undefined.

When an application uses browser data (document, window, etc), you need to make sure that this data is accessed only when the application is running in the browser itself, which is not the case in nodejs.

To do this, place the code snippet you need to use within a check like:

if (typeof window !== 'undefined') {
    // here runs your code...
    console.log(TJSONProtocol);
}

See: https://angular.io/guide/universal#working-around-the-browser-apis

Related