Back to Blog Home
← all posts

NativeScript Webpack 0.9.0—What Changed and How to Upgrade

December 21, 2017 — by Stanimira Vlaeva, Vasil Chimev, Panayot Cankov

Yesterday we released a new version of the NativeScript Webpack plugin that includes some non-trivial changes. In this article we’ll walk you through why we made these changes, and what you’ll need to change in your apps to upgrade.

Angular 5 Support

In NativeScript 3.4 we added support for Angular 5, and Angular 5 for webpack comes with a new AngularCompilerPlugin. The plugin internally creates a TypeScript compiler instance, and uses that instance as the basis for the webpack file system during compilation.

Because of that update, we had to make some changes to support the module and resource resolution conventions we use in NativeScript, for example platform-specific files such as my-component.ios.html and my-component.android.html. Our new extension of the AngularCompilerPlugin, NativeScriptAngularCompilerPlugin, has faster build times, and opens up the potential for us to use webpack’s --watch flag in the future.

NativeScript Core Webpack

For NativeScript Core apps, webpack configs will now include a PlatformFSPlugin, and map platform-specific files similar to the way the NativeScriptAngularCompilerPlugin does.

This change unlocks the ability for us to support consuming webpack contexts when registering modules. Your app’s bundle-config.js file will now automatically include all your page.xml|js|css files. Previously, only the .js and .xml files were consumed from the registered modules.

Hopefully we will eventually allow the community to write custom XML loaders that will handle component registration and ahead-of-time XML to JavaScript compilation. This should be fun!

NOTE: The NativeScriptAngularCompilerPlugin uses just-in-time compilation by default, and you need to use a separate flag to enable ahead-of-time compilation. Check out this section of the NativeScript webpack documentation for more information.

CSS-Loader

Webpack’s css-loader can now be used to resolve CSS files used in the NativeScript core modules. This includes all .css files for plain NativeScript apps, as well the app.css file for Angular apps. Your app.css will now be bundled in your vendor.js file, and it will therefore be parsed during the Android snapshot generation. This feature was ready in the NativeScript Core modules, but the necessary webpack config was not yet released. It is now!

Support For SCSS

SCSS is now supported for both webpacked and non-webpack apps, as well as for Angular components, vanilla NativeScript pages, and app.scss files. All of these file types also support platform-specific suffixes.

Integration with NativeScript CLI

Prior to NativeScript v3.4.0 and nativescript-dev-webpack 0.9.0, building with webpack required running external npm scripts. With the NativeScript 3.4 CLI release we integrated the webpack plugin directly into the NativeScript CLI—there is no need for separate npm scripts.

For example, before NativeScript 3.4 you would run the following command to run an Android app with webpack bundling.

npm run start-android-bundle

With NativeScript 3.4 you can now run the following command to accomplish the same task.

tns run android --bundle


This integration makes it easier to pass in other CLI options such provisioning profiles (e. g. tns run ios --bundle --provision NativeScriptDevProfile), and it also gives us a path towards integrating the webpack watcher and debugging in the future.

Updating Your Project

Now that we’ve covered what’s why we updated the webpack plugin and what we changed, let’s look at how you can upgrade your apps.

Prerequisites

You first need to install the latest (currently 3.4.0) version of NativeScript CLI.

npm i -g nativescript

Next, you need to update your platform and tns-core-modules dependencies of your project by running the following command.

tns update

Update nativescript-angular plugin

If you are using Angular in your NativeScript app, you next need to update to version 5.0 of the NativeScript Angular plugin.

npm install --save [email protected]

After that, you’ll also need to update your Angular versions as well. Specifically you need to update your @angular/ dependencies to version ~5.0.0, your rxjs dependency to ^5.5.0, and your typescript dependency to ~2.4.2. You will also need to add one extra dependency—@angular/platform-browser-dynamic.

You can use the script below to do all that:

./node_modules/.bin/update-app-ng-deps

