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

Commit 847a56f

Browse files
feat(livesync): enable webpack with watch (#433)
* feat(livesync): enable webpack with watch Plug into NativeScript CLI's LiveSync pipeline in order to enable incremental webpacking with watch. Includes: * Instruct CLI to watch `App_Resources` directory only * Launch `webpack` with `--watch` on before-watch hook * Do not launch multiple `webpack` processes * refactor(livesync): extract app as constant * chore(livesync): make code synchronous * fix: do not rebuild every time * fix: emit absolute paths
1 parent cfc0a57 commit 847a56f

10 files changed

+86
-13
lines changed

lib/before-prepareJS.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ module.exports = function ($mobileHelper, $projectData, hookArgs) {
77
const config = {
88
env,
99
platform,
10-
bundle: appFilesUpdaterOptions.bundle,
11-
watch: false // TODO: Read from CLI options...
10+
bundle: appFilesUpdaterOptions.bundle
1211
};
1312
const result = config.bundle && runWebpackCompiler.bind(runWebpackCompiler, config, $mobileHelper, $projectData, hookArgs);
1413
return result;

lib/before-watch.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const { runWebpackCompiler } = require("./compiler");
2+
3+
module.exports = function ($mobileHelper, $projectData, hookArgs) {
4+
if (hookArgs.config) {
5+
const appFilesUpdaterOptions = hookArgs.config.appFilesUpdaterOptions;
6+
if (appFilesUpdaterOptions.bundle) {
7+
const platforms = hookArgs.config.platforms;
8+
return Promise.all(platforms.map(platform => {
9+
const env = hookArgs.config.env || {};
10+
const config = {
11+
env,
12+
platform,
13+
bundle: appFilesUpdaterOptions.bundle,
14+
watch: true
15+
};
16+
17+
return runWebpackCompiler(config, $mobileHelper, $projectData, hookArgs);
18+
}));
19+
}
20+
}
21+
}

lib/before-watchPatterns.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const { AppDirectoryLocation } = require("./constants");
2+
3+
module.exports = function (hookArgs) {
4+
if (hookArgs.liveSyncData && hookArgs.liveSyncData.bundle) {
5+
return (args, originalMethod) => {
6+
return originalMethod().then(originalPatterns => {
7+
const appDirectoryLocationIndex = originalPatterns.indexOf(AppDirectoryLocation);
8+
if (appDirectoryLocationIndex !== -1) {
9+
originalPatterns.splice(appDirectoryLocationIndex, 1);
10+
}
11+
12+
return originalPatterns;
13+
});
14+
};
15+
}
16+
}

lib/compiler.js

+17-9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const { join, resolve: pathResolve } = require("path");
44
const { existsSync } = require("fs");
55
const readline = require("readline");
66
const { messages } = require("../plugins/WatchStateLoggerPlugin");
7+
const { AppDirectoryLocation } = require("./constants");
78

89
let hasBeenInvoked = false;
910

@@ -16,25 +17,19 @@ exports.getWebpackProcess = function getWebpackProcess() {
1617
exports.runWebpackCompiler = function runWebpackCompiler(config, $mobileHelper, $projectData, hookArgs, originalArgs, originalMethod) {
1718
if (config.bundle) {
1819
return new Promise(function (resolveBase, rejectBase) {
19-
if (hookArgs && hookArgs.config && hookArgs.config.changesInfo) {
20-
hookArgs.config.changesInfo.nativeChanged = true;
20+
if (webpackProcess) {
21+
return resolveBase();
2122
}
2223

2324
let isResolved = false;
2425
function resolve() {
2526
if (isResolved) return;
2627
isResolved = true;
27-
if (childProcess) {
28-
childProcess.removeListener("message", resolveOnWebpackCompilationComplete);
29-
}
3028
resolveBase();
3129
}
3230
function reject(error) {
3331
if (isResolved) return;
3432
isResolved = true;
35-
if (childProcess) {
36-
childProcess.removeListener("message", resolveOnWebpackCompilationComplete);
37-
}
3833
rejectBase(error);
3934
}
4035

@@ -75,11 +70,24 @@ exports.runWebpackCompiler = function runWebpackCompiler(config, $mobileHelper,
7570
cwd: $projectData.projectDir
7671
});
7772

73+
let isFirstWebpackWatchCompilation = true;
7874
function resolveOnWebpackCompilationComplete(message) {
7975
if (message === messages.compilationComplete) {
80-
console.log("Initial webpack build done!");
76+
console.log("Webpack build done!");
8177
resolve();
8278
}
79+
80+
if (message.emittedFiles) {
81+
if (isFirstWebpackWatchCompilation) {
82+
isFirstWebpackWatchCompilation = false;
83+
return;
84+
}
85+
86+
if (hookArgs.filesToSync && hookArgs.startSyncFilesTimeout) {
87+
hookArgs.filesToSync.push(...message.emittedFiles.map(emittedFile => join($projectData.projectDir, AppDirectoryLocation, emittedFile)));
88+
hookArgs.startSyncFilesTimeout();
89+
}
90+
}
8391
}
8492

8593
if (config.watch) {

lib/constants.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
AppDirectoryLocation: "app"
3+
};

package.json

+10
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@
2020
"script": "lib/before-cleanApp.js",
2121
"inject": true
2222
},
23+
{
24+
"type": "before-watch",
25+
"script": "lib/before-watch.js",
26+
"inject": true
27+
},
28+
{
29+
"type": "before-watchPatterns",
30+
"script": "lib/before-watchPatterns.js",
31+
"inject": true
32+
},
2333
{
2434
"type": "after-prepare",
2535
"script": "lib/after-prepare.js",

plugins/WatchStateLoggerPlugin.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,29 @@ export class WatchStateLoggerPlugin {
1313
isRunningWatching: boolean;
1414
apply(compiler) {
1515
const plugin = this;
16-
compiler.plugin("watch-run", function(compiler, callback) {
16+
compiler.plugin("watch-run", function (compiler, callback) {
1717
plugin.isRunningWatching = true;
1818
if (plugin.isRunningWatching) {
1919
console.log(messages.changeDetected);
2020
}
2121
process.send && process.send(messages.changeDetected, error => null);
2222
callback();
2323
});
24-
compiler.plugin("after-emit", function(compilation, callback) {
24+
compiler.plugin("after-emit", function (compilation, callback) {
2525
callback();
2626
if (plugin.isRunningWatching) {
2727
console.log(messages.startWatching);
2828
} else {
2929
console.log(messages.compilationComplete);
3030
}
31+
32+
const emittedFiles = Object
33+
.keys(compilation.assets)
34+
.filter(assetKey => compilation.assets[assetKey].emitted);
35+
3136
process.send && process.send(messages.compilationComplete, error => null);
37+
// Send emitted files so they can be LiveSynced if need be
38+
process.send && process.send({ emittedFiles }, error => null);
3239
});
3340
}
3441
}

templates/webpack.angular.js

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ module.exports = env => {
2020

2121
const config = {
2222
context: resolve("./app"),
23+
watchOptions: {
24+
ignored: resolve("./app/App_Resources")
25+
},
2326
target: nativescriptTarget,
2427
entry: {
2528
bundle: aot ? "./main.aot.ts" : "./main.ts",

templates/webpack.javascript.js

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ module.exports = env => {
1818

1919
const config = {
2020
context: resolve("./app"),
21+
watchOptions: {
22+
ignored: resolve("./app/App_Resources")
23+
},
2124
target: nativescriptTarget,
2225
entry: {
2326
bundle: `./${nsWebpack.getEntryModule()}`,

templates/webpack.typescript.js

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ module.exports = env => {
1818

1919
const config = {
2020
context: resolve("./app"),
21+
watchOptions: {
22+
ignored: resolve("./app/App_Resources")
23+
},
2124
target: nativescriptTarget,
2225
entry: {
2326
bundle: `./${nsWebpack.getEntryModule()}`,

0 commit comments

Comments
 (0)