Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Nov 17, 2022. It is now read-only.

Commit e5494ad

Browse files
NickIlievvchimev
authored and
vchimev
committed
refactor: Add instruction about webpack configs, updates and AOT files requrments
1 parent 345201e commit e5494ad

File tree

1 file changed

+41
-39
lines changed

1 file changed

+41
-39
lines changed

‎docs/best-practices/bundling-with-webpack.md‎

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,22 @@ The plugin adds a few dependencies to the project. Don't forget to install them:
6464
$ npm install
6565
```
6666

67+
We can generate new config files using the command below:
68+
```
69+
$ ./node_modules/.bin/update-ns-webpack --configs --deps --scripts
70+
```
71+
72+
> Note: Make sure to commit your current version of all WebPack related files:
73+
```
74+
./app/vendor-platform.android.ts
75+
./app/vendor-platform.ios.ts
76+
./app/vendor.ts
77+
./tsconfig.aot.json
78+
./tsconfig.json
79+
./webpack.config.json
80+
```
81+
82+
6783
#### XML Pages and Code-behind Files
6884

6985
XML page definitions load JavaScript modules named with the same name as the XML file that contains the UI markup. To make those work with webpack bundles, you need to register them as dynamic modules:
@@ -76,11 +92,15 @@ Here's an example [configuration](https://github.com/NickIliev/NativeScript-Cosm
7692

7793
For non-Angular apps, make sure to add `bundle-config.js|ts` file in the `app` folder with the following content:
7894

79-
```
80-
if (global["TNS_WEBPACK"]) {
81-
require("tns-core-modules/bundle-entry-points");
82-
global.registerModule("main-page", function () { return require("./main-page"); });
83-
// register more application modules here following the example above
95+
```JavaScript
96+
if (global.TNS_WEBPACK) {
97+
// registers tns-core-modules UI framework modules
98+
require("bundle-entry-points");
99+
100+
// register application modules
101+
// This will register each `page` postfixed xml, css, js, ts, scss etc. in app/ folder
102+
const context = require.context("~/", true, /page\.(xml|css|js|ts|scss|less|sass)$/);
103+
global.registerWebpackModules(context);
84104
}
85105
```
86106

@@ -157,13 +177,10 @@ $ tns build android --bundle --env.development --env.property=value
157177

158178
They can be accessed through the `env` object in the WebPack configuration:
159179

160-
```js
180+
```JavaScript
161181
// webpack.config.js
162-
163-
...
164182
module.exports = env => {
165183
console.dir(env); // { development: true, property: 'value' }
166-
...
167184
}
168185
```
169186

@@ -203,37 +220,22 @@ More options for publishing an iOS application can be found in the ["Publishing
203220
NativeScript Angular projects will also have the [`@ngtools/webpack`](https://www.npmjs.com/package/@ngtools/webpack) plugin added. The former performs Ahead-of-Time compilation and code splitting for lazily loaded modules. Also, if your application is Ahead-of-Time compiled, you won't have Angular compiler included in your bundle which results in smaller application size and improved start up time.
204221
To take advantage of Ahead-of-Time compilation, you need to bootstrap your app with the static NativeScript Angular platform instead of the dynamic one. For that, you will have to create a `main.aot.ts` file next to your `app/main.ts` file. Also make sure, that the `main` property in your `app/package.json` is `main.js`. If your root NgModule is named `AppModule` and is located in `app/app.module.ts`, the content of the `main.aot.ts` file should be the following:
205222

206-
```ts
223+
```TypeScript
207224
// app/main.aot.ts
208225
import { platformNativeScript } from "nativescript-angular/platform-static";
209226
import { AppModuleNgFactory } from "./app.module.ngfactory";
210227

211228
platformNativeScript().bootstrapModuleFactory(AppModuleNgFactory);
212229
```
213230

214-
Note that the `./app.module.ngfactory` file still does not exist. It will be in-memory generated by the Angular compiler (ngc) during build time. That's why you don't want TypeScript to try to compile the `main.aot.ts` file and fail. You can exclude it from compilation by configuring your `tsconfig.json`:
215-
216-
```ts
217-
// tsconfig.json
218-
{
219-
"compilerOptions": {
220-
...
221-
"paths": {
222-
"~/*": [
223-
"app/*"
224-
],
225-
"*": [
226-
"./node_modules/tns-core-modules/*",
227-
"./node_modules/*"
228-
]
229-
}
230-
},
231-
"exclude": [
232-
...
233-
"app/main.aot.ts"
234-
]
235-
}
231+
Note that the `./app.module.ngfactory` file still does not exist. It will be in-memory generated by the Angular compiler (ngc) during build time. For TypeScript to compile the `main.aot.ts` file we will need explicit declaration in `app/app.module.ngfactory.d.ts`:
236232

233+
```TypeScript
234+
// app/app.module.ngfactory.d.ts
235+
/*
236+
* A dynamically generated module when compiled with AoT.
237+
*/
238+
export const AppModuleNgFactory: any;
237239
```
238240

239241
PS: If you created your project with `tns create AppName --ng`, it will already be prepared for Ahead-of-Time compilation.
@@ -262,7 +264,7 @@ new CopyWebpackPlugin([
262264
When the application is implementing workers some additional steps are required to make the project WebPack compatible. Use `nativescript-worker-loader` plugin.
263265

264266
```
265-
npm i nativescript-worker-loader -D
267+
$ npm i nativescript-worker-loader -D
266268
```
267269

268270
Detailed instructions on how to implement WebPack compatible workers can be found in [this demonstration applicaiton](https://github.com/NativeScript/worker-loader#usage).
@@ -358,7 +360,7 @@ $ tns build android --bundle --env.report
358360

359361
The `NativeScriptSnapshotPlugin` by default comes with the following configuration:
360362

361-
```
363+
```JavaScript
362364
if (env.snapshot) {
363365
plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({
364366
chunk: "vendor",
@@ -379,7 +381,7 @@ if (env.snapshot) {
379381
1. The static binding generator saves the path to the file containing its JavaScript implementation in the class metadata.
380382
2. Before instantiating the class, the runtime loads and executes the module at the path saved in the metadata, assuming that this will evaluate the class extending code.
381383
When bundling with Webpack, the saved path in the metadata always points to the bundle script. However, depending on configurations, executing the bundle script may not evaluate the module containing the Java class definition. Therefore, instead of relying on the Android runtime mechanism to automatically load the JavaScript counterparts we load them on startup by explicitly adding `require` calls to such modules in our default `app/vendor-platform.android` module:
382-
```
384+
```JavaScript
383385
require("application");
384386
if (!global["__snapshot"]) {
385387
/*
@@ -391,15 +393,15 @@ if (env.snapshot) {
391393
}
392394
```
393395
However, when we add the V8 heap snapshot in the whole story, we are not allowed to extend native classes in snapshotted context. Therefore, we always include `ui/frame` and `ui/frame/activity` in the bundle but when snapshot is enabled they are not evaluated. Here is where the `tns-java-classes.js` file comes into play. Just after initialization, the Android runtime [will evaluate the script at `app/tns-java-classes.js` path if such exists](https://github.com/NativeScript/android-runtime/commit/d13189e4206b374142dc61d309d5aa708fb8095f). The snapshot generator creates such file and populates it with `require` calls to a user defined list of paths. This way, they are explicitly evaluated on app startup. You can add paths to be `require`-d in `tns-java-classes.js` like this:
394-
```
396+
```JavaScript
395397
new nsWebpack.NativeScriptSnapshotPlugin({
396398
...
397399
tnsJavaClassesOptions: { modules: ["path/to/file1.js", "path-to-module", "path/to/other-script"] }
398400
...
399401
});
400402
```
401403
If you are a plugin author and your plugin contains a module that have to be listed here, you can specify it in your plugin's `package.json` file:
402-
```
404+
```JSON
403405
"snapshot": {
404406
"android": {
405407
"tns-java-classes": {
@@ -409,7 +411,7 @@ if (env.snapshot) {
409411
}
410412
```
411413
This gives the opportunity to the plugin's clients to add all needed paths in their `tns-java-classes.js` file only by specifying the name of your package:
412-
```
414+
```JS
413415
new nsWebpack.NativeScriptSnapshotPlugin({
414416
...
415417
tnsJavaClassesOptions: { packages: ["my-package" ] }
@@ -418,7 +420,7 @@ if (env.snapshot) {
418420
```
419421
#### Checking if snapshot is enabled
420422
If you want to toggle whether specific logic is executed only in snapshotted context you can use the `global.__snapshot` flag. Its value is `true` only if the current execution happens in the snapshotted context. Once the app is deployed on the device, the value of the flag is changed to `false`. There is also `global.__snapshotEnabled` flag. Its only difference compared to `global.__snapshot` is that its value is `true` in both snapshotted and runtime contexts, given that snapshot generation is enabled.
421-
```
423+
```JavaScript
422424
function logMessage(message) {
423425
if (global.__snapshotEnabled) {
424426
if (!global.__snapshot) {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /