Skip to content
This repository was archived by the owner on Aug 7, 2021. It is now read-only.

Commit e9fa93d

Browse files
committed
feat: generate the snapshot entry module at build time
fixes #511
1 parent 2ff43bf commit e9fa93d

File tree

5 files changed

+98
-46
lines changed

5 files changed

+98
-46
lines changed

Diff for: plugins/NativeScriptSnapshotPlugin/index.js

+44-12
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,56 @@
1-
const { resolve, join } = require("path");
2-
const { closeSync, openSync } = require("fs");
1+
const { relative, resolve, join } = require("path");
2+
const { closeSync, openSync, writeFileSync } = require("fs");
33
const validateOptions = require("schema-utils");
44

55
const ProjectSnapshotGenerator = require("../../snapshot/android/project-snapshot-generator");
6-
const { resolveAndroidAppPath } = require("../../projectHelpers");
6+
const { resolveAndroidAppPath, getAndroidProjectPath } = require("../../projectHelpers");
77
const schema = require("./options.json");
88

9+
const SNAPSHOT_ENTRY_NAME = "snapshot-entry";
10+
const SNAPSHOT_ENTRY_MODULE = `${SNAPSHOT_ENTRY_NAME}.js`;
11+
912
exports.NativeScriptSnapshotPlugin = (function() {
1013
function NativeScriptSnapshotPlugin(options) {
1114
NativeScriptSnapshotPlugin.validateSchema(options);
12-
if (options.chunk) {
13-
options.chunks = options.chunks || [];
14-
options.chunks.push(options.chunk);
15-
}
1615

1716
ProjectSnapshotGenerator.call(this, options);
1817

19-
if (this.options.webpackConfig) {
20-
if (this.options.webpackConfig.output && this.options.webpackConfig.output.libraryTarget) {
21-
this.options.webpackConfig.output.libraryTarget = undefined;
22-
}
18+
const { webpackConfig } = this.options;
19+
NativeScriptSnapshotPlugin.removeLibraryTarget(webpackConfig);
20+
21+
const { entry } = webpackConfig;
22+
if (typeof entry === "string" || Array.isArray(entry)) {
23+
webpackConfig.entry = { bundle: entry };
24+
}
25+
26+
NativeScriptSnapshotPlugin.ensureSnapshotModuleEntry(this.options);
27+
}
28+
29+
NativeScriptSnapshotPlugin.removeLibraryTarget = function(webpackConfig) {
30+
const { output } = webpackConfig;
31+
if (output) {
32+
output.libraryTarget = undefined;
2333
}
2434
}
2535

36+
NativeScriptSnapshotPlugin.ensureSnapshotModuleEntry = function(options) {
37+
const { webpackConfig, requireModules, chunks, projectRoot } = options;
38+
39+
const androidProjectPath = getAndroidProjectPath({ projectRoot: projectRoot });
40+
const snapshotEntryPath = join(androidProjectPath, SNAPSHOT_ENTRY_MODULE);
41+
const snapshotEntryContent = requireModules.map(mod => `require('${mod}')`).join(";");
42+
writeFileSync(snapshotEntryPath, snapshotEntryContent, { encoding: "utf8" });
43+
44+
// add the module to the entry points to make sure it's content is evaluated
45+
webpackConfig.entry[SNAPSHOT_ENTRY_NAME] = relative(webpackConfig.context, snapshotEntryPath);
46+
47+
// prepend the module to the script that will be snapshotted
48+
chunks.unshift(SNAPSHOT_ENTRY_NAME);
49+
50+
// ensure that the runtime is installed only in the snapshotted chunk
51+
webpackConfig.optimization.runtimeChunk = { name: SNAPSHOT_ENTRY_NAME };
52+
}
53+
2654
NativeScriptSnapshotPlugin.validateSchema = function(options) {
2755
if (!options.chunk && !options.chunks) {
2856
const error = NativeScriptSnapshotPlugin.extendError({ message: `No chunks specified!` });
@@ -31,12 +59,16 @@ exports.NativeScriptSnapshotPlugin = (function() {
3159

3260
try {
3361
validateOptions(schema, options, "NativeScriptSnapshotPlugin");
62+
63+
if (options.chunk) {
64+
options.chunks = options.chunks || [];
65+
options.chunks.push(options.chunk);
66+
}
3467
} catch (error) {
3568
throw new Error(error.message);
3669
}
3770
}
3871

39-
// inherit ProjectSnapshotGenerator
4072
NativeScriptSnapshotPlugin.prototype = Object.create(ProjectSnapshotGenerator.prototype);
4173
NativeScriptSnapshotPlugin.prototype.constructor = NativeScriptSnapshotPlugin;
4274

Diff for: plugins/NativeScriptSnapshotPlugin/options.json

+28-4
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,40 @@
1313
"projectRoot": {
1414
"type": "string"
1515
},
16-
"webpackConfig": {},
16+
"webpackConfig": {
17+
"type": "object"
18+
},
1719
"targetArchs": {
18-
"type": "array"
20+
"type": "array",
21+
"default": [
22+
"arm",
23+
"arm64",
24+
"ia32"
25+
],
26+
"items": {
27+
"type": "string",
28+
"enum": [
29+
"arm",
30+
"arm64",
31+
"ia32"
32+
]
33+
}
1934
},
2035
"useLibs": {
21-
"type": "boolean"
36+
"type": "boolean",
37+
"default": false
2238
},
2339
"v8Version": {
24-
"type": "string"
40+
"type": "string"
41+
},
42+
"requireModules": {
43+
"type": "array",
44+
"default": []
2545
}
2646
},
47+
"required": [
48+
"projectRoot",
49+
"webpackConfig"
50+
],
2751
"additionalProperties": false
2852
}

Diff for: templates/webpack.angular.js

+12-8
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ module.exports = env => {
5252
nsWebpack.getAotEntryModule(appFullPath) :
5353
`${nsWebpack.getEntryModule(appFullPath)}.ts`;
5454
const entryPath = `.${sep}${entryModule}`;
55-
const vendorPath = `.${sep}vendor.ts`;
5655

5756
const config = {
5857
mode: production ? "production" : "development",
@@ -67,7 +66,6 @@ module.exports = env => {
6766
target: nativescriptTarget,
6867
entry: {
6968
bundle: entryPath,
70-
vendor: vendorPath,
7169
},
7270
output: {
7371
pathinfo: false,
@@ -103,7 +101,6 @@ module.exports = env => {
103101
},
104102
devtool: "none",
105103
optimization: {
106-
runtimeChunk: { name: "vendor" },
107104
splitChunks: {
108105
cacheGroups: {
109106
common: {
@@ -113,7 +110,6 @@ module.exports = env => {
113110
const moduleName = module.nameForCondition ? module.nameForCondition() : '';
114111
return /[\\/]node_modules[\\/]/.test(moduleName) ||
115112
appComponents.some(comp => comp === moduleName);
116-
117113
},
118114
enforce: true,
119115
},
@@ -186,7 +182,6 @@ module.exports = env => {
186182
], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }),
187183
// Generate a bundle starter script and activate it in package.json
188184
new nsWebpack.GenerateBundleStarterPlugin([
189-
"./vendor",
190185
"./common",
191186
"./bundle",
192187
]),
@@ -210,9 +205,9 @@ module.exports = env => {
210205

211206
if (platform === "android") {
212207
// Require all Android app components
213-
// in the entry module (bundle.ts) and the vendor module (vendor.ts).
208+
// in the entry module (bundle.ts)
214209
config.module.rules.unshift({
215-
test: new RegExp(`${entryPath}|${vendorPath}`),
210+
test: new RegExp(`${entryPath}`),
216211
use: {
217212
loader: "nativescript-dev-webpack/android-app-components-loader",
218213
options: { modules: appComponents }
@@ -233,7 +228,16 @@ module.exports = env => {
233228

234229
if (snapshot) {
235230
config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({
236-
chunks: [ "vendor", "common" ],
231+
chunk: "common",
232+
requireModules: [
233+
"reflect-metadata",
234+
"@angular/platform-browser",
235+
"@angular/core",
236+
"@angular/common",
237+
"@angular/router",
238+
"nativescript-angular/platform-static",
239+
"nativescript-angular/router",
240+
],
237241
projectRoot,
238242
webpackConfig: config,
239243
targetArchs: ["arm", "arm64", "ia32"],

Diff for: templates/webpack.javascript.js

+7-11
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ module.exports = env => {
4848

4949
const entryModule = nsWebpack.getEntryModule(appFullPath);
5050
const entryPath = `.${sep}${entryModule}.js`;
51-
const vendorPath = `.${sep}vendor.js`;
5251

5352
const config = {
5453
mode: production ? "production" : "development",
@@ -63,7 +62,6 @@ module.exports = env => {
6362
target: nativescriptTarget,
6463
entry: {
6564
bundle: entryPath,
66-
vendor: vendorPath,
6765
},
6866
output: {
6967
pathinfo: false,
@@ -99,7 +97,6 @@ module.exports = env => {
9997
},
10098
devtool: "none",
10199
optimization: {
102-
runtimeChunk: { name: "vendor" },
103100
splitChunks: {
104101
cacheGroups: {
105102
common: {
@@ -167,9 +164,8 @@ module.exports = env => {
167164
], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }),
168165
// Generate a bundle starter script and activate it in package.json
169166
new nsWebpack.GenerateBundleStarterPlugin([
170-
"./vendor", // install webpackJsonpCallback
171-
"./common", // require app/vendor.js
172-
"./bundle", // require the entry module (app/app.js)
167+
"./common",
168+
"./bundle",
173169
]),
174170
// Support for web workers since v3.2
175171
new NativeScriptWorkerPlugin(),
@@ -184,9 +180,9 @@ module.exports = env => {
184180

185181
if (platform === "android") {
186182
// Require all Android app components
187-
// in the entry module (bundle.js) and the vendor module (vendor.js).
183+
// in the entry module (bundle.js).
188184
config.module.rules.unshift({
189-
test: new RegExp(`${entryPath}|${vendorPath}`),
185+
test: new RegExp(`${entryPath}`),
190186
use: {
191187
loader: "nativescript-dev-webpack/android-app-components-loader",
192188
options: { modules: appComponents }
@@ -207,9 +203,9 @@ module.exports = env => {
207203

208204
if (snapshot) {
209205
config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({
210-
chunks: [
211-
"common",
212-
"vendor",
206+
chunk: "common",
207+
requireModules: [
208+
"tns-core-modules/bundle-entry-points",
213209
],
214210
projectRoot,
215211
webpackConfig: config,

Diff for: templates/webpack.typescript.js

+7-11
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ module.exports = env => {
4848

4949
const entryModule = nsWebpack.getEntryModule(appFullPath);
5050
const entryPath = `.${sep}${entryModule}.ts`;
51-
const vendorPath = `.${sep}vendor.ts`;
5251

5352
const config = {
5453
mode: production ? "production" : "development",
@@ -63,7 +62,6 @@ module.exports = env => {
6362
target: nativescriptTarget,
6463
entry: {
6564
bundle: entryPath,
66-
vendor: vendorPath,
6765
},
6866
output: {
6967
pathinfo: false,
@@ -99,7 +97,6 @@ module.exports = env => {
9997
},
10098
devtool: "none",
10199
optimization: {
102-
runtimeChunk: { name: "vendor" },
103100
splitChunks: {
104101
cacheGroups: {
105102
common: {
@@ -169,9 +166,8 @@ module.exports = env => {
169166
], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }),
170167
// Generate a bundle starter script and activate it in package.json
171168
new nsWebpack.GenerateBundleStarterPlugin([
172-
"./vendor", // install webpackJsonpCallback
173-
"./common", // require app/vendor.js
174-
"./bundle", // require the entry module (app/app.js)
169+
"./common",
170+
"./bundle",
175171
]),
176172
// Support for web workers since v3.2
177173
new NativeScriptWorkerPlugin(),
@@ -186,9 +182,9 @@ module.exports = env => {
186182

187183
if (platform === "android") {
188184
// Require all Android app components
189-
// in the entry module (bundle.ts) and the vendor module (vendor.ts).
185+
// in the entry module (bundle.ts).
190186
config.module.rules.unshift({
191-
test: new RegExp(`${entryPath}|${vendorPath}`),
187+
test: new RegExp(`${entryPath}`),
192188
use: {
193189
loader: "nativescript-dev-webpack/android-app-components-loader",
194190
options: { modules: appComponents }
@@ -209,9 +205,9 @@ module.exports = env => {
209205

210206
if (snapshot) {
211207
config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({
212-
chunks: [
213-
"common",
214-
"vendor",
208+
chunk: "common",
209+
requireModules: [
210+
"tns-core-modules/bundle-entry-points",
215211
],
216212
projectRoot,
217213
webpackConfig: config,

0 commit comments

Comments
 (0)