mynethome.de

10. Juni 2021 um 13:40 Uhr

Upgrade to NativeScript 8

ℹ New version of NativeScript CLI is available (8.0.2), run 'npm i -g nativescript' to update.

This is the message you see when you run a ns command at this time when you local installation is outdated.

So, lets see what it means to upgrade an app from running with NativeScript 7.2.1 to the recent 8.0.2.

Of course, there has been an interesting announcement blogpost that contains a short how-to-upgrade section and emphasises many great improvements that motivate for an upgrade. One of them is the great performance boot with webpack 5, another the ios-debug library.

Basically, doing an upgrade boils down to

npm i -g nativescript

ns migrate

Webpack 5 polyfill config missing

After ns migrate, the first attempt to run the app on iOS fails with a couple of error messages:


WARNING in ./node_modules/crypto-js/core.js 43:22-39
Module not found: Error: Can't resolve 'crypto' in '/Users/markus/src/mobile-app/node_modules/crypto-js'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
    - install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "crypto": false }
 @ ./node_modules/crypto-js/index.js 4:37-54
 @ ./src/app/services/PublicKeyService.ts 3:0-38 57:21-36 57:51-67
 @ ./src/app/app.module.ts 51:0-67 83:8-24 200:20-36
 @ ./src/main.ts 9:0-45 57:46-55

1 warning has detailed information that is not shown.
Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it.

ERROR in ./node_modules/nativescript-zip/zip-worker-ios.js (./node_modules/@nativescript/webpack/dist/loaders/nativescript-worker-loader/index.js!./node_modules/nativescript-zip/zip-worker-ios.js) 62:13-35
Module not found: Error: Can't resolve 'file-system' in '/Users/markus/src/mobile-app/node_modules/nativescript-zip'
 @ ./node_modules/nativescript-zip/zip.ios.js 18:35-89 63:35-89
 @ ./src/app/config/FileTraceWriter.ts 3:0-39 39:14-21
 @ ./src/main.ts 7:0-63 12:24-51

ERROR in ./node_modules/nativescript-fingerprint-auth/fingerprint-auth.ios.js 3:14-53
Module not found: Error: Can't resolve 'tns-core-modules/utils/utils' in '/Users/markus/src/mobile-app/node_modules/nativescript-fingerprint-auth'
 @ ./src/app/services/FingerprintService.ts 3:0-64 8:35-50
 @ ./src/app/app.module.ts 48:0-71 79:8-26 196:20-38
 @ ./src/main.ts 9:0-45 57:46-55

ERROR in ./node_modules/nativescript-secure-storage/secure-storage.common.js 3:26-74
Module not found: Error: Can't resolve 'tns-core-modules/application-settings' in '/Users/markus/src/mobile-app/node_modules/nativescript-secure-storage'
 @ ./node_modules/nativescript-secure-storage/secure-storage.ios.js 3:30-64
 @ ./src/app/services/SecureStorageService.ts 2:0-60 19:33-46
 @ ./src/app/app.module.ts 56:0-75 86:8-28 203:20-40
 @ ./src/main.ts 9:0-45 57:46-55

ERROR in ./node_modules/nativescript-zip/zip.ios.js 3:9-48
Module not found: Error: Can't resolve 'tns-core-modules/file-system' in '/Users/markus/src/mobile-app/node_modules/nativescript-zip'
 @ ./src/app/config/FileTraceWriter.ts 3:0-39 39:14-21
 @ ./src/main.ts 7:0-63 12:24-51

The nativescript-zip error can be fixed by replacing it with the more recently updated @nativescript/zip, but as the API has changed, we need to adjust a little bit of our code.

Also, update packages: @nativescript/fingerprint-auth and @nativescript/secure-storage

In order to fix the error shown at top regarding webpack 5 and polyfills, I need to extend the webpack.config.js to look like this:

const webpack = require("@nativescript/webpack");

module.exports = (env) => {
    webpack.init(env);

    webpack.mergeWebpack({ resolve: {
                                fallback: {
                                    "crypto": require.resolve("crypto-browserify"),
                                    "stream": require.resolve("stream-browserify") 
                                }
                            }
                        })

    return webpack.resolveConfig();
};

And install the two ..-browserify packages named in the config.

SCSS processing problems

After having this solved, I get some error regarding the CSS:

