Using "bundle-config" in {N} projects


#1

As of {N} 2.5, new NativeScript projects include a “bundle-config” file (.ts or .js depending on your template choice). It’s clear that this is related to WebPack, but I’ve got questions. :slight_smile:

  1. Is this file being used by default? Or do you have to do something to enable it in the build process?
  2. Does this file have to be manually maintained?
  3. Do you have to put every module you create in this file? Only some?
  4. Why should I use this bundle-config approach? Any advantages?

In my case, I’m just using TypeScript (no Angular). I assume that might might some difference in your decision to use WebPack/bundle-config. Also primarily targeting iOS.

Help a poor WebPack neophyte fill-in the gaps.


#2

OK WebPackers, start your engines. @triniwiz what say you? @bradwaynemartin?


#3

Here (https://github.com/NativeScript/NativeScript/blob/master/tns-core-modules/bundle-entry-points.ts) is the bundle-entry-points in the core which looks to explicitly declare all the core-modules for bundling so I assume you need to declare any module you want to webpack in the bundle-config.


#4

Let’s unpack this webpack guidance some more… :slight_smile:

Why would I want to begin using webpack in the first place? What are the advantages for my {N} build over the “standard” {N} build process?

And to that end, if I want to enable webpack builds, what else do I need to do other than updating this bundle-config file?

We’ve got to distill this to 101.


#5

I’ve not used webpack with NS yet, plan to look into it more in the future. Quickly reviewing the docs on webpack with NS (http://docs.nativescript.org/tooling/bundling-with-webpack#how-nativescript-dev-webpack-works) seems to do a decent explanation I think. I’m sure it could be improved of course.

Specifically the Overview is helpful to know what webpack does http://docs.nativescript.org/tooling/bundling-with-webpack#overview


#6

Personally I don’t have a need to use webpack since I don’t use Angular. The startup speed and overall app size for plain NS apps isn’t an issue for me. App starts with the snapshots on android are 1-3 seconds. First run maybe 4-6 seconds from my testing.

Hopefully with Angular 4 reducing their overall footprint, once NS merges that in the overall angular+nativescript app size will reduce with some perf also.


#7

Let’s do some 101 on why you should care about webpack in the first place.

Because NativeScript runs JavaScript code, the JavaScript code that NativeScript interprets at runtime will be included in your final executable—aka either your .apk file on Android or your .ipa file on iOS.

There are two performance ramifications to this approach.

The first is easy to understand—every byte of JavaScript code you include in your app increases the size of your application bundle. Because one of the things webpack does is compress your JavaScript code, by using webpack you end up with less JavaScript code in your executable, and therefore smaller app bundles. (And less bloat for your users when they download your app from the stores.)

The second performance ramification is more interesting. When NativeScript starts up your app it must register all of your JavaScript code with the JavaScript Virtual Machine that NativeScript includes in your app bundle. Think of this like V8 interpreting a <script> tag in Chrome, or JavaScriptCore interpreting a <script> tag in Safari. Much like adding a bunch of <script> tags will slow down your web app, feeding a bunch of JavaScript into NativeScript’s JavaScript virtual machine will slow down the load of your native app.

The primary reason NativeScript apps start a bit slower than purely native apps is due to this—NativeScript has to wait until your JavaScript code has been interpreted by the appropriate JavaScript virtual machine before running your app. (This concern, by the way, applies to other JavaScript-driven native frameworks like React Native and Appcelerator Titanium.)

Simply put, the more JavaScript code you include in your app the longer it’ll take for your application to load. In NativeScript Core apps this isn’t a huge deal unless your app is quite large, but in NativeScript apps with Angular, the sheer size of Angular can make this a problem right away.

Webpack has the ability to do things like tree shaking that can remove unused code, which reduces the amount of code NativeScript needs to pass to the JavaScript virtual machine at runtime, which speeds up your app’s loading time. In the case of NativeScript with Angular the speed improvements can be drastic, especially on Android.

With that background out of the way let’s return to your original questions:

Is this file being used by default? Or do you have to do something to enable it in the build process?

No, the file is not used by default. You need to install the webpack plugin and run bundled builds to leverage the file.

In general it’s only recommend that you only run these bundled builds when you’re getting ready to release to the app stores. This is because bundled builds take longer, as it takes some time for webpack to do its thing.

Does this file have to be manually maintained?

Yes, and this is kind of annoying. You can refer to the starter template on GitHub for updates, but we should think of ways we can make this easier.

Do you have to put every module you create in this file? Only some?
Why should I use this bundle-config approach? Any advantages?

For these questions I’ll defer to our experts that have a bit more webpack knowledge. The one webpack-enabled app that I maintain, Groceries doesn’t use this bundle-config file at all, so I’m kind of curious what this file is doing as well.


#8

Super helpful! Thanks for the background and direct answers.

My TL;DR so far…

  • Unless you actively setup webpack, you can safely ignore (or even delete) the bundle-config file in new {N} projects
  • Webpack in {N} is mostly beneficial for apps using Angular due to Angular’s size
  • If you are generally happy with your {N} app load time, you probably don’t need webpack yet
  • If you do use Webpack, don’t use it for every build during development (just release builds)
  • No-one is quite sure yet how/why to use the bundle-config file :slight_smile:

Is that correct?

Would be interesting to add webpack comparisons to {N} performance benchmarks. Wonder how much improvement it might offer to apps not using Angular, too…


#9

Yep, excellent tl;dr summary :smile:

Webpack definitely does improve your load times in {N} core apps, the effect is just not as pronounced. And yes, if you’re happy with your app’s size and loading times then you have no need for webpack. The downside of introducing webpack is you have another thing to maintain over time.


#10

Okay. Cool. So back to the bundle-config

Based on the documentation, it seems as though you need to register any XML UI file that has an associated “code behind” JS file. Does that sound right?

I’m guessing bundle-config is meant to be the place you register all XML/code behind combos to make sure they get included in webpacking.

The one thing that remains unclear is if webpack will “discover” some of these XML/code behind files on its own after you register your app’s initial entry point…or if you must register EVERY. SINGLE. XML UI. Look forward to some expert clarification. :slight_smile:

@TJ: Since you say you are using WebPack, but not bundle-config, is it safe to assume you get some webpack value even if you skip this bundle-config setup?


#11

Think I read on the docs or in the source that you have to register every module (xml/code) or it won’t work with the bundle-config route.


#12

I feel like this could turn into a support group thread for webpack users. I myself failed dismally getting webpack to work in PocketRave or PracticeBuddy, my two Angular apps in production. These both badly need to be webpacked as they have a big app size for a pretty basic app and are a bit slow to startup.

I believe my failure is due to the fact that I wasn’t able to make webpack work with the plugins that I was using. From what I understand, some plugins need tweaking to work properly with webpack.

I am willing to stand corrected on this, but so far I have not been able to webpack my Angular apps yet. @triniwiz, @wwwalkerrun and @nathanaela have been more successful than myself on this front. Why we have this file suddenly appear is a question we ought to ask of engineering, but I feel like it’s intended to help us organize our webpackable assets.

Now, I need to use it.


#13

Ah! The plugins.

Really, it is this “fear” of plugin incompatibility that has also made me slow to adopt Angular in a lot of my apps. Feels like an area that we as a community need to focus on improving even more: consistent support in plugins for Angular, WebPack, TypeScript, etc.

I’m interested in giving WebPack a try, but need to validate the plugins I’m using will work. Maybe as a first step we can provide some validation steps?


#14

I’ve just finished setting up webpack on a new non-Angular app, and here are some things to consider:

  1. You need to install nativescript-dev-webpack which will install all dependencies and will add the needed npm scripts in the package.json file
  2. In the bundle-config.ts file you must specify only the view modules and any plugins/code that you do not require anywhere. As an example I’m using the PullToRefresh plugin and since I’ve used it only the XML files and not using it in code, I had to register it. Any other module will be picked from webpack when it builds the dependencies of the view files.
    Also note that it is really important to register your views exactly with the same name as you use them when you navigate to the view. For example if you navigate if you use frame.topmost().navigate("./welcome") and in the bundle config you have global.registerModule("welcome", () => require("./welcome")); the view will not work as expected.

As for plugin support - so far the only two things that are important for webpack compatibility are mentioned in the doc article https://docs.nativescript.org/tooling/bundling-with-webpack#recommendations-for-plugin-authors

The gain (tested on iPhone 6+ with an IPA built with the --release flag):
IPA Size:
w/o webpack - 13.5 MB
w/ webpack+uglify - 12.5 MB

1st Run (time to get to initial view):
w/o webpack - ~3sec
w/ webpack+uglify - ~2sec

2+ Run (time to get to initial view):
w/o webpack - ~2sec
w/ webpack+uglify - ~2sec, but seems was still very slightly faster than w/o webpack


#15

Just web-packed my app (Typescript) and I’m also noticing minimal improvements.

I’m just eye-balling the startup times and they seem to be about 3-4 seconds - both with and without webpacking.

Is this normal?


#16

Nobody seemed to mention the fact that you can also use webpack to obfuscate your code. (unless there’s another way to do it that I’m not aware of). The webpack-obfuscator package (https://github.com/javascript-obfuscator/webpack-obfuscator) also seem to be compatible with {N}.