Author Archives: Nathanael Anderson

GitLab Verified Email account issue

I use a privately hosting Gitlab's instance for a bazillion projects; and have a lot of users from around the world. Unfortunately, I have ran into a long standing bug that has never been fixed in many years. It only crops up occasionally now, but it is still a major pain for everyone involved. Many, many reports and many issues in the gitlabs issue database on this issue.

Basically, the end user never sees a "verify this email" email. And without that email; they can not login. Catch-22. In addition the "Confirm" button in the administrator account also fails to work in this situation, so neither the user nor the admin can do anything to fix it. Which then basically means I have a dead account that no one can do anything with. Until today.

These notes are so that I can easily fix it in the future.

First thing you do is go to the https://yourinstance/users/confirmation/new and create a new verification email. This way the token you will get later is now valid (as tokens expire after a number of hours).

Next thing is login to the Docker instance; if you aren't running docker; then don't worry about this step:

docker exec -it gitlab bash

Then once inside the docker bash shell; you launch the gitlab's interactive shell -- technically you can just the gitlab-rails runner "command; command; command" but the docker instance I run doesn't seem to have it present -- so we will launch the full gitlab rails console.

bundle exec rails console -e production

Once in this the rails console; we search for the user:

u = User.find_by_username('USERNAME')
(or u = User.find_by_any_email("emailaddress"))

Once we have the u variable; we can do a huge number of items on it; but what we really need to do is output the current confirmation token.

u.confirmation_token

And it will print a token that looks like this: "s2vzxVeWYhkzzDsBN8fC"

Type, exit, to exit the gitlab console. Then exit again to exit the docker instance. Go to your browser; and then use a modified version of this url:

https://yourinstance/users/confirmation?confirmation_token=<strong>s2vzxVeWYhkzzDsBN8fC</strong>

And let your browser go to it; and if you did everything correctly; you should see gitlab say it verified your email address and that you can now login.

Please note their are a lot of features/functions/data off the user "u" variable (over 3000); however, after spending over an hour trying confirmation, verification and other related features -- everything "looked" correct on the user record; but in the web admin page still showed the account was unverified. I just realized their might be some sort of user save record which then would have persisted my changes; but I didn't think about it until I was writing this blog.

However, since I could not get any of the other u.* functions to fix the record, I finally figured that the simplest way to fix this was just to have gitlab run its OWN verification code and so all I need to do is provide the token it generated myself to its verification page to make gitlab believe the end user got the email and now verified it.

VMWare - Shrinking disk size Macintosh/Linux

