2. Juni 2021 um 15:01 Uhr

Upgrading Plugins for NativeScript 7 and following

In my previous blogpost, I wrote about updating an app from NativeScript 6.5 to 8, taking 7 as the necessary step in between. The app is basically working but major functionality is missing as it crashes as soon it tries to execute functions from an internally maintained plugin.

Must read when upgrading plugins:

That post offers a 6-step procedure to convert a plugin which I will follow.

Basic steps for migration are the same as for the app: Remove deep imports from core, fix references.d.ts file, etc

Step 3 about @NativeClass decorator needs some more attention as we have implemented quite a lot of the iOS part of the plugin directly in TypeScript.

As with the move to Angular 10, some Angular specific consideration have to be made for plugins as described in that blogpost. But as we did not choose to implement such in our plugin, I´m fine here and do not need to take care of specifics.

To migrate the sample apps, I need to take basically the same steps as I did for the main application.

After I have the demo-apps migrated and get to the point to test the plugin using these, I run into a problem on iOS:

Our iOS specific code (TypeScript using ObjC interfaces) contains static methods and calls to them, e.g. a class

export ViewControllerWrapper extends UIViewController {

    public static initWithOptionsAndStrategy(options: LogicOptions, logicStrategy: LogicStrategy): ViewControllerWrapper {

            return wrapper;

and a call to that initializer method:

const view = ViewControllerWrapper.initWithOptionsAndStrategy(...);

The error I get during runtime (build is fine) is CONSOLE LOG: Error: rejected Cannot read property 'initWithOptionsAndStrategy' of undefined. That means that the javascript resulting from the transpilation does not have a valid referenece to my static method.

Also, I get this warning during build

WARNING in /Users/markus/src/plugin/src/ios/ViewControllerWrapper.ts 269:55-91
"export 'ViewControllerWrapper' was not found in './ViewControllerWrapper'
 @ /Users/markus/src/plugin/src/SomeAction.ts
 @ ./app.ts

The solution to this is described in the best-practices articles for @NativeClass in the NativeScript docs. I need to seperate the export from the class declaration as the @NativeClass decorator changes the JS syntax and thus breaks the export.

So, instead of

export class CustomClass extends NSObject {}

we need to do

class CustomClass extends NSObject {}

export { CustomClass }

On testing my plugin in the app (build & package a tgz locally and reference it from the app´s package.json with file:/path/to/plugin.tgz instead of the version number), I got errors sayint Uncaught ReferenceError: NativeClass is not defined.

Which appeared like an packaging error to me, so I had to revise the webpack.config and ths tsconfig.

It turned out that my tsconfig.json was actually missing the following that takes care for the NativeClass items:

"plugins": [
        "transform": "@nativescript/webpack/transformers/ns-transform-native-classes",
        "type": "raw"

Finally, I stumbled over a "declaration: false"setting in the plugin´s tsconfig.json – with this set, the generated code in the packaged plugin will not be useable to the app as typescript will not find the expected code to import classes. It has to be set to true.

And with this, the migration of the custom plugins is complete and we have our app migrated to NS 7. 🎉

Einen Kommentar schreiben

Gravatar unterstützt wird erstellt mit WordPress
Beiträge (RSS) und Kommentare (RSS)

(c) 2005 - 2015 Markus Schlichting