NativeScript team has done it again and delivered the latest Angular 10 support for NativeScript. The new release of @nativescript/schematics
package marks another great milestone in the journey for unifying codebases across web and mobile, as well as improving the developer experience while building NativeScript with Angular. If you are new to @nativescript/schematics
you need to have a look at the package source repository on Github to learn more about it. If you want to give it a shot now, you can do the following:
npm i -g @angular/cli // You could be needing to prefix sudo on GNU/Linux and other Unix-like OSes.
npm i -g nativescript // You could be needing to prefix sudo on GNU/Linux and other Unix-like OSes.
npm i -g @nativescript/schematics // You could be needing to prefix sudo on GNU/Linux and other Unix-like OSes.
ng new workspace
cd workspace
ng add @nativescript/schematics --skipAutoGeneratedComponent
// start apps:
npm run ios
npm run android
ng serve
Based on https://github.com/NativeScript/nativescript-schematics/pull/286#issuecomment-666116443
Updating your project now actually prepares you for the upcoming NativeScript 7 release as it relies on the current running @nativescript/core rc's which use es2017 target builds for compliance with Angular 10 since es5 support was officially dropped by default. This is a wonderful and welcome change upcoming in NativeScript 7 and will allow nice optimizations with the v8 engine, advanced tree shaking and aligning your NativeScript code with modern JS ecosystems.
If you already use NativeScript with Angular and want to stay up-to-date with the project releases, here's your guide to upgrade your project to Angular 10:
WARNING: Make sure to have your project changes committed and pushed to your remote repository. The process involves some changes that would be beneficial to have a changeset diff on against your current project
package.json
package.json
is the ultimate reference for what your project contains and depends on. For that, it currently enlists previous versions of your project dependencies. Nathan Walker, a TSC member, has explained and put in place the form in which package.json
needs to look like. Based on his comment I created a sample node
script that takes your current package.json
and using Spread syntax
it updates the packages that needs to be updated without removing your other project dependencies. The script additionally removes the platform version definitions from nativescript
section of your package.json
, as upgrading the platforms versions alongside @nativescript/angular
packages is an advised step. To use the script:
package.json
is at).node update_package.tns-ng10.js
.🎉 Updated package.json!
.
a. If not, and the message you received is "package.json.bak" was found...
, it is possible you already attempted to run script before and that your package.json
file is already updated.
b. To confirm, open package.json
and confirm whether @nativescript/angular
package version is set to ~10.0.0
.
c. If so, you probably have your package.json
already updated by earlier run of the script.
d. If not, delete package.json.bak
.
e. If issue is still persistent, let me know so I can work with you on it.package.json
file and make sure it looks fine.webpack.config.js
.
webpack.config.js
you would need to keep them in mind to re-implement them afterwards as NativeScript packages would attempt to create updated webpack.config.js
file when it is not present.npm run clean && npm run PLATFORM
where PLATFORM is the platform you are attempting to deploy the app for.
tns run PLATFORM
would result in non-working app due to required --no-hmr
argument to be passed. using npm run PLATFORM
shall give you a shorthand access to the action needed.preview
mode using NativeScript Preview apps on Android and iOS is not possible as of this moment as an update for Preview apps is required and is undergoing: https://github.com/NativeScript/nativescript-schematics/pull/286#issuecomment-667577731If you prefer to do things yourself. Here's what you need to do:
package.json
packages versions as per this comment.nativescript
section, but keep id
property.webpack.config.js
.npm run clean && npm run PLATFORM
where PLATFORM is the platform you are attempting to deploy the app for.NativeScript with Angular 10 brings more standardized experience on using the framework. One aspect is importing the tools and classes provided by the framework. This will help improve your project's future upgrade resilience to framework changes since the core team can make improvements under the hood to organization of the framework classes without affecting tons of deep import paths which can be wildly varied from one project to the next. This means some old import styles in your project need to be updated. To do so use your IDE or editor to search for the following terms and replace them, as:
tns-core-modules
WARNING: Your search results would include results from
package.json
,package-lock.json
,package.json.bak
, andwebpack.config.js
. You should not attempt to modify these files.
This package contains all the core tools and classes of NativeScript. You would need to search for any import statement importing from tns-core-modules
and replace it with @nativescript/core
. If you have an import statement, importing from a nested module, such as:
import { screen } from 'tns-core-modules/platform';
you would need to replace the import as top-level to become:
import { screen } from '@nativescript/core'; // and not @nativescript/core/platform
// Still will give error, read next...
The change from tns-core-modules
to @nativescript/core
has also had some classes names changed, such as screen
earlier which becomes Screen
. You can figure this out by hitting your IDE or editor auto-complete combination (Usually, Ctrl+Space, Cmd+Space) to list all classes available in @nativescript/core
package and find the possible new class name.
Some other imports are invalid totally now such as:
import * as applicationSettings from 'tns-core-modules/application-settings';
which need to be imported as:
import { ApplicationSettings } from '@nativescript/core';
You will be done with this step when you don't have any results when searching for the terms tns-core-modules
or @nativescript/core/
in your codebase.
Top-level import is suggested in this comment and it was essential for my projects to be upgraded to Angular 10. Having deep imports seem to break my projects, and simply changing to top-level importing based on the comment suggestion resolved my upgrade issues.
nativescript-angular
WARNING: Your search results would include results from
package.json
,package-lock.json
,package.json.bak
, andwebpack.config.js
. You should not attempt to modify these files.
Similarly, you would need to replace all imports to nativescript-angular
to @nativescript/angular
. Same top-level rule apply here, so if after fixing your imports you end up with search results for @nativescript/angular/
you would need to drop those deep import statements and rebase them for top-level imports. A common one is the import statement in app-routing.module.tns.ts
which gets created by @nativescript/schematics
as:
import { NativeScriptRouterModule } from 'nativescript-angular/router';
which, if you just change to:
import { NativeScriptRouterModule } from '@nativescript/angular/router';
it would still break the app, but you need to completely drop the deep import as:
import { NativeScriptRouterModule } from '@nativescript/angular';
Some classes are not available after the upgrade such as DEVICE
which used to be imported for injecting in your Angular classes. You now need to simply use Device
from @nativescript/core
without injecting it.
You will be done with this step when you don't have any results when searching for the terms nativescript-angular
or @nativescript/angular/
in your codebase.
As mentioned earlier, to run your NativeScript with Angular 10 app you can either use:
npm run PLATFORM
tns run PLATFORM --no-hmr
as compiling the app would fail if --no-hmr
argument is not present when using tns
.
If you ever used this nice hack to add re-routing to HMR
you would need to undo it as it will break your app. you simply need to comment the line import './livesync-navigation.tns';
in your main.tns.ts
file.
Lastly, if you get the following error:
com.tns.NativeScriptException: Calling js method onCreate failed
Followed with following error on Android and iOS respectively:
java.lang.IllegalArgumentException: Cannot add a null child view to a ViewGroup
Root should be either UIViewController or UIView
then, you probably are facing an interesting issue I faced, which is having app.component.tns.html
look like:
<page-router-outlet></page-router-outlet>
And, wrapping page-router-outlet
with any layout component such as GridLayout
or StackLayout
fixed the issue. So, your app.component.tns.html
should become similar to:
<GridLayout>
<page-router-outlet></page-router-outlet>
</GridLayout>
CORE TEAM NOTE: It's advantageous to wrap
page-router-outlet
with aGridLayout
and there will be more details shared on some advantages to this layout in the future which is why it's now the default and required.
Unit Testing is broken since release of NativeScript with Angular 9. However, NativeScript team seems to have an idea about it and I'm hoping the issues surrounding this gets resolved soon. For now, you have to live without testing (which, I know you were hoping for all along xD).
If you want to see upgrading in action, have a look at my repository which I used as one of the tests to confirm the sequence of events to upgrade NativeScript with Angular projects. Before the upgrade, the project was based on Angular 8, and now it's running on Angular 10 without any issues. Find the exact changes here: https://github.com/mahmoudajawad/nativescript-pokedex/commit/2e9723dd093244761cd524cb068a0563d5813e22.