JS: Style: Css styling failed: Error: undefined:2:51: Parse error: Identifier is expected
JS:     1 |var[_ngcontent-c106]   resource[_ngcontent-c106];
JS:     2 | (()[_ngcontent-c106]   =[_ngcontent-c106] >  { // webpackBootstrap
JS: ---------------------------------------------------------^
JS:     3 |     var __webpack_modules__ = ({
JS:     4 |
JS: INFO: SplashScreen constructor
JS: Style: Css styling failed: Error: undefined:2:49: Parse error: Identifier is expected
JS:     1 |var[_ngcontent-c84]   resource[_ngcontent-c84];
JS:     2 | (()[_ngcontent-c84]   =[_ngcontent-c84] >  { // webpackBootstrap
JS: -------------------------------------------------------^
JS:     3 |     var __webpack_modules__ = ({
JS:     4 |
JS: INFO: User does not have PIN code configured, redirect to registration screen
JS: Style: Css styling failed: Error: undefined:2:51: Parse error: Identifier is expected
JS:     1 |var[_ngcontent-c104]   resource[_ngcontent-c104];
JS:     2 | (()[_ngcontent-c104]   =[_ngcontent-c104] >  { // webpackBootstrap
JS: ---------------------------------------------------------^
JS:     3 |     var __webpack_modules__ = ({
JS:     4 |
JS: Style: Css styling failed: Error: undefined:2:49: Parse error: Identifier is expected
JS:     1 |var[_ngcontent-c87]   resource[_ngcontent-c87];
JS:     2 | (()[_ngcontent-c87]   =[_ngcontent-c87] >  { // webpackBootstrap
JS: -------------------------------------------------------^
JS:     3 |     var __webpack_modules__ = ({
JS:     4 |
JS: DEBUG: RegistrationComponent initialized
JS: Error: Could not load CSS from app.css: Error: require's first parameter should be string

Looking at my scss files, I find a lot of imports starting with a ~. With the migration to Webpack 5, this is not required anymore, so we remove all the tildes:

@import "~@nativescript/theme/core";
@import "~@nativescript/theme/default";
@import '~@nativescript/theme/scss/variables';
@import '~@nativescript/theme/scss/variables/blue';

becomes

@import "@nativescript/theme/core";
@import "@nativescript/theme/default";
@import '@nativescript/theme/scss/variables';
@import '@nativescript/theme/scss/variables/blue';

But unfortunately, this does not solve my problem here.

To solve this, it turns out I have to do two things:

  1. follow a hint I got from rigor789 (kudos! :-) ) on the NativeScript slack community that „styleurls must reference files that end with .component.css or .component.scss“ – so I renamed all of them. This limitation is being worked on ATM and should be gone in short time (thus chances are good that this hint will not be relevant to you when reading this ;-) ).
  2. remove the devDependency to node-sass in my package.json as it was outdated and seemed to confuse the whole SCSS processing.

Startup Issue in iOS

Also, while investigating the CSS problem, the apps seems to build fine, but it doesn’t start up on iOS. Using the „Konsole“ app to access the device logs, I get this error:

Process exited: <FBApplicationProcess: 0x131e7a640; mobileapp (de.customer.application); pid: -1> -> <FBApplicationProcessExitContext: 0x2807e0180; exitReason: (none); terminationReason: (none)> {
    stateAtExit = <FBProcessState: 0x2809d82a0; pid: 1936; taskState: Running; visibility: Unknown>;
    terminationRequest = <FBSProcessTerminationRequest: 0x28117f340; label: "watchdog provision violated"; exceptionCode: "Watchdog Violation (0x8BADF00D)"; reportType: CrashLog; explanation: "process-launch watchdog transgression: de.customer.application exhausted real (wall clock) time allowance of 20.00 seconds">;
    watchdogContext = <FBProcessWatchdogEventContext: 0x2807f0390; event: process-launch>;
}

So, the app takes way too long to start up and gets stopped by iOS after 20s.

This turns out to be a side effect of the SCSS issue above – with that solved, the app also starts on iOS as expected.

Refresh / Repaint after navigate()

With NativeScript 8 and Angular 11, we see some view that do not update as expected and thus, e.g. just showing a blank view without text, icons and labels, as shown here:

Along with that, I can find an error in the log telling me CONSOLE WARN: Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?. After a short search I stumble upon the issue 2308 in nativescript-angular that seems to document whats going on and provides a workaround using ngZone.run() which works for me.

Upgrade Show on Youtube

While writing this, I realize that Alexander Ziskind and Nathan Walker (both part of the core NativeScript community, and at least Nathan if not both, part of the NativeScript TSC) did a Live-Stream doing a migration from NativeScript 6 to NativeScript 8:

On updated plugins…

As many plugins have been move during the transition to NativeScript 7 and 8, it´s confusing now that many are around under two names, e.g. nativescript-example and @nativescript/example. Also, with this transition, it’s not always clear where an release originates from, as Changelogs and Releasenotes are often not maintained. So look around, check for the scoped plugin names and see if there is an updated version of a plugin in quiestion. Help by providing pull requests to README.md files and other resources to clarify :-).

Angular 12

Finally, Angular 12 is available for NativeScript and the upgrade worked just like a charm for our app – go ahead :)

Have fun with mobile development leveraging your web dev skills :D

Einen Kommentar schreiben


Gravatar unterstützt

mynethome.de wird erstellt mit WordPress
Beiträge (RSS) und Kommentare (RSS)

(c) 2005 - 2015 Markus Schlichting