Update nativescript-pro-ui plugin

If you are using NativeScript Pro UI in your NativeScript app, you next step is to update it to its latest version (currently 3.3).

npm install --save nativescript-pro-ui@latest

Update nativescript-dev-webpack plugin

With those dependencies out of the way, next update your NativeScript webpack plugin to version 0.9.0.

npm install --save-dev [email protected] 

NOTE: Make sure you have have committed your current version of all webpack related files:

./app/vendor-platform.android.ts
./app/vendor-platform.ios.ts
./app/vendor.ts
./webpack.config.json

You can generate new versions of those files for the new version of the plugin using the command below:

./node_modules/.bin/update-ns-webpack --configs --deps

Next, you’ll want to apply any custom configurations you have previously made on the newly generated files.

CSS Imports

If you have CSS imports that reference files from node_modules you need to prefix them with a tilde (~).

For example, if you have the nativescript-theme-core package you will need to make the following changes in your app.css file:

Before:

@import 'nativescript-theme-core/css/core.light.css';

After:

@import '~nativescript-theme-core/css/core.light.css';


NOTE: This is different from ~/.

  • ~ (just tilde) will resolve the path relative to node_modules.
  • ~/ (tilde and slash) will resolve the path relative to the app directory.

Modify Bundle-Config

This step is for NativeScript Core projects only (aka apps that don’t use Angular).

You can now register your app’s XML, CSS, and JavaScript resources with a regex instead of listing them one-by one. Here is how you can modify your bundle-config.js or bundle-config.ts to do that:

if (global.TNS_WEBPACK) {
    // registers tns-core-modules UI framework modules
    require("bundle-entry-points");

    // register application modules
    // This will register each `page` postfixed xml, css, js, ts, scss etc. in the app/ folder
    const context = require.context("~/", true, /(page|fragment)\.(xml|css|js|ts|scss|less|sass)$/);
    global.registerWebpackModules(context);
}


Here is a link to these code changes:
https://github.com/NativeScript/template-hello-world/commit/9121973bd3289358284b0da9d33a98e7624c4955

Update Typescript Plugin

For TypeScript and Angular projects, you also need to update your nativescript-dev-typescript plugin by running the following command:

npm install --save-dev nativescript-dev-typescript@latest

Single tsconfig for AOT and JIT

This step is for Angular projects only.

You can now get rid of your tsconfig.aot.json file. However, you will need to update your tsconfig.json file to now exclude only thenode_modules and platforms folders:

   "exclude": [
       "node_modules",
       "platforms",
       "**/*.aot.ts"
   ]

In your main.aot.ts you probably have the following import:

import { AppModuleNgFactory } from "./app.module.ngfactory";

The ngfactory file is dynamically generated during AOT compilation. To satisfy Typescript static checks, add a app.module.ngfactory.d.ts file with the following content:

export const AppModuleNgFactory: any;

Running/Building Your Projects

Now that the upgrade is done you’re ready to start building your apps with the new version of the NativeScript webpack plugin. Because the NativeScript CLI now directly supports the webpack plugin, you can delete any existing scripts you might have in your package.json file for building/running your app with webpack.

After cleaning those old scripts out, go ahead and try using the new --bundle flag to make sure everything works.

tns run ios/android --bundle
or
tns build ios/android --bundle


There are a couple of options you can pass to configure the webpack build:

  • --env.aot - to enable angular AOT. Note: this is false by default
  • --env.snapshot - to enable V8 snapshots (Android only)
  • --env.uglify - to enable uglify
  • --env.report - output webpack build reports

NOTE: Livesync is still not supported for webpack builds. This is something that we will be working on in the future. Exciting times lie ahead 😄

If you run into any problems during the upgrade feel free to reach out on the NativeScript community forum, and if you find issues with the webpack plugin itself please report those on GitHub.

This is just the first of many exciting things we have in store for the webpack plugin. Look forward to some cool new webpack functionality next year!