NativeScript 7.0 marks a signficant step forward for the framework by aligning with modern JS standards and bringing broad consistency across the whole stack. It also reigns in a holistic sweep over the management of all the open source surrounding the framework providing the ability for more efficient updates with JS ecosystem changes.
This release is a testament to the effectiveness and true meaning behind the framework being community driven and governed by established open source guidelines.
You really should read the entire announcement details below though ๐
Install the 7.0 cli:
npm i -g nativescript
You now have a few new cli aliases:
ns
- the new standard โจnsc
- for those who can't stop thinking about javac
you can think of this as the "NativeScript Compilertns
- this will always work too for historical reasonsThere's a new convenient clean
command as well as this has often become a common stumbling block across development teams. This helps ensure the proper project files are cleaned when needed.
ns clean
NOTE: If your world is ever upside down, just ns clean
from here on out. ๐งน๐
You can also migrate existing projects* using:
ns migrate
NOTE*: Always check your project's plugins for NativeScript 7 compatibility first here before migrating and feel free to comment on that post if you use a plugin not listed with support yet and we can help the author.
You should also have a look at the import reference guide to help flatten any deep imports your project may be using.
Let's cover the key elements that 7.0 brings to the table.
NativeScript has been targeting es5
and commonjs
since the beginning. It has worked well but there are improvements nowadays that deserved to be taken advantage of.
Targeting es2017+ allows faster and more performant code along with allowing you to use the latest ES advancements like real Nullish coalescing operator ??. In the past TypeScript allowed you to use many new features but they would be converted to ES5 code and some aspects may actually become slower code. The v8 engine NativeScript uses (now on iOS as well! ๐) has always had cutting edge support for the newest ES support.
Read more on this push forward here
A number of framework npm packages have been scoped (@nativescript
) including several plugins to help clarify and delineate what is NativeScript 7 supported (es2017 based builds). It also helps with some project dependency organization we've longed for.
This is only required if you use TypeScript and are extending a native class. If you are using pure JavaScript, you can use the .extend()
function as usual.
One of the attractive (and fun) features with NativeScript is its ability to extend native platform classs directly in JavaScript. However JavaScript has no way of knowing how to extend a native class on it's own. When you wrote class MyClass extends android.os.class
and it was compiled to ES5, the runtimes used the __extends
function to handle the behavior. In ES2017, extends
is supported natively and thus is compiled "as-is" leaving out the __extends
needed for the runtimes.
This was a perfect opportunity to use a decorator and thanks to an excellent community contributor Martin Guillon, aka farfromrefug ๐ค we were able to introduce the @NativeClass() decorator to assist here.
You can see an example of how to use the NativeClass decorator here in this post
There's a few places where app configurations were handled and it deserved to be centralized and simplified - as well as strongly typed!
There's long been a nativescript
key in any app's root package.json
to manage app bundle id's and the runtime versions. There was also another package.json
embedded in the app's src directory which contained runtime flags. And yet another file called nsconfig.json
which contained other app configurations used to define various things about the project.
In NativeScript 7, this is all consolidated into a single nativescript.config.ts
(or nativescript.config.js
). Let's look at an example:
nsconfig.json
{
"appResourcesPath": "App_Resources",
"appPath": "src",
"webpackConfigPath": "webpack.config.js"
}
src/package.json
{
"main": "app.js",
"android": {
"v8Flags": "--nolazy --expose_gc",
"markingMode": "none",
"suppressCallJSMethodExceptions": false
},
"discardUncaughtJsExceptions": false
}
package.json
{
"nativescript": {
"id": "com.company.app",
"tns-android": {
"version": "6.5.3"
},
"tns-ios": {
"version": "6.5.2"
}
},
...
import { NativeScriptConfig } from '@nativescript/core';
export default {
id: 'com.company.app',
main: 'app.js',
appResourcesPath: 'App_Resources',
webpackConfigPath: 'webpack.config.js',
ios: {
discardUncaughtJsExceptions: true
},
android: {
discardUncaughtJsExceptions: true,
v8Flags: '--nolazy --expose_gc',
"markingMode": "none",
"suppressCallJSMethodExceptions": false
}
} as NativeScriptConfig;
The runtime versions can now simply be managed as one would expect in devDependencies
:
"devDependencies": {
"@nativescript/android": "~7.0.0",
"@nativescript/ios": "~7.0.0"
}
NativeScript's Android runtime has run JavaScript v8 for quite awhile now however the iOS runtime has been using JavaScriptCore all this time. This lead to some subtle differences in the way each runtime behaved.
In NativeScript 7, for the first time ever, the default iOS runtime is now using same v8 engine with @nativescript/ios
. This also helps improve the maintenance of both runtimes.
Note: You can still use
tns-ios
runtime based off JavaScriptCore if you find that the new v8 engine has an issue. You can also still usetns-android
for that matter if you need to use older android runtime as well.
"dependencies": {
"@nativescript/core": "~7.0.0"
},
"devDependencies": {
"@nativescript/android": "~7.0.0",
"@nativescript/ios": "~7.0.0",
"@nativescript/types": "~7.0.0",
"@nativescript/webpack": "~3.0.0",
"typescript": "~3.9.0"
}
With the new @nativescript/types
you can actually simplify your references.d.ts
to this if you want both iOS and Android type declarations:
/// <reference path="./node_modules/@nativescript/types/index.d.ts" />
You can also include specific platform types as needed if you desire; for example, say you wanted different Android sdk types alongside the iOS types:
/// <reference path="./node_modules/@nativescript/types-ios/index.d.ts" />
/// <reference path="./node_modules/@nativescript/types-android/lib/android-29.d.ts" />
We want to take a moment to give a special thanks to the entire community whom have provided excellent issue reports, pull requests and the wonderful contributions via Open Collective as well as through Github. The TSC could not have possibly prepared and executed a major release as large as this one without you and we are excited to hear more feedback from everyone as we continue to move NativeScript forward.
We welcome anyone to become involved in the framework's development process and history. A good place to start is by joining the weekly community chats hosted every Wednesday at 12 pm PDT. Then check out the code of governance the framework follows and try submitting a fix or feature sometime! โค๏ธ
There's a few immediate followup tasks we are doing for this release including:
For 7.1, we plan to continue delivering on the 2020 roadmap by focusing (in part) on:
Please take care everyone! โ๏ธ