From 9317c2e25aa1d7fe6e49a4f272df0c0fd9936ce9 Mon Sep 17 00:00:00 2001 From: fatme Date: Mon, 10 Sep 2018 16:32:13 +0300 Subject: [PATCH 1/4] * Introduce new "before-preview-sync" hook * Add event handler for "liveSyncStopped" event * Persist webpack process per platform Implements: https://github.com/NativeScript/nativescript-dev-webpack/issues/457 --- lib/after-watch.js | 10 +++----- lib/before-cleanApp.js | 9 ++++--- lib/before-preview-sync.js | 21 ++++++++++++++++ lib/before-watch.js | 50 +++++++++++++++++++++++--------------- lib/compiler.js | 37 +++++++++++++++++++++------- package.json | 5 ++++ 6 files changed, 93 insertions(+), 39 deletions(-) create mode 100644 lib/before-preview-sync.js diff --git a/lib/after-watch.js b/lib/after-watch.js index 37f82b78..d241196d 100644 --- a/lib/after-watch.js +++ b/lib/after-watch.js @@ -1,8 +1,6 @@ -const compiler = require('./compiler'); +const { stopWebpackCompiler } = require('./compiler'); + module.exports = function($logger) { - const webpackProcess = compiler.getWebpackProcess(); - if (webpackProcess) { - $logger.info("Stopping webpack watch"); - webpackProcess.kill("SIGINT"); - } + $logger.info("Stopping webpack watch"); + stopWebpackCompiler(); } diff --git a/lib/before-cleanApp.js b/lib/before-cleanApp.js index ec6e7f60..70a06b0a 100644 --- a/lib/before-cleanApp.js +++ b/lib/before-cleanApp.js @@ -1,13 +1,14 @@ const { cleanSnapshotArtefacts } = require("../snapshot/android/project-snapshot-generator"); const { isAndroid } = require("../projectHelpers"); -const { getWebpackProcess } = require("./compiler"); +const { getWebpackProcesses } = require("./compiler"); module.exports = function (hookArgs) { return (args, originalMethod) => { - const webpackProcess = getWebpackProcess(); - const promise = webpackProcess ? Promise.resolve() : originalMethod(...args); + const platform = hookArgs.platformInfo.platform; + const webpackProcesses = getWebpackProcesses(); + const promise = webpackProcesses[platform] ? Promise.resolve() : originalMethod(...args); return promise.then(() => { - if (isAndroid(hookArgs.platformInfo.platform)) { + if (isAndroid(platform)) { cleanSnapshotArtefacts(hookArgs.platformInfo.projectData.projectDir); } }); diff --git a/lib/before-preview-sync.js b/lib/before-preview-sync.js new file mode 100644 index 00000000..f2f221c2 --- /dev/null +++ b/lib/before-preview-sync.js @@ -0,0 +1,21 @@ +const { runWebpackCompiler } = require("./compiler"); + +module.exports = function($logger, $liveSyncService, hookArgs) { + const { config } = hookArgs; + const bundle = config && config.appFilesUpdaterOptions && config.appFilesUpdaterOptions.bundle; + if (bundle) { + const env = config.env || {}; + const platform = config.platform; + const release = config && config.appFilesUpdaterOptions && config.appFilesUpdaterOptions.release; + const compilerConfig = { + env, + platform, + bundle, + release, + watch: true + }; + + return runWebpackCompiler(compilerConfig, hookArgs.projectData, $logger, $liveSyncService, hookArgs); + } +} + diff --git a/lib/before-watch.js b/lib/before-watch.js index e732a65c..db89c4bf 100644 --- a/lib/before-watch.js +++ b/lib/before-watch.js @@ -1,23 +1,33 @@ -const { runWebpackCompiler } = require("./compiler"); +const { getWebpackProcesses, runWebpackCompiler, stopWebpackCompiler } = require("./compiler"); -module.exports = function ($logger, $liveSyncService, $options, hookArgs) { - if (hookArgs.config) { - const appFilesUpdaterOptions = hookArgs.config.appFilesUpdaterOptions; - if (appFilesUpdaterOptions.bundle) { - const platforms = hookArgs.config.platforms; - return Promise.all(platforms.map(platform => { - const env = hookArgs.config.env || {}; - env.hmr = !!$options.hmr; - const config = { - env, - platform, - bundle: appFilesUpdaterOptions.bundle, - release: appFilesUpdaterOptions.release, - watch: true - }; +module.exports = function ($logger, $liveSyncService, $options, $devicesService, hookArgs) { + if (hookArgs.config) { + const appFilesUpdaterOptions = hookArgs.config.appFilesUpdaterOptions; + if (appFilesUpdaterOptions.bundle) { + $liveSyncService.on("liveSyncStopped", data => { + const webpackProcesses = getWebpackProcesses(); + Object.keys(webpackProcesses).forEach(platform => { + const devices = $devicesService.getDevicesForPlatform(platform); + if (!devices || !devices.length) { + stopWebpackCompiler(platform); + } + }); + }); - return runWebpackCompiler(config, hookArgs.projectData, $logger, $liveSyncService, hookArgs); - })); - } - } + const platforms = hookArgs.config.platforms; + return Promise.all(platforms.map(platform => { + const env = hookArgs.config.env || {}; + env.hmr = !!$options.hmr; + const config = { + env, + platform, + bundle: appFilesUpdaterOptions.bundle, + release: appFilesUpdaterOptions.release, + watch: true + }; + + return runWebpackCompiler(config, hookArgs.projectData, $logger, $liveSyncService, hookArgs); + })); + } + } } diff --git a/lib/compiler.js b/lib/compiler.js index 9e0f92d6..b14e44d2 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -9,17 +9,17 @@ const { buildEnvData, debuggingEnabled } = require("./utils"); let hasBeenInvoked = false; -let webpackProcess = null; +let webpackProcesses = {}; let hasLoggedSnapshotWarningMessage = false; -exports.getWebpackProcess = function getWebpackProcess() { - return webpackProcess; +exports.getWebpackProcesses = function getWebpackProcess() { + return webpackProcesses; } exports.runWebpackCompiler = function runWebpackCompiler(config, $projectData, $logger, $liveSyncService, hookArgs) { if (config.bundle) { return new Promise(function (resolveBase, rejectBase) { - if (webpackProcess) { + if (webpackProcesses[config.platform]) { return resolveBase(); } @@ -77,22 +77,27 @@ exports.runWebpackCompiler = function runWebpackCompiler(config, $projectData, $ if (hookArgs.filesToSync && hookArgs.startSyncFilesTimeout) { hookArgs.filesToSync.push(...message.emittedFiles); - hookArgs.startSyncFilesTimeout(); + hookArgs.startSyncFilesTimeout(platform); + } + + if (hookArgs.filesToSyncMap && hookArgs.startSyncFilesTimeout) { + hookArgs.filesToSyncMap[platform] = message.emittedFiles; + hookArgs.startSyncFilesTimeout(platform); } } } if (config.watch) { childProcess.on("message", resolveOnWebpackCompilationComplete); - if (webpackProcess) { + if (webpackProcesses[platform]) { throw new Error("Webpack process already spawned."); } - webpackProcess = childProcess; + webpackProcesses[platform] = childProcess; } childProcess.on("close", code => { - if (webpackProcess == childProcess) { - webpackProcess = null; + if (webpackProcesses[platform] === childProcess) { + delete webpackProcesses[platform]; } if (code === 0) { resolve(); @@ -106,6 +111,14 @@ exports.runWebpackCompiler = function runWebpackCompiler(config, $projectData, $ } } +exports.stopWebpackCompiler = function stopWebpackCompiler(platform) { + if (platform) { + stopWebpackForPlatform(platform); + } else { + Object.keys(webpackProcesses).forEach(platform => stopWebpackForPlatform(platform)); + } +} + function buildEnvCommandLineParams(config, envData, $logger) { const envFlagNames = Object.keys(envData); const snapshotEnvIndex = envFlagNames.indexOf("snapshot"); @@ -136,3 +149,9 @@ function logSnapshotWarningMessage($logger) { } } +function stopWebpackForPlatform(platform) { + const webpackProcess = webpackProcesses[platform]; + webpackProcess.kill("SIGINT"); + delete webpackProcesses[platform]; +} + diff --git a/package.json b/package.json index 5eaf3f40..23a59da8 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,11 @@ "type": "after-prepare", "script": "lib/after-prepare.js", "inject": true + }, + { + "type": "before-preview-sync", + "script": "lib/before-preview-sync", + "inject": true } ] }, From 35d8560a6877599ecf60d93aca68aab644a62565 Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 12 Sep 2018 18:06:11 +0300 Subject: [PATCH 2/4] feat: add externals to webpack in order to work on android devices --- lib/compiler.js | 4 ++++ templates/webpack.angular.js | 4 +++- templates/webpack.javascript.js | 4 +++- templates/webpack.typescript.js | 2 ++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/compiler.js b/lib/compiler.js index b14e44d2..c8dc010d 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -43,6 +43,10 @@ exports.runWebpackCompiler = function runWebpackCompiler(config, $projectData, $ env["sourceMap"] = true; } + if (hookArgs && hookArgs.externals) { + env.externals = hookArgs.externals; + } + const envData = buildEnvData($projectData, platform, env); const envParams = buildEnvCommandLineParams(config, envData, $logger); diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index cf7e9dc5..a3410b7f 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -42,7 +42,8 @@ module.exports = env => { uglify, // --env.uglify report, // --env.report sourceMap, // --env.sourceMap - hmr, // --env.hmr + hmr, // --env.hmr, + externals } = env; const appFullPath = resolve(projectRoot, appPath); @@ -63,6 +64,7 @@ module.exports = env => { const config = { mode: uglify ? "production" : "development", context: appFullPath, + externals, watchOptions: { ignored: [ appResourcesFullPath, diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index da5748b1..8fe14e09 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -40,7 +40,8 @@ module.exports = env => { uglify, // --env.uglify report, // --env.report sourceMap, // --env.sourceMap - hmr, // --env.hmr + hmr, // --env.hmr, + externals } = env; const appFullPath = resolve(projectRoot, appPath); @@ -52,6 +53,7 @@ module.exports = env => { const config = { mode: uglify ? "production" : "development", context: appFullPath, + externals, watchOptions: { ignored: [ appResourcesFullPath, diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index e3673cde..141cbc09 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -41,6 +41,7 @@ module.exports = env => { report, // --env.report sourceMap, // --env.sourceMap hmr, // --env.hmr + externals } = env; const appFullPath = resolve(projectRoot, appPath); @@ -52,6 +53,7 @@ module.exports = env => { const config = { mode: uglify ? "production" : "development", context: appFullPath, + externals, watchOptions: { ignored: [ appResourcesFullPath, From e3147472701ca7c87d013dd34c0d1a10577cd124 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Thu, 13 Sep 2018 14:30:22 +0300 Subject: [PATCH 3/4] fix: support deep external requires --- templates/webpack.angular.js | 4 +++- templates/webpack.javascript.js | 4 +++- templates/webpack.typescript.js | 6 ++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index a3410b7f..326c28d0 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -43,8 +43,10 @@ module.exports = env => { report, // --env.report sourceMap, // --env.sourceMap hmr, // --env.hmr, - externals } = env; + const externals = env.externals.map((e) => { // --env.externals + return new RegExp(e + ".*"); + }); const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index 8fe14e09..9253cee1 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -41,8 +41,10 @@ module.exports = env => { report, // --env.report sourceMap, // --env.sourceMap hmr, // --env.hmr, - externals } = env; + const externals = env.externals.map((e) => { // --env.externals + return new RegExp(e + ".*"); + }); const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index 141cbc09..a9b2c945 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -40,9 +40,11 @@ module.exports = env => { uglify, // --env.uglify report, // --env.report sourceMap, // --env.sourceMap - hmr, // --env.hmr - externals + hmr, // --env.hmr, } = env; + const externals = env.externals.map((e) => { // --env.externals + return new RegExp(e + ".*"); + }); const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); From 5ebf1e50a06c4d93ef8e8a02bcbf3d55fc7c2d5f Mon Sep 17 00:00:00 2001 From: fatme Date: Thu, 13 Sep 2018 15:56:44 +0300 Subject: [PATCH 4/4] Fix "Cannot read .map of undefined" error --- lib/compiler.js | 1 + templates/webpack.angular.js | 2 +- templates/webpack.javascript.js | 2 +- templates/webpack.typescript.js | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/compiler.js b/lib/compiler.js index c8dc010d..8f2bea7f 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -43,6 +43,7 @@ exports.runWebpackCompiler = function runWebpackCompiler(config, $projectData, $ env["sourceMap"] = true; } + // Currently externals param is passed only from before-preview-sync hook. This hook is triggered only when `tns preview --bundle` command is executed if (hookArgs && hookArgs.externals) { env.externals = hookArgs.externals; } diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index 326c28d0..ecc2d48b 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -44,7 +44,7 @@ module.exports = env => { sourceMap, // --env.sourceMap hmr, // --env.hmr, } = env; - const externals = env.externals.map((e) => { // --env.externals + const externals = (env.externals || []).map((e) => { // --env.externals return new RegExp(e + ".*"); }); diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index 9253cee1..5b91a631 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -42,7 +42,7 @@ module.exports = env => { sourceMap, // --env.sourceMap hmr, // --env.hmr, } = env; - const externals = env.externals.map((e) => { // --env.externals + const externals = (env.externals || []).map((e) => { // --env.externals return new RegExp(e + ".*"); }); diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index a9b2c945..a8ef8aa4 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -42,7 +42,7 @@ module.exports = env => { sourceMap, // --env.sourceMap hmr, // --env.hmr, } = env; - const externals = env.externals.map((e) => { // --env.externals + const externals = (env.externals || []).map((e) => { // --env.externals return new RegExp(e + ".*"); });