If you have a Macintosh or Linux based image; the tooling to shrink the hard drives is basically broken in the Gui (and/or, don't work). So to shrink these types of containers; the easiest method is to force the entire empty area to be Zero's, then defragment, and finally shrink all ..

First thing we need to do is Zero all blocks that are no longer used. Please note this will make your container grow to the maximum size your container is allowed to grow; so you might need a lot of disk space!

cat /dev/zero > zerofile; rm zerofile

Next you need to shutdown the client, so on linux it might be shutdown now -h or clicking a couple buttons to shutdown cleanly. After the VM has been shutdown you need to run the following commands from the command line.

vmware-vdiskmanager -d <diskimage.vmdk>

This command will defragment the image; moving all the data to the front of the image and all the empty blocks to the end. You obviously need to point the &lt;diskimage.vmdk> at wherever the vmdk you are working with is located, and if the vmware-vdiskmanager is not on your path; you will have to manually call it from wherever it resides. Finally you need to call

vmware-vdiskmanager -k <diskimage.vmdk>

As this will shrink the image; and if you are lucky, your 280 gig image will shrink to 80 gigs.

NativeScript Fonter revisited again (using DuoTone FontAwesome)

In a prior post I discussed using fonts in NativeScript. This morning I saw an issue in the NativeScript github repo about how to use the Font Awesome Duotone fonts.

Since I love puzzles, and I know the NativeScript font system fairly well, and I also own a subscription to the commercial Font Awesome -- I figured I could easily see if I can make it work. Immediately, I had a idea on how to solve the issue.

So I downloaded both the WebFonts and the Desktop fonts. Interestingly, enough the Desktop fonts actually have a warning that links to a post about Duotone fonts and the issues with the desktop... So after I read that post; it basically confirmed my understanding on how this font works and exactly how to make this work inside NativeScript.

So first things first, you need to update your app.css file; you want to add something like this to it:

.fad {
   font-family: fa-duotone-900, Font Awesome 5 Duotone;
   font-weight: 900;
}

.fad-op {
   opacity: .4;
}

Why TWO names for font-family?

If you recall from my prior fonter post; you want to create the rule that has the name of the actual font file without the .TTF or .OTF extension. So since the font folder looks like this:

The last file in the example fonts folder, is fa-duotone-900.ttf; straight from the web download zip file that I downloaded this morning.

So you see the rule is:

   font-family: fa-duotone-900, Font Awesome 5 Duotone;

This allows NativeScript to find the actual file name, in a lot of cases it can use just the filename to work its magic. However on iOS specifically, we want to include the actual internal font name. So double clicking on the font gives us this image under linux.

Under macintosh the title bar also shows the exact same information. So that is why I then typed "Font Awesome 5 Duotone" as the second part of the rule -- this must EXACTLY match. The two names covers all the cases we need, font file name to load it and actual internal font name to reference it later.

The second css rule we just added was fad-op, it is so that we can have some opacity for which ever section of the font we want or need opacity on.

We can do no opacity, solid/solid, and it would look like this:
Notice both parts are solid.

Now if we add opacity to section two; you can see the beak, legs on the bird are slightly transparent; and the acorn body is partially transparent.

Finally if we reverse the opacity to make section one have the opacity it looks like this:

You can also apply any opacity you want like 0.10 looks like this

And you can apply opacity to both sections and it looks like this:

All of them are using the EXACT same colors; just a difference in opacity. The sky is the limit; you are free to color and apply opacity on whatever amounts to each of the two sections.

So how do we do this magic?

Well technically the hard part is already done, that awesome css rule and dropping the font file into the app/fonts folder has 99% of the work done for us. The rest is simple stuff.

So the next thing you need to know is; which duotone icons do you want to use?

So first we need to know what is available for duotone; so we go to the font awesome icon page; and select the duotone filter. Once we have that; we can choose something; so lets look at the crow.

The crow at the top of the page lists this information:

Now at this point we can't really use "fa-crow" just because NativeScript doesn't know what that is; but the two pieces of information we do need to know to make it work is the f520 and the 10f520 these are the unicode values for the two sections of the icon we want.

So our xml needs to look like this:

 
  

This gives us the two characters in the same location on the screen. The first character is using the "fad" css rule; along with the text color blue. The second character is also using the "fad" css rule, and it adds the red text color and the "fad-op" rule for opacity.

Which gives us the duotone bird:

The key item is that you want the characters to print over each other; Gridlayout by default allows you to put multiple items in the same row and column. Since the characters are the same size; they by default will automatically line up and work.

Angular Flavor Issue

Angular's HTML parser has an issue which characters in the upper unicode -- it is great with any unicode value 65535 and below. Which of course if you have seen the first character of each of these duotone values is < 0xffff (65535). However the second character starts in the 0x100000 (1048576) range which is a lot larger than 0xffff. Unfortunately this means that in Angular even though you pass in 0x10f520 you actually get 0xf520 assigned. If you are paying really close attention, this is the same value as the very first code. So in angular you get two labels with the exact same unicode value. So how do we fix this?

Well ultimately; the underlying Angular parser should be fixed -- so if one of you wants to tackle this, track down where in the parser it breaks and push a PR; that would make a lot of people in the Angular community happy! However, since this is not something I am going to tackle and I still want you to be able to use Duotone fonts, I will present an alternate method to how to fix this on Angular.

In Angular; we can do it one of two ways; automagically; or direct assign. I prefer the automagically; so this is the HTML that we have:

<Label col="1" text="&#xf6ae;" class="larger fad "></Label>
<Label col="1" text="&#x10f6ae;" class="larger fad blue fad-op" (loaded)="fixAngularParsingIssue($event)"></Label>

As you can see it is identical to the above NS-Core XML, except I added the (loaded) event. This event fires once in the lifecycle of the Label. And runs my handy dandy "fixAngularParsingIssue" function.

fixAngularParsingIssue(args: any): void {
  let field = args.object;
  let val = field.text.codePointAt(0);

  // Check to see if this is already a valid unicode string above 0xffff.
  if (val > 65535) { return; }

  // We found a character we need to change...
  val = val | 0x100000;
  field.text = String.fromCodePoint(val);
}

The function is straight forward; we grab the current text value; verify it is actually still less than the unicode value we want as the parser could get fixed in a future version. Then we take that value and add our missing 0x100000; and then re-assign the text. Now this function could instead be written to take the actual value you want to assign rather than computing it, but I prefer simplicity as then I can just add this function to all labels that need it and just not think about it.

Angular Directive

I suggested in the issue that someone create a directive; and Pandishpan spent the time and converted my simple code into a directive for Angular making it even easier to use in angular! Thank you for your awesome work! So now, all you have to do is apply the "labelDuoTone" directive to the html, and it handles the rest of the work for you.

You can grab the code for the angular directive in the github issue here.

NativeScript Core demo application

You can download the NativeScript-Core fonter application from the github repo, https://github.com/NathanaelA/fonter

Please note the fa-duotone-900.ttf font is NOT shipped with the demo; you must download it yourself and copy it into the app/fonts folder.

Android (on left) and iOS (on right) looks like this:

Android
iOS


NativeScript 6.4 released

NativeScript 6.40 has a couple cool new things; but better yet it fixes several issues that can will affect your users if you are using 6.3.x lets look at them...

Some of the fixes include instability during android's fragment handling occurred in 6.32, which is worth while. A couple really awesome community PR's, and of course one of my favorite items is the new CSS parser by default and the v8 upgrades...

[UPDATE] The new 6.4.1 Android engine that was just released a day or so after 6.4.0 adds v8 version 8! Which add a lot of cool features (see v8 section)

Core Modules

  • NativeScript is got a new much faster CSS parser in v6.3 -- it is now default in 6.4!
  • The community (Ryan & Hamdi) and the NativeScript team worked on 3d rotation for a while now; this has now shipped! .rotate-x, .rotate-y, and .rotate-z
  • .Fixed background color reset on Tabs

We had even more awesome community PR's this month, a big thank you to the community!

CLI

The CLI team has fixed several outstanding bugs; including several webpack hmr issues. This also includes Node 13 and Android API 29 compatibility.

  • CLI now cleans up after itself in a corner case where CTRL-C'ing when first starting the build.
  • Doctor now will throw error if using Java 13 (NativeScript doesn't support it yet)
  • CLI Will now detect and let you know about the breaking issue of including multiple versions of the same plugins or multiple NativeScript core versions.
  • Native Metadata filtering, allow Application/Plugins to declare what Metadata they need; to allow smaller metadata and faster startup.

Webpack Changes

  • Snapshot bug fixes
  • Ability to set a Webpack config location so you can add custom application rules
  • Ability to allow custom platforms building (--env.platform <platform>)

V8

If you didn't read my notice on the last update; I'm creating this new v8 Section, because Android and soon iOS will both be using the same v8 engine. v8 was upgraded to v7.9 (in 6.4.0) and then the awesome v8.0 was slipped into (6.4.1) which adds:

  • IC Handlers are now cached properly; giving a ~12% for all IC calls into the C++ runtime.
  • OSR Replacement - 5% - 18% speed up.
  • Pointer Compression (Saves up to 40% of heap memory) which increased speed on large JS by a few percentage points!
  • Optional Chaining
  • Null coalescing

Android

  • Async WebAssembly issue resolved
  • Memory freed on some objects that were being retained
  • Upgraded to V8 8.0 (See v8 section)
  • Fix for Elevation usage on some API versions
  • "FlipRight/flipLeft" transition fixed

IOS

  • The CLI will warn you if you forget a module.modulemap file in your included .M files
  • Project Template is FastLane compatible
  • Fixed discarded exceptions
  • Safari Inspector now shows startup errors
  • A lot more changes to the new v8 version of the iOS runtime that is now in BETA testing to eventually replace the JSCore version... Overall now is the time to test it!

Updating NativeScript

To get updated; you first need to do:
npm i -g nativescript@latest

To update a project; you need to do the following:

Latest Runtimes:
tns platform remove android && tns platform add android@latest
tns platform remove ios && tns platform add ios@latest

Latest Core modules:
npm r tns-core-modules --save
npm i tns-core-modules@latest --save

To install Webpack support:
npm i nativescript-dev-webpack@latest --save-dev

To install latest NativeScript Angular plugin
npm i nativescript-angular@latest --save
You will then need to install the actual angular bits; which as of this post v6 is currently supported.

The addition of t additional analytics/tracking to the CLI reminded me; you can disable it permanently; if you value your privacy by doing:
tns usage-reporting disable && tns error-reporting disable

NativeScript 6.3.0 Released

NativeScript 6.30 has a couple cool new things; but better yet it fixes several issues that can will affect your users if you are using 6.2.x lets look at them...

Some of the fixes include instability during android's switching of applications and resuming it. An issue with unloading views on Android. Out of memory situation on Android, and dialog fixes for iOS. In addition to several important build fixes that appear to solve a lot of build HMR related issues. Overall this release is worth upgrading to for just the bug fixes alone.

Core Modules

NativeScript is getting a new CSS parser; unfortunately it is not enabled by default in 6.3; but based on a PR should be enabled by default in 6.4. If you would like to enable this in your app to see how much faster it can parse your css; you do so by editing the packages.json file that ships with the application and adding a new key called "cssParser" and set it to "css-tree". The valid options are "rework" (current parser) and also "nativescript" which was the original css parser.

We had a couple awesome community PR's this month the first by Eduardo Speroni adds requestAnimationFrame as a supported function. And the second by Shailesh Lolam  add dialog sizing (width & height properties) to the modal dialogs on iOS.

And finally to round up our new core module features; Modal dialogs now have all the same CSS properties applied to them to allow better styling. In addition to the normal properties, a new .ns-modal class is applied.

CLI

The CLI team has fixed several outstanding bugs; including several webpack hmr issues. This also includes Node 13 and Android API 29 compatibility.

V8

I'm going to create this new v8 Section, because Android and soon iOS will both be using the same v8 engine. v8 was upgraded to v7.8 which adds:

  • Faster object destructuringconst {x, y} = object; This is now as fast as the normal ES5 const x = object.x, y = object.y;
  • Lazy source positioning; which can save 1 - 2.5% of memory; basically instead of storing all source code lines for when errors occur; it recalculates it when it needs it.
  • Faster RegEx
  • Several Wasm improvements

Android

The Android team kept busy this month;

  • Fixed some Kotlin issues
  • Android Signal 1 & 11 are now captured
  • Fixed a worker issue
  • Upgraded to V8 7.8 (See v8 section)

IOS

  • Upgraded to WebKit 13.2
  • Several metadata fixes
  • Fixed a worker issue
  • Fixed debugger not working issue
  • Fixed discardUncaughtJsExceptions issue

    A lot of changes to the new v8 version of the iOS runtime that is still in alpha testing to eventually replace the JSCore version... It appears the iOS v8 version is shaping up to be an awesome release.

Updating NativeScript

To get updated; you first need to do:
npm i -g nativescript@latest

To update a project; you need to do the following:

Latest Runtimes:
tns platform remove android && tns platform add android@latest
tns platform remove ios && tns platform add ios@latest

Latest Core modules:
npm r tns-core-modules --save
npm i tns-core-modules@latest --save

To install Webpack support:
npm i nativescript-dev-webpack@latest --save-dev

To install latest NativeScript Angular plugin
npm i nativescript-angular@latest --save
You will then need to install the actual angular bits; which as of this post v6 is currently supported.

The addition of t additional analytics/tracking to the CLI reminded me; you can disable it permanently; if you value your privacy by doing:
tns usage-reporting disable && tns error-reporting disable

ProPlugins - end of year update

We started the ProPlugins project pretty close to the launch of NS (NativeScript) 6.0. So it has only been active for about five months now. So how is it doing???

Well, first let cover the reason why we created it. This plays in strongly into how well ProPlugins is doing.

Why ProPlugins?

For most of us plugin developers who have worked in the NativeScript eco-system for a while. We all knew that NS 6.0 had a range of breaking changes; which meant it was the fifth set of breaking changes in less than 4 years for plugins. Each one of the NS major releases, had a range of breaking changes that required certain types of plugins to make fixes. Sometimes the changes were minor, other times the changes actually requires some major rewrites and/or major time debugging why something was no longer working properly. Of course the vast majority of this work was done by the original author; with very little or no help from the rest of the community. I recommend you read all three of my prior blog posts on the plugin costs and the plugin problem. And then why we believe ProPlugins is the solution. With those posts you will have a pretty good idea that the actual costs to an author, the community involvement, and how the open source seems pretty much unsustainable.

In addition to our experience, their are lots of blog posts by many other authors, on how for the most part, the majority of projects that are open source by independent developers has a serious funding and/or burnout issues. We have seen the exact same thing in the NativeScript plugin community way too many times. in fact, the other day I responded to a issue saying that I believe a specific plugin was still maintained as this author has been around for a while -- and then several people pointed me to the issue where the author has mentioned it is no longer maintained. Sadly another excellent plugin author appears to have left the community.

Community Involvement

When we FORKED all these plugins into ProPlugins, the original version was left to see how much the community would be actually willing to maintain them. My stance has been that I didn't believe the community would change any; but I have been 100% committed to allowing the community to prove me wrong and send in any PR's and I would publish the new version fairly quickly.

Sadly, my prior blogs posts on the problem, which tells the sad tale of how many PR's per plugin is received from the community before ProPlugins was created. The communities involvement still has not changed, and as such we have still only seen less than a handful of PR's for all 40 of the plugins we forked into ProPlugins. Meaning the vast majority of all these plugins probably don't work with NativeScript 6.x. This doesn't surprise me, since I had seen this lack of involvement for the last 4 years of plugin development...

The most interesting thing, is that this experiment really could have gone a couple ways. I could have been proven wrong and the community would have finally stepped up and worked on fixing all the plugins for NS 6 support. Or even the worst possible outcome, nobody could have joined, and also nobody did anything to fix any plugins. However, it seems the community has decided that joining ProPlugins as the best option to move forward. It eliminates them from having any additional time commitments, and helps us create sustainable source code.

So how has has ProPlugins done?

We grew to have 40 fully maintained plugins, which have had around 30 PR's for issues introduced in the NS 6.0 upgrade. We have done several PR's for issues people found in the last couple months to several of the plugins. We have also added several new features to multiple plugins. Finally, recently about 10 PR's for different plugins to fix the breaking change that was accidentally introduced in NS 6.2. So adding and maintenance of existing plugins seems to be off to a very successful start.

In addition, this new year we have several new plugins that we have plans to add. Even better, we have more authors lined up for joining the ProPlugins program. So by the end on 2020; we hope we will have around a hundred fully maintained top quality plugins in the program.

Despite the lack of any recent advertising and really my total lack of my focus on it for the last couple months; ProPlugins has each month done considerably better than the prior month. So our subscription revenue has been increasing faster than I had planned.

Since 80% of all revenue goes to the authors, the remainder goes to the actual expenses like paypal fees, advertising, servers, etc. We believe, the ProPlugins experiment has successfully started the process to having sustainable source code in our community, completely from the community. So a big congrats to the community for helping fund this!

We hope you all have a merry Christmas, and a happy New Year. We look forward to even more of you becoming part of the ProPlugins project and helping us fund sustainable open source for the NativeScript community.

NativeScript Offline Plugins

There are cases where you might want to package plugins with your app in your version control; like for example you are using a commercial plugin or maybe a proplugin and need to use cloud building.

The simplest setup that I have personally used is in the very root of your application.


You create a folder called plugins. Inside this folder you put any commercial and plugins you need to keep with the apps source. For example one of my projects looks like the above picture, I have 5 plugins that are actually in version control with the application. So anyone checking out the source code from git will get all these plugins with the application.

To use these plugins in your NativeScript app, in the root directory you type "tns plugin add ./plugins/nativescript-compress-0.0.1.tgz" you need to type the ENTIRE name including the extension.

How do I download them

So say I want to have the proplugins/nativescript-dialog plugin.

npm pack @proplugins/nativescript-dialog
will download the latest .tgz file into the current directory for you.

PSA: NativeScript 6.20 - Is a Breaking Change release!!!

Upgrading to 6.2.1 and the latest Nativescript-angular (if using angular) and the latest proplugins; should fix MOST issues that 6.2.0 had. However, I still highly recommend the webpack rewrite rules at the bottom of the post to solve ALL the issues.


NativeScript follows the SemVer process; so normally they would have bumped a major version on breaking changed. This break is mostly an un-attended side effects of a couple things. And unfortunately they didn't realize it broke things, so we now have 6.2 which breaks things... Oh well, mistakes happen, life will go on. And so this post is to make you aware of what things you want to change when you upgrade to NS 6.2.0...

To Upgrade or not to Upgrade, that is the question!

I do want to make sure I am VERY clear -- I do NOT think this was a bad change, nor do I think NS 6.2 is a bad release! My apps will be upgraded to it. It offers a lot of good features and fixes. It is just that being aware of the issues will help you make sure you don't have any issues with it when you do upgrade to it.

Lets dig in to the issue.

So lets get some details, first about 3 major versions ago in 2017, my business partner and buddy Nathan Walker proposed on issue 4041 to move the nativescript tns-core-modules into its own namespace. @nativescript along with other nativescript pieces being put into that parent namespace...

So based on this you might guess where the source of the issue lies now.

If you read the above issue; you will notice Peter (another awesome developer) and I both recommended that they do this in the 6.0 release. I personally felt like a hard break would be the safest course of action. Just eliminate tns-core-modules totally. Since they already were totally breaking the build tools, and also breaking other plugins things in v6.0 -- they might as well add this to the pile so we deal with all the breaking changes at one time in plugins. Unfortunately, our advice wasn't taken, or it was missed and so here we are with a very interesting breaking change that I honestly did NOT foresee when I recommended they do it in the initial 6.0.

There are three different issues here that stem from the same cause:

First, if you are using NativeScript-Angular and use any third party plugins -- you might find that they are failing because NativeScript-Angular was moved into the @nativescript/angular namespace. The compatibility imports for the old namespace; is apparently missing a couple redirects so plugins trying to load them fail. I'm sure these plugins will be updated shortly; but right now they are broken. (This has been fixed in the latest version of NativeScript-Angular)

I do NOT know yet if NS-Vue, NS-Svelte, or React-NativeScript have any issues; but odds are a fairly low with them because they are third party and were not moved into the @nativescript namespace, so apps depending on this probably are NOT affected directly (other than by any other plugins.)

Second, because of the design of the tns-core-modules redirect, the redirects waste a little bit of running memory. If your app or plugin imports tns-core-modules/BLAH (which all apps do before 6.2) then webpack will give you Object #1 tns-core-modules-blah, however, when a plugin or the core modules loads @nativescript/core/BLAH you get Object #2 nativescript-core-blah -- they LOOK the same but they are different objects each using memory. This does increase a little bit some parsing and memory that the V8 has to use because you now have basically more than a single framework in memory. Some of this is mitigated based on how objects are tracked; but some of it isn't. So this creates some other un-intended side effects of little bit more GC pressure, more ram usage, and the nasty pitfall we will discuss later...

Finally, if you are using any plugin that does any sort of class monkey patching, they will now all fail -- in this category is things like my very own nativescript-platform-css, nativescript-orientation. The reason why is because of the above allocation issues. Object #1 != Object #2. monkey patch Object #2, doesn't monkey patch Object #1. This is a corner case; as it requires you to actually replace the class (i.e. the top level object). So any plugins that rely on nativescript-global-events which extends and enhances the page class; were affected.

As an aside: The good news is virtually every one of my plugins on https://proplugins.org has been updated to have a NS 6.2 version. If you find a plugin that no longer works after you updated to 6.2; let us know and we will attempt to get it fixed. The 6.1 -> 6.2 fixes are very minor; so they can be rapidly put into the plugins.

One final note -- Please see the method to update the webpack at the bottom to have webpack rewrite tns-core-modules to @nativescript/core this is still highly recommended as some plugins will still be broken if you are still using the tns-core-modules redirect version.


The low level nitty gritty details - Proceed with caution.

For those who are interested in the nitty-gritty; we will walk through why #2 and #3 occur in NS 6.2. Please note this is VERY simplified -- The actual TS -> JS code is a bit more complex and a wrapped object. However, this should give you an idea of the why's...

V8 basically keeps a object map of how a object looks in memory; so if I have file "Blah" with class HiYa -- that looks like this:

export class HiYa {

   function hi() { /* do something */ }

}

When it exports it has a unique signature. In NativeScript this is compiled down to ES5 code. So this will basically look like this when all said and done:

function HiYa() {} 

HiYa.prototype.hi = function() { /* do something */}

module.exports = HiYa;

Now when I do a const HiYaRunnerMaster = require('@nativescript/core/blah'); The Blah.js file is loaded into memory; parsed and then a runnable object representation of this is passed back to HiYaRunner, lets call this HiYaRunnerMaster. So far so good.

Now for the NativeScript tns-core-module redirects / compatibility layer.. This is the exact code that you see in tns-core-modules/* in 6.2... It basically redirects to the @nativescript/core version of the file. Seems simple, and unless you are paying close attention you might not even see why this actually is a problem.

function __export(m) {

    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];

}

Object.defineProperty(exports, "__esModule", { value: true });

__export(require("@nativescript/core/blah"));

So when I do a const HiYaRunnerFromTNS = require('tns-core-modules/blah'); it loads the above code and runs it. . It first defines the __export function, then runs that function on what it gets from the require of @nativescript/core/blah . Seems simple enough. Lets break this down into each step to what the v8/JavaScriptCore engines do.

  1. const tempObject = require('@nativescript/core/blah'); -- THIS object is the same/identical HiYaRunnerMasterObject as we got earlier when we ran it. Every time we do this specific require statement, we get the exact same object. Which is what we want!
  2. __export(tempObject); This runs the export function, passing in our HiYaRunnerMasterObject which so far doesn't seem like an issue.
  3. for (key in HiYaRunnerMasterObject) { we are looping through every property in HiYaRunnerMasterObject
  4. if (!exports.hasOwnProperty(key) verify the exports variable doesn't have this key property already.
  5. exports[key] = HiYaRunnerMasterObject[key]
  6. And behind the scenes exports is passed to the HiYaRunnerFromTNS at the end.

Did anyone else see what happened in step 5? First, exports is a 100% BRAND NEW OBJECT. (our Object #2). We then COPIED all the properties/functions from Object #1 (HiYaRunnerMasterObject) onto this new Object #2 (exports). Each copy is actually a new piece of memory that point to the old object's key value. So the new exports[Key] = old.value. in simplistic terms has two separate memory slots; "Key" and Value". So exports[key] is always a new memory pointer (of key) that either points to the original object's [key]; or to its own copy of a un-boxed object. So the memory usage could be 50% of the original object to the exact same memory usage as the original object, all depending on what the values (boxed or unboxed) are. In NativeScript it should be much closer to adding the 50% additional memory, not the 100% as a worst case number as almost all values on a nativescript key are objects.

At the end, in step 6 we used the brand new object to assign to HiYaRunnerFromTNS. Whoops; so we now have TWO different objects in memory with two different sets of memory usage.

This means that if you monkey patch the HiYaRunnerFromTNS copy; you are not actually monkey patching the actual original and running version. So in several of my plugins, this caused them to break as the monkey patching basically never occurred as far as the running copy of NativeScript was concerned.

In addition their is one more potential gotcha; I'll make a simple example:

let Obj1 = {a: {value: 1}}; // Original Object
let Obj2 = {a: Obj1.a}; // Copied key object

If I do Obj1.a.value = 2; then Obj2.a.value === 2 because both a's point to the exact same memory location with a "value" key in it . However, if I do Obj1.a = {value: 10} then Obj1.a then creates a brand NEW object which also has a value key; of which it has the value of 10 in it. And Obj2.a continues to point to the OLD original object with the value = 1. So even though your objects initially started pointing to the exact same value in memory. A new object assignment will replace just that objects location.

Why does this matter? When since the running instance of NativeScript is the @nativescript/core versions of the object. And your applications code will all currently require tns-core-module versions; you DO initially have two objects but they should all start out pointing to the same memory locations. Just like our example earlier (Obj1.a = Obj2.b) However, if you change a value that is NOT using a setter -- then the value you just changed won't be propagated to the running version, and you will have Obj1.a = {value: 10} and Obj2.a = {Value: 1} and you won't have a clue you just did a noop statement.

I do want to say the above potential gotcha scenario is very UNLIKELY, all code that I can think of runs through a setter; a setter function should be getting and setting the original object's value, and thus they shouldn't go out of sync. But corner cases can and do occur. So my recommendation for anyone updating to NS 6.2 is to do...

Recommendations

  1. Long term, replace ALL tns-core-modules/ with @nativescript/core/ and all nativescript-angular/ with @nativescript/angular/ everywhere in your app. No longer have ANYTHING pointing to tns-core-modules/ or nativescript-angular -- pretend those old namespaces no longer exist and were deleted.
  2. Update to the latest @proplugins if you are using any @proplugins, as most of them have already made the transition, as this will at least save you time on that aspect.

Short term tip (and highly recommended until they have a solid fix):

Richard Smith, posted a good tip that can quickly get you working -- you can add a rule to your `webpack.config.js` file. Find the alias section and add:

   
  "nativescript-angular": "@nativescript/angular",
  "tns-core-modules": "@nativescript/core",

So it looks like:

  
alias: {
      "~": appFullPath,
      "nativescript-angular": "@nativescript/angular",
      "tns-core-modules": "@nativescript/core"
},

NativeScript 6.2.0 Released

NativeScript 6.20 has several fixes, and finally added the long awaited Scoped packages. UPDATE Scoped packages apparently breaks some things. See here for more info on how to deal with it.

Scoped packages; are where you can now do

const label = require("@nativescript/core/ui/label" rather than the older const label = require("tns-core-modules/ui/label");

This makes things a lot cleaner and over time more times should end up in the @nativescript namespace. Currently in the @nativescript namespace is:

  • Core Modules
  • Theme
  • Angular

Core Modules

Since they added the ns-root, ns-landscape, ns-phone, etc; in the prior version of NativeScript they have added even more css functionality in this version. ns-light and ns-dark are now added values which you can use to select specific theme color rules. They are added depending on the devices theme. Along with that change, more css optimizations, including hsla color support were added. A long awaited and very welcome fix to allow values to be reset to default when css rules are disabled was also finally done. Overall just the CSS fixes are worth the price.

Another cool change is they updated they revampled the android transition code. Should be better and more customizable. In addition Android also got ContentInset properties on the ActionBar. And iOS got selectedSegmentTintColor on the Segment bar.

Finally, the awesome community PR that was snuck into this release is Peter Staev's async read/write addition. readAsync and writeAsync allow async access to the file system.

CLI

The CLI team has fixed several outstanding bugs; things like Asset generation, several webpack issues, cocoapod fixes.

V8

I'm going to create this new v8 Section, because Android and soon iOS will both be using the same v8 engine. v8 was upgraded to v7.7 which adds:

  • Lazy feedback allocation - this reduces the memory load of the v8 engine, which is always good to have on mobile devices

Android

The Android team kept busy this month;
- They improved the error logging.
- Added Kotlin extension function support
- Added JSONObject support
- Upgraded to V8 7.7 (See v8 section)

IOS

Fixed a Mashalling issue from "unsigned char *"
Fixed losing some exceptions in TS from runtime

A lot of changes to the new v8 version of the iOS runtime that is still in alpha testing to eventually replace the JSCore version... This new runtime has pretty close to the same feature parity as the Android versoon. I'm sure the iOS team would LOVE you all to test out this runtime on your apps to verify they work properly -- you can do so by using tns platform add ios@alpha-v8 to tell it to use the v8 runtime.

Updating NativeScript

To get updated; you first need to do:
npm i -g nativescript@latest

To update a project; you need to do the following:

Latest Runtimes:
tns platform remove android && tns platform add android@latest
tns platform remove ios && tns platform add ios@latest

Latest Core modules:
npm r tns-core-modules --save
npm i tns-core-modules@latest --save

To install Webpack support:
npm i nativescript-dev-webpack@latest --save-dev

To install latest NativeScript Angular plugin
npm i nativescript-angular@latest --save
You will then need to install the actual angular bits; which as of this post v6 is currently supported.

The addition of t additional analytics/tracking to the CLI reminded me; you can disable it permanently; if you value your privacy by doing:
tns usage-reporting disable && tns error-reporting disable

NativeScript 6.10 Released

NativeScript 6.10 has several fixes, and a couple new features to make it worth your time to upgrade. 6.1 has to be one of my favorite recent releases.

Being biased here, the best fix is the PR I did; it allows the tns command line to actually be used with our awesome https://proplugins.org site. You could easily use NPM to work around the issue; but it is always better if the standard NativeScript cli tooling also works. So, I am ecstatic to see this show up in 6.1. So now completely removing my bias; the new ios wifi deployment support (which I haven't tested); is something I have really needed for a while, so awesome job team!

Core Modules

Their are a couple changes in Core modules that are worth noting. First of all; for those who have used my awesome nativescript-platform-css plugin for years; the NativeScript team finally decided I was right! 😀 They have not only stolen, er, borrowed, the idea to put device type in the class name (ns-android & ns-ios) , but they also borrowed the same idea I did in my nativescript-orientation plugin, which is put the orientation (ns-landscape & ns-portrait) into the class also. Unfortunately, I am a bit sad they still didn't have the foresight to borrow my poor-mans-media query system; it is still way better than nothing. Nor did they decide to use the device name css system, or any of the additional classes like .notch. So if you still need media query or actual device name support or anything else the platform-css; then you can continue to use the ns-platform-css plugin. And the ns-orientation plugin still offers the ability to force rotation and/or lock the rotation to a certain direction, so neither plugin will be discontinued because of the additional functionality both plugins still offer that the team didn't borrow.

In addition another community PR was accepted to add CSS calculation support! Unfortunately do to a minor oversight, it is broken in 6.10, but I would guess it should be fully fixed in 6.11.

CLI

This team has hit several home runs this release with me. In addition to getting my PR merged which solves the npm issues. They also added awesome iOS Wifi deployment support. And added iOS 13 and Xcode 11 support. Overall the CLI release looks to be a very awesome release.

Android

Android added several cool things in 6.1 also. First and foremost; Initial Kotlin compatibility has been added. This is very preliminary; so many things may not work.

Second they upgraded the the v8 Engine to 7.6 which adds the following features and enhancements

  • New much faster JSON parser
  • Promises.allsettled

In addition to the cool features added, they have also updated it to allow the latest Android tools and latest gradle. Also, they now added gradle.properties support so you can easily define properties next to your other gradle files...

IOS

Added metadata generation from inner members
Fixed issues with latest version of iOS and Xcode

Updating NativeScript

To get updated; you first need to do:
npm i -g nativescript@latest

To update a project; you need to do the following:

Latest Runtimes:
tns platform remove android && tns platform add android@latest
tns platform remove ios && tns platform add ios@latest

Latest Core modules:
npm r tns-core-modules --save
npm i tns-core-modules@latest --save

To install Webpack & HMR support:
npm i nativescript-dev-webpack@latest --save-dev
Note: you need to have nativescript-dev-webpack as a development dependency for HMR to work.  

To install latest NativeScript Angular plugin
npm i nativescript-angular@latest --save
You will then need to install the actual angular bits; which as of this post v6 is currently supported.

The addition of all the additional analytics/tracking to the CLI reminded me; you can disable it permanently; if you value your privacy by doing:
tns usage-reporting disable && tns error-reporting disable