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

Commit d30bd90

Browse files
author
Dimitar Kerezov
committed
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
1 parent 07ba1ae commit d30bd90

9 files changed

+90
-10
lines changed

Diff for: lib/before-prepareJS.js

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

Diff for: 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+
platforms.forEach(platform => {
9+
const env = hookArgs.config.env || {};
10+
const config = {
11+
env,
12+
platform,
13+
bundle: appFilesUpdaterOptions.bundle,
14+
watch: true
15+
};
16+
17+
runWebpackCompiler(config, $mobileHelper, $projectData, hookArgs);
18+
});
19+
}
20+
}
21+
}

Diff for: lib/before-watchPatterns.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module.exports = function (hookArgs) {
2+
if (hookArgs.liveSyncData && hookArgs.liveSyncData.bundle) {
3+
const appDirectoryLocation = "app"; // Might need to get this from config file in the future
4+
const appResourcesDirectoryLocation = "app/App_Resources"; // Might need to get this from config file in the future
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+
if (originalPatterns.indexOf(appResourcesDirectoryLocation) === -1) {
13+
originalPatterns.push(appResourcesDirectoryLocation);
14+
}
15+
16+
return originalPatterns;
17+
});
18+
};
19+
}
20+
}

Diff for: lib/compiler.js

+20-7
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 ProjectSnapshotGenerator = require("../snapshot/android/project-snapshot-generator");
78

89
let hasBeenInvoked = false;
910

@@ -16,6 +17,10 @@ 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) {
20+
if (webpackProcess) {
21+
return resolveBase();
22+
}
23+
1924
if (hookArgs && hookArgs.config && hookArgs.config.changesInfo) {
2025
hookArgs.config.changesInfo.nativeChanged = true;
2126
}
@@ -24,17 +29,11 @@ exports.runWebpackCompiler = function runWebpackCompiler(config, $mobileHelper,
2429
function resolve() {
2530
if (isResolved) return;
2631
isResolved = true;
27-
if (childProcess) {
28-
childProcess.removeListener("message", resolveOnWebpackCompilationComplete);
29-
}
3032
resolveBase();
3133
}
3234
function reject(error) {
3335
if (isResolved) return;
3436
isResolved = true;
35-
if (childProcess) {
36-
childProcess.removeListener("message", resolveOnWebpackCompilationComplete);
37-
}
3837
rejectBase(error);
3938
}
4039

@@ -75,11 +74,25 @@ exports.runWebpackCompiler = function runWebpackCompiler(config, $mobileHelper,
7574
cwd: $projectData.projectDir
7675
});
7776

77+
let isFirstWebpackWatchCompilation = true;
7878
function resolveOnWebpackCompilationComplete(message) {
7979
if (message === messages.compilationComplete) {
80-
console.log("Initial webpack build done!");
80+
console.log("Webpack build done!");
8181
resolve();
8282
}
83+
84+
if (message.emittedFiles) {
85+
if (isFirstWebpackWatchCompilation) {
86+
isFirstWebpackWatchCompilation = false;
87+
return;
88+
}
89+
90+
if (hookArgs.filesToSync && hookArgs.startSyncFilesTimeou) {
91+
// TODO: Might need to get the "app" constant from config file in the future
92+
hookArgs.filesToSync.push(...message.emittedFiles.map(emittedFile => join("app", emittedFile)));
93+
hookArgs.startSyncFilesTimeout();
94+
}
95+
}
8396
}
8497

8598
if (config.watch) {

Diff for: package.json

+10
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@
1515
"script": "lib/before-prepareJS.js",
1616
"inject": true
1717
},
18+
{
19+
"type": "before-watch",
20+
"script": "lib/before-watch.js",
21+
"inject": true
22+
},
23+
{
24+
"type": "before-watchPatterns",
25+
"script": "lib/before-watchPatterns.js",
26+
"inject": true
27+
},
1828
{
1929
"type": "after-prepare",
2030
"script": "lib/after-prepare.js",

Diff for: 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
}

Diff for: 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",

Diff for: 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()}`,

Diff for: 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)