From 8a45768c0d87ce8d6b45ca6f0303940289d488a7 Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 8 May 2019 11:54:30 +0300 Subject: [PATCH 01/13] fix: don't provide fake paths to the {N} CLI - relative to the `app` folder --- plugins/WatchStateLoggerPlugin.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/plugins/WatchStateLoggerPlugin.ts b/plugins/WatchStateLoggerPlugin.ts index 55cbb8ba..84b90c68 100644 --- a/plugins/WatchStateLoggerPlugin.ts +++ b/plugins/WatchStateLoggerPlugin.ts @@ -36,14 +36,9 @@ export class WatchStateLoggerPlugin { .keys(compilation.assets) .filter(assetKey => compilation.assets[assetKey].emitted); - // provide fake paths to the {N} CLI - relative to the 'app' folder - // in order to trigger the livesync process - const emittedFilesFakePaths = emittedFiles - .map(file => join(compiler.context, file)); - process.send && process.send(messages.compilationComplete, error => null); // Send emitted files so they can be LiveSynced if need be - process.send && process.send({ emittedFiles: emittedFilesFakePaths, webpackRuntimeFiles: runtimeOnlyFiles }, error => null); + process.send && process.send({ emittedFiles, webpackRuntimeFiles: runtimeOnlyFiles }, error => null); }); } } From 59ff41d5e117df61ca6a0cc062b088bbfe46637b Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 8 May 2019 11:55:41 +0300 Subject: [PATCH 02/13] feat: remove not needed hooks --- lib/after-watch.js | 8 -------- lib/before-prepareJS.js | 17 ----------------- lib/before-preview-sync.js | 22 ---------------------- lib/before-shouldPrepare.js | 25 ------------------------- lib/before-watch.js | 35 ----------------------------------- package.json | 27 +-------------------------- 6 files changed, 1 insertion(+), 133 deletions(-) delete mode 100644 lib/after-watch.js delete mode 100644 lib/before-prepareJS.js delete mode 100644 lib/before-preview-sync.js delete mode 100644 lib/before-shouldPrepare.js delete mode 100644 lib/before-watch.js diff --git a/lib/after-watch.js b/lib/after-watch.js deleted file mode 100644 index 85e8cb20..00000000 --- a/lib/after-watch.js +++ /dev/null @@ -1,8 +0,0 @@ -const { stopWebpackCompiler } = require('./compiler'); -const { removeListener } = require("./utils"); - -module.exports = function($logger, $liveSyncService) { - stopWebpackCompiler($logger); - removeListener($liveSyncService, "liveSyncStopped"); - removeListener(process, "exit"); -} diff --git a/lib/before-prepareJS.js b/lib/before-prepareJS.js deleted file mode 100644 index debd93dd..00000000 --- a/lib/before-prepareJS.js +++ /dev/null @@ -1,17 +0,0 @@ -const { runWebpackCompiler } = require("./compiler"); - -module.exports = function ($logger, $liveSyncService, hookArgs) { - const platform = hookArgs.config.platform; - const appFilesUpdaterOptions = hookArgs.config.appFilesUpdaterOptions; - const env = hookArgs.config.env || {}; - env.hmr = appFilesUpdaterOptions.useHotModuleReload; - const config = { - env, - platform, - bundle: appFilesUpdaterOptions.bundle, - release: appFilesUpdaterOptions.release, - }; - - const result = config.bundle && runWebpackCompiler.bind(runWebpackCompiler, config, hookArgs.config.projectData, $logger, $liveSyncService, hookArgs); - return result; -} diff --git a/lib/before-preview-sync.js b/lib/before-preview-sync.js deleted file mode 100644 index f15cefcd..00000000 --- a/lib/before-preview-sync.js +++ /dev/null @@ -1,22 +0,0 @@ -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 || {}; - env.hmr = config.appFilesUpdaterOptions.useHotModuleReload; - 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-shouldPrepare.js b/lib/before-shouldPrepare.js deleted file mode 100644 index f61fa2df..00000000 --- a/lib/before-shouldPrepare.js +++ /dev/null @@ -1,25 +0,0 @@ -const { join } = require("path"); -const { readFileSync, existsSync, writeFileSync } = require("fs"); -const envOptionsCacheFileLocation = join(__dirname, "env.cache.json"); - -module.exports = function (hookArgs) { - const platformInfo = hookArgs.shouldPrepareInfo && hookArgs.shouldPrepareInfo.platformInfo; - if (platformInfo && platformInfo.appFilesUpdaterOptions && platformInfo.appFilesUpdaterOptions.bundle) { - - return (args, originalMethod) => { - return originalMethod(...args).then(originalShouldPrepare => { - const currentEnvString = JSON.stringify(platformInfo.env || {}); - if (existsSync(envOptionsCacheFileLocation)) { - const oldEnvOptionsString = readFileSync(envOptionsCacheFileLocation).toString(); - if (oldEnvOptionsString === currentEnvString) { - return originalShouldPrepare; - } - } - - writeFileSync(envOptionsCacheFileLocation, currentEnvString); - - return true; - }); - }; - } -} diff --git a/lib/before-watch.js b/lib/before-watch.js deleted file mode 100644 index 84ba260d..00000000 --- a/lib/before-watch.js +++ /dev/null @@ -1,35 +0,0 @@ -const { getWebpackProcesses, runWebpackCompiler, stopWebpackCompiler } = require("./compiler"); -const { addListener } = require("./utils"); - -module.exports = function ($logger, $liveSyncService, $devicesService, hookArgs) { - if (hookArgs.config) { - const appFilesUpdaterOptions = hookArgs.config.appFilesUpdaterOptions; - if (appFilesUpdaterOptions.bundle) { - addListener($liveSyncService, "liveSyncStopped", () => { - const webpackProcesses = getWebpackProcesses(); - Object.keys(webpackProcesses).forEach(platform => { - const devices = $devicesService.getDevicesForPlatform(platform); - if (!devices || !devices.length) { - stopWebpackCompiler($logger, platform); - } - }); - }); - addListener(process, "exit", () => stopWebpackCompiler($logger)); - - const platforms = hookArgs.config.platforms; - return Promise.all(platforms.map(platform => { - const env = hookArgs.config.env || {}; - env.hmr = appFilesUpdaterOptions.useHotModuleReload; - const config = { - env, - platform, - bundle: appFilesUpdaterOptions.bundle, - release: appFilesUpdaterOptions.release, - watch: true - }; - - return runWebpackCompiler(config, hookArgs.projectData, $logger, $liveSyncService, hookArgs); - })); - } - } -} diff --git a/package.json b/package.json index 62882c62..933554c2 100644 --- a/package.json +++ b/package.json @@ -10,45 +10,20 @@ ], "nativescript": { "hooks": [ - { - "type": "before-prepareJSApp", - "script": "lib/before-prepareJS.js", - "inject": true - }, { "type": "before-cleanApp", "script": "lib/before-cleanApp.js", "inject": true }, - { - "type": "before-watch", - "script": "lib/before-watch.js", - "inject": true - }, - { - "type": "after-watch", - "script": "lib/after-watch.js", - "inject": true - }, { "type": "before-watchPatterns", "script": "lib/before-watchPatterns.js", "inject": true }, - { - "type": "before-shouldPrepare", - "script": "lib/before-shouldPrepare.js", - "inject": true - }, { "type": "after-prepare", "script": "lib/after-prepare.js", "inject": true - }, - { - "type": "before-preview-sync", - "script": "lib/before-preview-sync", - "inject": true } ] }, @@ -60,7 +35,7 @@ "scripts": { "postinstall": "node postinstall.js", "postpack": "rm -rf node_modules", - "prepare": "tsc && npm run jasmine", + "prepare": "tsc", "test": "npm run prepare && npm run jasmine", "jasmine": "jasmine --config=jasmine-config/jasmine.json", "version": "rm package-lock.json && conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md" From 81c723722bb07d5727e97b3e3d922f8d74d3c1a5 Mon Sep 17 00:00:00 2001 From: fatme Date: Mon, 20 May 2019 12:56:07 +0300 Subject: [PATCH 03/13] feat: remove webpack compiler logic --- lib/after-prepare.js | 10 +- lib/before-cleanApp.js | 16 --- lib/before-watchPatterns.js | 19 ---- lib/compiler.js | 182 -------------------------------- lib/utils.js | 96 +---------------- package.json | 12 +-- projectHelpers.js | 15 --- templates/webpack.angular.js | 8 +- templates/webpack.javascript.js | 8 +- templates/webpack.typescript.js | 8 +- templates/webpack.vue.js | 8 +- 11 files changed, 35 insertions(+), 347 deletions(-) delete mode 100644 lib/before-cleanApp.js delete mode 100644 lib/before-watchPatterns.js delete mode 100644 lib/compiler.js diff --git a/lib/after-prepare.js b/lib/after-prepare.js index 2f647f1c..f876e6e6 100644 --- a/lib/after-prepare.js +++ b/lib/after-prepare.js @@ -2,15 +2,13 @@ const { installSnapshotArtefacts } = require("../snapshot/android/project-snapsh const { shouldSnapshot } = require("./utils"); module.exports = function (hookArgs) { - const env = hookArgs.env || {}; - env.hmr = hookArgs.appFilesUpdaterOptions.useHotModuleReload; + const env = hookArgs.prepareData.env || {}; const shouldSnapshotOptions = { - platform: hookArgs.platform, - bundle: hookArgs.appFilesUpdaterOptions.bundle, - release: hookArgs.appFilesUpdaterOptions.release + platform: hookArgs.prepareData.platform, + release: hookArgs.prepareData.release }; if (env.snapshot && shouldSnapshot(shouldSnapshotOptions)) { - installSnapshotArtefacts(hookArgs.projectData.projectDir); + installSnapshotArtefacts(hookArgs.prepareData.projectDir); } } diff --git a/lib/before-cleanApp.js b/lib/before-cleanApp.js deleted file mode 100644 index 70a06b0a..00000000 --- a/lib/before-cleanApp.js +++ /dev/null @@ -1,16 +0,0 @@ -const { cleanSnapshotArtefacts } = require("../snapshot/android/project-snapshot-generator"); -const { isAndroid } = require("../projectHelpers"); -const { getWebpackProcesses } = require("./compiler"); - -module.exports = function (hookArgs) { - return (args, originalMethod) => { - const platform = hookArgs.platformInfo.platform; - const webpackProcesses = getWebpackProcesses(); - const promise = webpackProcesses[platform] ? Promise.resolve() : originalMethod(...args); - return promise.then(() => { - if (isAndroid(platform)) { - cleanSnapshotArtefacts(hookArgs.platformInfo.projectData.projectDir); - } - }); - } -} diff --git a/lib/before-watchPatterns.js b/lib/before-watchPatterns.js deleted file mode 100644 index fddfc999..00000000 --- a/lib/before-watchPatterns.js +++ /dev/null @@ -1,19 +0,0 @@ -const { basename } = require("path"); -const { getAppPathFromProjectData } = require("../projectHelpers"); - -module.exports = function (hookArgs) { - const { liveSyncData } = hookArgs; - if (!liveSyncData || !liveSyncData.bundle) { - return; - } - - return (args, originalMethod) => { - return originalMethod(...args).then(originalPatterns => { - - const appPath = getAppPathFromProjectData(hookArgs.projectData); - const ignorePattern = `!${appPath}`; - - return [...originalPatterns, ignorePattern]; - }); - }; -} diff --git a/lib/compiler.js b/lib/compiler.js deleted file mode 100644 index 6398436c..00000000 --- a/lib/compiler.js +++ /dev/null @@ -1,182 +0,0 @@ -const utils = require("./utils"); -const { spawn } = require("child_process"); -const { resolve: pathResolve } = require("path"); -const { existsSync } = require("fs"); -const readline = require("readline"); - -const { messages } = require("../plugins/WatchStateLoggerPlugin"); -const { buildEnvData, debuggingEnabled, getUpdatedEmittedFiles } = require("./utils"); - -let hasBeenInvoked = false; - -let webpackProcesses = {}; -let hasLoggedSnapshotWarningMessage = false; - -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 (webpackProcesses[config.platform]) { - return resolveBase(); - } - - let isResolved = false; - function resolve() { - if (isResolved) return; - isResolved = true; - resolveBase(); - } - function reject(error) { - if (isResolved) return; - isResolved = true; - rejectBase(error); - } - - console.log(`Running webpack for ${config.platform}...`); - - const projectDir = $projectData.projectDir; - const { platform, env } = config; - if (debuggingEnabled($liveSyncService, projectDir)) { - 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; - } - - const envData = buildEnvData($projectData, platform, env); - const envParams = buildEnvCommandLineParams(config, envData, $logger); - - const args = [ - "--preserve-symlinks", - pathResolve(projectDir, "node_modules", "webpack", "bin", "webpack.js"), - `--config=${pathResolve(projectDir, "webpack.config.js")}`, - ...(config.watch ? ["--watch"] : []), - ...envParams, - ].filter(a => !!a); - - const childProcess = spawn("node", args, { - // Watch opens IPC so we don't mess with the stdin/out/err. - // These will notify us for the webpack compilation states. - // Enables `childProcess.on("message", msg => ...)` kind of communication. - stdio: config.watch ? ["inherit", "inherit", "inherit", "ipc"] : "inherit", - cwd: projectDir - }); - - let isFirstWebpackWatchCompilation = true; - function resolveOnWebpackCompilationComplete(message) { - if (message === messages.compilationComplete) { - console.log("Webpack build done!"); - resolve(); - } - - if (message.emittedFiles) { - if (isFirstWebpackWatchCompilation) { - isFirstWebpackWatchCompilation = false; - return; - } - - const result = getUpdatedEmittedFiles(message.emittedFiles, message.webpackRuntimeFiles); - - if (hookArgs.hmrData) { - hookArgs.hmrData[platform] = { - hash: result.hash || "", - fallbackFiles: result.fallbackFiles - }; - } - - if (hookArgs.filesToSyncMap && hookArgs.startSyncFilesTimeout) { - hookArgs.filesToSyncMap[platform] = result.emittedFiles; - hookArgs.startSyncFilesTimeout(platform); - } else if (hookArgs.filesToSync && hookArgs.startSyncFilesTimeout) { - hookArgs.filesToSync.push(...result.emittedFiles); - hookArgs.startSyncFilesTimeout(platform); - } - } - } - - if (config.watch) { - childProcess.on("message", resolveOnWebpackCompilationComplete); - if (webpackProcesses[platform]) { - throw new Error("Webpack process already spawned."); - } - webpackProcesses[platform] = childProcess; - } - - childProcess.on("close", code => { - if (webpackProcesses[platform] === childProcess) { - delete webpackProcesses[platform]; - } - if (code === 0) { - resolve(); - } else { - const error = new Error(`Executing webpack failed with exit code ${code}.`); - error.code = code; - reject(error); - } - }); - }); - } -} - -exports.stopWebpackCompiler = function stopWebpackCompiler($logger, platform) { - if (platform) { - stopWebpackForPlatform($logger, platform); - } else { - Object.keys(webpackProcesses).forEach(platform => stopWebpackForPlatform($logger, platform)); - } -} - -function buildEnvCommandLineParams(config, envData, $logger) { - const envFlagNames = Object.keys(envData); - const snapshotEnvIndex = envFlagNames.indexOf("snapshot"); - if (snapshotEnvIndex > -1 && !utils.shouldSnapshot(config)) { - logSnapshotWarningMessage($logger); - envFlagNames.splice(snapshotEnvIndex, 1); - } - - const args = []; - envFlagNames.map(item => { - let envValue = envData[item]; - if (typeof envValue === "undefined") { - return; - } - if (typeof envValue === "boolean") { - if (envValue) { - args.push(`--env.${item}`); - } - } else { - if (!Array.isArray(envValue)) { - envValue = [envValue]; - } - - envValue.map(value => args.push(`--env.${item}=${value}`)) - } - }); - - return args; -} - -function logSnapshotWarningMessage($logger) { - if (!hasLoggedSnapshotWarningMessage) { - $logger.warn("Stripping the snapshot flag. " + - "Bear in mind that snapshot is only available in release builds and " + - "is NOT available on Windows systems."); - - hasLoggedSnapshotWarningMessage = true; - } -} - -function stopWebpackForPlatform($logger, platform) { - $logger.trace(`Stopping webpack watch for platform ${platform}.`); - const webpackProcess = webpackProcesses[platform]; - if (webpackProcess) { - webpackProcess.kill("SIGINT"); - delete webpackProcesses[platform]; - } -} - diff --git a/lib/utils.js b/lib/utils.js index b5341c52..a527b24a 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,97 +1,11 @@ const os = require("os"); - -const { - getAppPathFromProjectData, - getAppResourcesPathFromProjectData, - isAndroid, -} = require("../projectHelpers"); - -const eventHandlers = {}; - -function debuggingEnabled(liveSyncService, projectDir) { - const deviceDescriptors = liveSyncService.getLiveSyncDeviceDescriptors(projectDir); - return deviceDescriptors.some(device => device.debugggingEnabled); -} - -function buildEnvData($projectData, platform, env) { - const envData = Object.assign({}, - env, - { [platform.toLowerCase()]: true } - ); - - const appPath = getAppPathFromProjectData($projectData); - const appResourcesPath = getAppResourcesPathFromProjectData($projectData); - Object.assign(envData, - appPath && { appPath }, - appResourcesPath && { appResourcesPath } - ); - - return envData; -} - -/** - * Checks if there's a file in the following pattern 5e0326f3bb50f9f26cf0.hot-update.json - * if yes this is a HMR update and remove all bundle files as we don't need them to be synced, - * but only the update chunks - */ -function getUpdatedEmittedFiles(emittedFiles, webpackRuntimeFiles) { - let fallbackFiles = []; - let hotHash; - if (emittedFiles.some(x => x.endsWith('.hot-update.json'))) { - let result = emittedFiles.slice(); - const hotUpdateScripts = emittedFiles.filter(x => x.endsWith('.hot-update.js')); - hotUpdateScripts.forEach(hotUpdateScript => { - const { name, hash } = parseHotUpdateChunkName(hotUpdateScript); - hotHash = hash; - // remove bundle/vendor.js files if there's a bundle.XXX.hot-update.js or vendor.XXX.hot-update.js - result = result.filter(file => file !== `${name}.js`); - if (webpackRuntimeFiles && webpackRuntimeFiles.length) { - // remove files containing only the Webpack runtime (e.g. runtime.js) - result = result.filter(file => webpackRuntimeFiles.indexOf(file) === -1); - } - }); - //if applying of hot update fails, we must fallback to the full files - fallbackFiles = emittedFiles.filter(file => result.indexOf(file) === -1); - return { emittedFiles: result, fallbackFiles, hash: hotHash }; - } - else { - return { emittedFiles, fallbackFiles }; - } -} - -/** - * Parse the filename of the hot update chunk. - * @param name bundle.deccb264c01d6d42416c.hot-update.js - * @returns { name: string, hash: string } { name: 'bundle', hash: 'deccb264c01d6d42416c' } - */ -function parseHotUpdateChunkName(name) { - const matcher = /^(.+)\.(.+)\.hot-update/gm; - const matches = matcher.exec(name); - return { - name: matches[1] || "", - hash: matches[2] || "", - }; -} +const { isAndroid } = require("../projectHelpers"); function shouldSnapshot(config) { const platformSupportsSnapshot = isAndroid(config.platform); const osSupportsSnapshot = os.type() !== "Windows_NT"; - return config.bundle && config.release && platformSupportsSnapshot && osSupportsSnapshot; -} - -function addListener(eventEmitter, name, handler) { - if (!eventHandlers[name]) { - eventEmitter.on(name, handler); - eventHandlers[name] = handler; - } -} - -function removeListener(eventEmitter, name) { - if (eventHandlers[name]) { - eventEmitter.removeListener(name, eventHandlers[name]); - delete eventHandlers[name]; - } + return config.release && platformSupportsSnapshot && osSupportsSnapshot; } function convertToUnixPath(relativePath) { @@ -99,12 +13,6 @@ function convertToUnixPath(relativePath) { } module.exports = { - buildEnvData, - debuggingEnabled, shouldSnapshot, - getUpdatedEmittedFiles, - parseHotUpdateChunkName, - addListener, - removeListener, convertToUnixPath }; diff --git a/package.json b/package.json index 933554c2..06b45a58 100644 --- a/package.json +++ b/package.json @@ -10,16 +10,6 @@ ], "nativescript": { "hooks": [ - { - "type": "before-cleanApp", - "script": "lib/before-cleanApp.js", - "inject": true - }, - { - "type": "before-watchPatterns", - "script": "lib/before-watchPatterns.js", - "inject": true - }, { "type": "after-prepare", "script": "lib/after-prepare.js", @@ -35,7 +25,7 @@ "scripts": { "postinstall": "node postinstall.js", "postpack": "rm -rf node_modules", - "prepare": "tsc", + "prepare": "tsc && npm run jasmine", "test": "npm run prepare && npm run jasmine", "jasmine": "jasmine --config=jasmine-config/jasmine.json", "version": "rm package-lock.json && conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md" diff --git a/projectHelpers.js b/projectHelpers.js index 64862bf3..792dd8fa 100644 --- a/projectHelpers.js +++ b/projectHelpers.js @@ -3,11 +3,6 @@ const fs = require("fs"); const hook = require("nativescript-hook")(__dirname); -const PROJECT_DATA_GETTERS = { - appPath: "getAppDirectoryRelativePath", - appResourcesPath: "getAppResourcesRelativeDirectoryPath", -}; - const isTypeScript = ({ projectDir, packageJson } = {}) => { packageJson = packageJson || getPackageJson(projectDir); @@ -78,14 +73,6 @@ const getPackageJsonPath = projectDir => resolve(projectDir, "package.json"); const isAndroid = platform => /android/i.test(platform); const isIos = platform => /ios/i.test(platform); -function getAppPathFromProjectData(data) { - return safeGet(data, PROJECT_DATA_GETTERS.appPath); -} - -function getAppResourcesPathFromProjectData(data) { - return safeGet(data, PROJECT_DATA_GETTERS.appResourcesPath); -} - function safeGet(object, property, ...args) { if (!object) { return; @@ -112,8 +99,6 @@ function convertSlashesInPath(modulePath) { const isWindows = process.platform.startsWith("win32"); module.exports = { - getAppPathFromProjectData, - getAppResourcesPathFromProjectData, getPackageJson, getProjectDir, isAndroid, diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index b7d950c0..f9a1fbd5 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -101,6 +101,12 @@ module.exports = env => { let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); + const itemsToClean = [`${dist}/**/*`]; + if (platform === "android") { + itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "src", "main", "assets", "snapshots")}`); + itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); + } + const config = { mode: uglify ? "production" : "development", context: appFullPath, @@ -257,7 +263,7 @@ module.exports = env => { "process": undefined, }), // Remove all files from the out dir. - new CleanWebpackPlugin([`${dist}/**/*`]), + new CleanWebpackPlugin(itemsToClean), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ { from: { glob: "fonts/**" } }, diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index 105992d5..78882160 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -61,6 +61,12 @@ module.exports = env => { let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); + const itemsToClean = [`${dist}/**/*`]; + if (platform === "android") { + itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "src", "main", "assets", "snapshots")}`); + itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); + } + const config = { mode: uglify ? "production" : "development", context: appFullPath, @@ -208,7 +214,7 @@ module.exports = env => { "process": undefined, }), // Remove all files from the out dir. - new CleanWebpackPlugin([`${dist}/**/*`]), + new CleanWebpackPlugin(itemsToClean), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ { from: { glob: "fonts/**" } }, diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index 75efdc61..adcd7e0d 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -65,6 +65,12 @@ module.exports = env => { let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); + const itemsToClean = [`${dist}/**/*`]; + if (platform === "android") { + itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "src", "main", "assets", "snapshots")}`); + itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); + } + const config = { mode: uglify ? "production" : "development", context: appFullPath, @@ -232,7 +238,7 @@ module.exports = env => { "process": undefined, }), // Remove all files from the out dir. - new CleanWebpackPlugin([`${dist}/**/*`]), + new CleanWebpackPlugin(itemsToClean), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ { from: { glob: "fonts/**" } }, diff --git a/templates/webpack.vue.js b/templates/webpack.vue.js index 5f8cbec4..8155649b 100644 --- a/templates/webpack.vue.js +++ b/templates/webpack.vue.js @@ -69,6 +69,12 @@ module.exports = env => { let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); + const itemsToClean = [`${dist}/**/*`]; + if (platform === "android") { + itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "src", "main", "assets", "snapshots")}`); + itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); + } + const config = { mode: mode, context: appFullPath, @@ -234,7 +240,7 @@ module.exports = env => { "TNS_ENV": JSON.stringify(mode) }), // Remove all files from the out dir. - new CleanWebpackPlugin([`${dist}/**/*`]), + new CleanWebpackPlugin(itemsToClean), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ { from: { glob: "fonts/**" } }, From f9e7e16383141ccad49c7fccc35b81535b8333c7 Mon Sep 17 00:00:00 2001 From: fatme Date: Fri, 31 May 2019 09:02:21 +0300 Subject: [PATCH 04/13] fix: don't copy app_resources to the platforms folder --- demo/AngularApp/webpack.config.js | 2 +- templates/webpack.angular.js | 13 ------------- templates/webpack.javascript.js | 12 ------------ templates/webpack.typescript.js | 12 ------------ templates/webpack.vue.js | 12 ------------ 5 files changed, 1 insertion(+), 50 deletions(-) diff --git a/demo/AngularApp/webpack.config.js b/demo/AngularApp/webpack.config.js index bd41e4f5..9cb8260a 100644 --- a/demo/AngularApp/webpack.config.js +++ b/demo/AngularApp/webpack.config.js @@ -286,7 +286,7 @@ module.exports = env => { ])); } - + if (report) { // Generate report files for bundles content config.plugins.push(new BundleAnalyzerPlugin({ diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index f9a1fbd5..dea87609 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -280,19 +280,6 @@ module.exports = env => { ], }; - // Copy the native app resources to the out dir - // only if doing a full build (tns run/build) and not previewing (tns preview) - if (!externals || externals.length === 0) { - config.plugins.push(new CopyWebpackPlugin([ - { - from: `${appResourcesFullPath}/${appResourcesPlatformDir}`, - to: `${dist}/App_Resources/${appResourcesPlatformDir}`, - context: projectRoot - }, - ])); - } - - if (report) { // Generate report files for bundles content config.plugins.push(new BundleAnalyzerPlugin({ diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index 78882160..749a26cc 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -235,18 +235,6 @@ module.exports = env => { ], }; - // Copy the native app resources to the out dir - // only if doing a full build (tns run/build) and not previewing (tns preview) - if (!externals || externals.length === 0) { - config.plugins.push(new CopyWebpackPlugin([ - { - from: `${appResourcesFullPath}/${appResourcesPlatformDir}`, - to: `${dist}/App_Resources/${appResourcesPlatformDir}`, - context: projectRoot - }, - ])); - } - if (report) { // Generate report files for bundles content config.plugins.push(new BundleAnalyzerPlugin({ diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index adcd7e0d..3f30a7fb 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -266,18 +266,6 @@ module.exports = env => { ], }; - // Copy the native app resources to the out dir - // only if doing a full build (tns run/build) and not previewing (tns preview) - if (!externals || externals.length === 0) { - config.plugins.push(new CopyWebpackPlugin([ - { - from: `${appResourcesFullPath}/${appResourcesPlatformDir}`, - to: `${dist}/App_Resources/${appResourcesPlatformDir}`, - context: projectRoot - }, - ])); - } - if (report) { // Generate report files for bundles content config.plugins.push(new BundleAnalyzerPlugin({ diff --git a/templates/webpack.vue.js b/templates/webpack.vue.js index 8155649b..68b2d04a 100644 --- a/templates/webpack.vue.js +++ b/templates/webpack.vue.js @@ -275,18 +275,6 @@ module.exports = env => { ); } - // Copy the native app resources to the out dir - // only if doing a full build (tns run/build) and not previewing (tns preview) - if (!externals || externals.length === 0) { - config.plugins.push(new CopyWebpackPlugin([ - { - from: `${appResourcesFullPath}/${appResourcesPlatformDir}`, - to: `${dist}/App_Resources/${appResourcesPlatformDir}`, - context: projectRoot - }, - ])); - } - if (report) { // Generate report files for bundles content config.plugins.push(new BundleAnalyzerPlugin({ From 467ebaec2749a1a20b3faf73a736f314a254cd15 Mon Sep 17 00:00:00 2001 From: fatme Date: Fri, 31 May 2019 10:57:02 +0300 Subject: [PATCH 05/13] fix: respect --env.verbose --- templates/webpack.angular.js | 3 ++- templates/webpack.javascript.js | 5 +++-- templates/webpack.typescript.js | 5 +++-- templates/webpack.vue.js | 3 ++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index dea87609..2417d0f5 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -50,6 +50,7 @@ module.exports = env => { hiddenSourceMap, // --env.hiddenSourceMap hmr, // --env.hmr, unitTesting, // --env.unitTesting + verbose, // --env.verbose } = env; const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; @@ -263,7 +264,7 @@ module.exports = env => { "process": undefined, }), // Remove all files from the out dir. - new CleanWebpackPlugin(itemsToClean), + new CleanWebpackPlugin(itemsToClean, { verbose: !!verbose }), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ { from: { glob: "fonts/**" } }, diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index 749a26cc..d54498be 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -43,7 +43,8 @@ module.exports = env => { sourceMap, // --env.sourceMap hiddenSourceMap, // --env.hiddenSourceMap hmr, // --env.hmr, - unitTesting, // --env.unitTesting + unitTesting, // --env.unitTesting, + verbose, // --env.verbose } = env; const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; @@ -214,7 +215,7 @@ module.exports = env => { "process": undefined, }), // Remove all files from the out dir. - new CleanWebpackPlugin(itemsToClean), + new CleanWebpackPlugin(itemsToClean, { verbose: !!verbose }), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ { from: { glob: "fonts/**" } }, diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index 3f30a7fb..e9259fdd 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -44,7 +44,8 @@ module.exports = env => { sourceMap, // --env.sourceMap hiddenSourceMap, // --env.hiddenSourceMap hmr, // --env.hmr, - unitTesting, // --env.unitTesting + unitTesting, // --env.unitTesting, + verbose, // --env.verbose } = env; const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; const externals = nsWebpack.getConvertedExternals(env.externals); @@ -238,7 +239,7 @@ module.exports = env => { "process": undefined, }), // Remove all files from the out dir. - new CleanWebpackPlugin(itemsToClean), + new CleanWebpackPlugin(itemsToClean, { verbose: !!verbose }), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ { from: { glob: "fonts/**" } }, diff --git a/templates/webpack.vue.js b/templates/webpack.vue.js index 68b2d04a..032d3eaa 100644 --- a/templates/webpack.vue.js +++ b/templates/webpack.vue.js @@ -48,6 +48,7 @@ module.exports = env => { sourceMap, // --env.sourceMap hiddenSourceMap, // --env.hiddenSourceMap unitTesting, // --env.unitTesting + verbose, // --env.verbose } = env; const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; @@ -240,7 +241,7 @@ module.exports = env => { "TNS_ENV": JSON.stringify(mode) }), // Remove all files from the out dir. - new CleanWebpackPlugin(itemsToClean), + new CleanWebpackPlugin(itemsToClean, { verbose: !!verbose }), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ { from: { glob: "fonts/**" } }, From 0bde5f97275fd291d274714335da4b3e30ade618 Mon Sep 17 00:00:00 2001 From: fatme Date: Fri, 31 May 2019 11:25:46 +0300 Subject: [PATCH 06/13] feat: respect production mode based on release option Implements: https://github.com/NativeScript/nativescript-dev-webpack/issues/911 --- templates/webpack.angular.js | 5 +++-- templates/webpack.javascript.js | 3 ++- templates/webpack.typescript.js | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index 2417d0f5..e94ffc0d 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -43,7 +43,8 @@ module.exports = env => { // You can provide the following flags when running 'tns run android|ios' aot, // --env.aot - snapshot, // --env.snapshot + snapshot, // --env.snapshot, + production, // --env.production uglify, // --env.uglify report, // --env.report sourceMap, // --env.sourceMap @@ -109,7 +110,7 @@ module.exports = env => { } const config = { - mode: uglify ? "production" : "development", + mode: production ? "production" : "development", context: appFullPath, externals, watchOptions: { diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index d54498be..e27baf1e 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -38,6 +38,7 @@ module.exports = env => { // You can provide the following flags when running 'tns run android|ios' snapshot, // --env.snapshot + production, // --env.production uglify, // --env.uglify report, // --env.report sourceMap, // --env.sourceMap @@ -69,7 +70,7 @@ module.exports = env => { } const config = { - mode: uglify ? "production" : "development", + mode: production ? "production" : "development", context: appFullPath, externals, watchOptions: { diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index e9259fdd..daf5a94b 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -39,6 +39,7 @@ module.exports = env => { // You can provide the following flags when running 'tns run android|ios' snapshot, // --env.snapshot + production, // --env.production uglify, // --env.uglify report, // --env.report sourceMap, // --env.sourceMap @@ -73,7 +74,7 @@ module.exports = env => { } const config = { - mode: uglify ? "production" : "development", + mode: production ? "production" : "development", context: appFullPath, externals, watchOptions: { From 4f481b930a20fc902827fcde35187318dd205227 Mon Sep 17 00:00:00 2001 From: fatme Date: Fri, 31 May 2019 15:49:37 +0300 Subject: [PATCH 07/13] fix: watch platform specific files from node_modules Rel to: https://github.com/NativeScript/nativescript-cli/issues/4480 --- package.json | 1 + templates/webpack.javascript.js | 4 ++++ templates/webpack.typescript.js | 4 ++++ templates/webpack.vue.js | 4 ++++ 4 files changed, 13 insertions(+) diff --git a/package.json b/package.json index 06b45a58..a4e474b9 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "copy-webpack-plugin": "~4.6.0", "css-loader": "~2.1.1", "fork-ts-checker-webpack-plugin": "1.3.0", + "extra-watch-webpack-plugin": "1.0.3", "global-modules-path": "2.0.0", "minimatch": "3.0.4", "nativescript-hook": "0.2.4", diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index e27baf1e..fd656554 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -5,6 +5,7 @@ const nsWebpack = require("nativescript-dev-webpack"); const nativescriptTarget = require("nativescript-dev-webpack/nativescript-target"); const CleanWebpackPlugin = require("clean-webpack-plugin"); const CopyWebpackPlugin = require("copy-webpack-plugin"); +const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin'); const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); const TerserPlugin = require("terser-webpack-plugin"); @@ -234,6 +235,9 @@ module.exports = env => { }), // Does IPC communication with the {N} CLI to notify events when running in watch mode. new nsWebpack.WatchStateLoggerPlugin(), + new ExtraWatchWebpackPlugin({ + files: [`node_modules/**/*.${platform}.js`] + }) ], }; diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index daf5a94b..fd169d2e 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -6,6 +6,7 @@ const nativescriptTarget = require("nativescript-dev-webpack/nativescript-target const CleanWebpackPlugin = require("clean-webpack-plugin"); const CopyWebpackPlugin = require("copy-webpack-plugin"); const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); +const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin'); const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); const TerserPlugin = require("terser-webpack-plugin"); @@ -264,6 +265,9 @@ module.exports = env => { async: false, useTypescriptIncrementalApi: true, memoryLimit: 4096 + }), + new ExtraWatchWebpackPlugin({ + files: [`node_modules/**/*.${platform}.ts`] }) ], }; diff --git a/templates/webpack.vue.js b/templates/webpack.vue.js index 032d3eaa..945d1f7f 100644 --- a/templates/webpack.vue.js +++ b/templates/webpack.vue.js @@ -3,6 +3,7 @@ const { join, relative, resolve, sep } = require("path"); const webpack = require("webpack"); const CleanWebpackPlugin = require("clean-webpack-plugin"); const CopyWebpackPlugin = require("copy-webpack-plugin"); +const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin'); const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); const TerserPlugin = require("terser-webpack-plugin"); @@ -258,6 +259,9 @@ module.exports = env => { }), // Does IPC communication with the {N} CLI to notify events when running in watch mode. new nsWebpack.WatchStateLoggerPlugin(), + new ExtraWatchWebpackPlugin({ + files: [`node_modules/**/*.${platform}.ts`, `node_modules/**/*.${platform}.js`] + }) ], }; From de2b23aa56beac005df7140b00beefa4eb908d9c Mon Sep 17 00:00:00 2001 From: fatme Date: Thu, 6 Jun 2019 16:56:41 +0300 Subject: [PATCH 08/13] fix: don't emit absolute webpack's runtime files Previously we needed to emit files with full paths as {N} CLI relies on this and expected them in a such format. With the changes for "webpack-only" mode, {N} CLI expects only relative paths. So we need to fix this in order to ensure that runtime.js file will not be transferred on device on change in hmr mode. --- plugins/WatchStateLoggerPlugin.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/plugins/WatchStateLoggerPlugin.ts b/plugins/WatchStateLoggerPlugin.ts index 84b90c68..9f2ebdfd 100644 --- a/plugins/WatchStateLoggerPlugin.ts +++ b/plugins/WatchStateLoggerPlugin.ts @@ -1,5 +1,3 @@ -import { join } from "path"; - export enum messages { compilationComplete = "Webpack compilation complete.", startWatching = "Webpack compilation complete. Watching for file changes.", @@ -31,7 +29,7 @@ export class WatchStateLoggerPlugin { console.log(messages.compilationComplete); } - const runtimeOnlyFiles = getWebpackRuntimeOnlyFiles(compilation, compiler.context); + const runtimeOnlyFiles = getWebpackRuntimeOnlyFiles(compilation); let emittedFiles = Object .keys(compilation.assets) .filter(assetKey => compilation.assets[assetKey].emitted); @@ -43,7 +41,7 @@ export class WatchStateLoggerPlugin { } } -function getWebpackRuntimeOnlyFiles(compilation, basePath) { +function getWebpackRuntimeOnlyFiles(compilation) { let runtimeOnlyFiles = []; try { runtimeOnlyFiles = [].concat(...Array.from(compilation.entrypoints.values()) @@ -52,9 +50,7 @@ function getWebpackRuntimeOnlyFiles(compilation, basePath) { .filter(runtimeChunk => !!runtimeChunk && runtimeChunk.preventIntegration) .map(runtimeChunk => runtimeChunk.files)) // get only the unique files in case of "single" runtime (e.g. runtime.js) - .filter((value, index, self) => self.indexOf(value) === index) - // convert to absolute paths - .map(fileName => join(basePath, fileName)); + .filter((value, index, self) => self.indexOf(value) === index); } catch (e) { // breaking change in the Webpack API console.log("Warning: Unable to find Webpack runtime files."); From a0c42451822d338cb1ae77ac537c07b2cd826385 Mon Sep 17 00:00:00 2001 From: fatme Date: Fri, 7 Jun 2019 08:34:05 +0300 Subject: [PATCH 09/13] fix: don't process runtime.js files We needed a special processing for `runtime.js` files as we excluded them when transferring the files on device. As the CLI is filtering and emit only hot-update files we don't need this logic anymore. --- plugins/WatchStateLoggerPlugin.ts | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/plugins/WatchStateLoggerPlugin.ts b/plugins/WatchStateLoggerPlugin.ts index 9f2ebdfd..6131550f 100644 --- a/plugins/WatchStateLoggerPlugin.ts +++ b/plugins/WatchStateLoggerPlugin.ts @@ -29,32 +29,13 @@ export class WatchStateLoggerPlugin { console.log(messages.compilationComplete); } - const runtimeOnlyFiles = getWebpackRuntimeOnlyFiles(compilation); let emittedFiles = Object .keys(compilation.assets) .filter(assetKey => compilation.assets[assetKey].emitted); process.send && process.send(messages.compilationComplete, error => null); // Send emitted files so they can be LiveSynced if need be - process.send && process.send({ emittedFiles, webpackRuntimeFiles: runtimeOnlyFiles }, error => null); + process.send && process.send({ emittedFiles }, error => null); }); } } - -function getWebpackRuntimeOnlyFiles(compilation) { - let runtimeOnlyFiles = []; - try { - runtimeOnlyFiles = [].concat(...Array.from(compilation.entrypoints.values()) - .map(entrypoint => entrypoint.runtimeChunk) - // filter embedded runtime chunks (e.g. part of bundle.js or inspector-modules.js) - .filter(runtimeChunk => !!runtimeChunk && runtimeChunk.preventIntegration) - .map(runtimeChunk => runtimeChunk.files)) - // get only the unique files in case of "single" runtime (e.g. runtime.js) - .filter((value, index, self) => self.indexOf(value) === index); - } catch (e) { - // breaking change in the Webpack API - console.log("Warning: Unable to find Webpack runtime files."); - } - - return runtimeOnlyFiles; -} From 9738806105a01923b98496db3b66045ef2de2d91 Mon Sep 17 00:00:00 2001 From: fatme Date: Mon, 10 Jun 2019 14:37:30 +0300 Subject: [PATCH 10/13] fix: emit runtime files and entry point files --- plugins/WatchStateLoggerPlugin.ts | 44 ++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/plugins/WatchStateLoggerPlugin.ts b/plugins/WatchStateLoggerPlugin.ts index 6131550f..bbcff833 100644 --- a/plugins/WatchStateLoggerPlugin.ts +++ b/plugins/WatchStateLoggerPlugin.ts @@ -33,9 +33,51 @@ export class WatchStateLoggerPlugin { .keys(compilation.assets) .filter(assetKey => compilation.assets[assetKey].emitted); + const webpackRuntimeFiles = getWebpackRuntimeOnlyFiles(compilation); + const entryPointFiles = getEntryPointFiles(compilation); + process.send && process.send(messages.compilationComplete, error => null); // Send emitted files so they can be LiveSynced if need be - process.send && process.send({ emittedFiles }, error => null); + process.send && process.send({ emittedFiles, webpackRuntimeFiles, entryPointFiles }, error => null); }); } } + +function getWebpackRuntimeOnlyFiles(compilation) { + let runtimeOnlyFiles = []; + try { + runtimeOnlyFiles = [].concat(...Array.from(compilation.entrypoints.values()) + .map(entrypoint => entrypoint.runtimeChunk) + // filter embedded runtime chunks (e.g. part of bundle.js or inspector-modules.js) + .filter(runtimeChunk => !!runtimeChunk && runtimeChunk.preventIntegration) + .map(runtimeChunk => runtimeChunk.files)) + // get only the unique files in case of "single" runtime (e.g. runtime.js) + .filter((value, index, self) => self.indexOf(value) === index); + } catch (e) { + // breaking change in the Webpack API + console.log("Warning: Unable to find Webpack runtime files."); + } + + return runtimeOnlyFiles; +} + +function getEntryPointFiles(compilation) { + const entryPointFiles = []; + try { + Array.from(compilation.entrypoints.values()) + .forEach((entrypoint: any) => { + const entryChunk = entrypoint.chunks.find(chunk => chunk.name === entrypoint.options.name); + if (entryChunk) { + entryChunk.files.forEach(fileName => { + if (fileName.indexOf("hot-update") === -1) { + entryPointFiles.push(fileName); + } + }); + } + }); + } catch (e) { + console.log("Warning: Unable to find Webpack entry point files."); + } + + return entryPointFiles; +} \ No newline at end of file From 0b48eb3e50b78ea4f13e3cd1925a3ecee85b9116 Mon Sep 17 00:00:00 2001 From: fatme Date: Sat, 15 Jun 2019 11:47:53 +0300 Subject: [PATCH 11/13] fix: update webpack config files of demo apps --- demo/AngularApp/webpack.config.js | 32 ++++++++--------- demo/JavaScriptApp/webpack.config.js | 33 ++++++++--------- demo/TypeScriptApp/webpack.config.js | 54 +++++++++++++++------------- 3 files changed, 61 insertions(+), 58 deletions(-) diff --git a/demo/AngularApp/webpack.config.js b/demo/AngularApp/webpack.config.js index 9cb8260a..9019eea7 100644 --- a/demo/AngularApp/webpack.config.js +++ b/demo/AngularApp/webpack.config.js @@ -44,13 +44,15 @@ module.exports = env => { // You can provide the following flags when running 'tns run android|ios' aot, // --env.aot - snapshot, // --env.snapshot + snapshot, // --env.snapshot, + production, // --env.production uglify, // --env.uglify report, // --env.report sourceMap, // --env.sourceMap hiddenSourceMap, // --env.hiddenSourceMap hmr, // --env.hmr, unitTesting, // --env.unitTesting + verbose, // --env.verbose } = env; const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; @@ -60,8 +62,9 @@ module.exports = env => { const tsConfigName = "tsconfig.tns.json"; const entryModule = `${nsWebpack.getEntryModule(appFullPath, platform)}.ts`; const entryPath = `.${sep}${entryModule}`; - const entries = { bundle: entryPath, application: "./application.android" }; - if (platform === "ios") { + const entries = { bundle: entryPath }; + const areCoreModulesExternal = Array.isArray(env.externals) && env.externals.some(e => e.indexOf("tns-core-modules") > -1); + if (platform === "ios" && !areCoreModulesExternal) { entries["tns_modules/tns-core-modules/inspector_modules"] = "inspector_modules"; }; @@ -101,8 +104,14 @@ module.exports = env => { let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); + const itemsToClean = [`${dist}/**/*`]; + if (platform === "android") { + itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "src", "main", "assets", "snapshots")}`); + itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); + } + const config = { - mode: uglify ? "production" : "development", + mode: production ? "production" : "development", context: appFullPath, externals, watchOptions: { @@ -257,7 +266,7 @@ module.exports = env => { "process": undefined, }), // Remove all files from the out dir. - new CleanWebpackPlugin([`${dist}/**/*`]), + new CleanWebpackPlugin(itemsToClean, { verbose: !!verbose }), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ { from: { glob: "fonts/**" } }, @@ -274,19 +283,6 @@ module.exports = env => { ], }; - // Copy the native app resources to the out dir - // only if doing a full build (tns run/build) and not previewing (tns preview) - if (!externals || externals.length === 0) { - config.plugins.push(new CopyWebpackPlugin([ - { - from: `${appResourcesFullPath}/${appResourcesPlatformDir}`, - to: `${dist}/App_Resources/${appResourcesPlatformDir}`, - context: projectRoot - }, - ])); - } - - if (report) { // Generate report files for bundles content config.plugins.push(new BundleAnalyzerPlugin({ diff --git a/demo/JavaScriptApp/webpack.config.js b/demo/JavaScriptApp/webpack.config.js index e6156dca..6d8c7c8c 100644 --- a/demo/JavaScriptApp/webpack.config.js +++ b/demo/JavaScriptApp/webpack.config.js @@ -5,6 +5,7 @@ const nsWebpack = require("nativescript-dev-webpack"); const nativescriptTarget = require("nativescript-dev-webpack/nativescript-target"); const CleanWebpackPlugin = require("clean-webpack-plugin"); const CopyWebpackPlugin = require("copy-webpack-plugin"); +const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin'); const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); const TerserPlugin = require("terser-webpack-plugin"); @@ -39,12 +40,14 @@ module.exports = env => { // You can provide the following flags when running 'tns run android|ios' snapshot, // --env.snapshot + production, // --env.production uglify, // --env.uglify report, // --env.report sourceMap, // --env.sourceMap hiddenSourceMap, // --env.hiddenSourceMap hmr, // --env.hmr, - unitTesting, // --env.unitTesting + unitTesting, // --env.unitTesting, + verbose, // --env.verbose } = env; const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; @@ -55,14 +58,21 @@ module.exports = env => { const entryModule = nsWebpack.getEntryModule(appFullPath, platform); const entryPath = `.${sep}${entryModule}.js`; const entries = { bundle: entryPath, application: "./application.android" }; - if (platform === "ios") { + const areCoreModulesExternal = Array.isArray(env.externals) && env.externals.some(e => e.indexOf("tns-core-modules") > -1); + if (platform === "ios" && !areCoreModulesExternal) { entries["tns_modules/tns-core-modules/inspector_modules"] = "inspector_modules"; }; let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); + const itemsToClean = [`${dist}/**/*`]; + if (platform === "android") { + itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "src", "main", "assets", "snapshots")}`); + itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); + } + const config = { - mode: uglify ? "production" : "development", + mode: production ? "production" : "development", context: appFullPath, externals, watchOptions: { @@ -208,7 +218,7 @@ module.exports = env => { "process": undefined, }), // Remove all files from the out dir. - new CleanWebpackPlugin([`${dist}/**/*`]), + new CleanWebpackPlugin(itemsToClean, { verbose: !!verbose }), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ { from: { glob: "fonts/**" } }, @@ -226,21 +236,12 @@ module.exports = env => { }), // Does IPC communication with the {N} CLI to notify events when running in watch mode. new nsWebpack.WatchStateLoggerPlugin(), + new ExtraWatchWebpackPlugin({ + files: [`node_modules/**/*.${platform}.js`] + }) ], }; - // Copy the native app resources to the out dir - // only if doing a full build (tns run/build) and not previewing (tns preview) - if (!externals || externals.length === 0) { - config.plugins.push(new CopyWebpackPlugin([ - { - from: `${appResourcesFullPath}/${appResourcesPlatformDir}`, - to: `${dist}/App_Resources/${appResourcesPlatformDir}`, - context: projectRoot - }, - ])); - } - if (report) { // Generate report files for bundles content config.plugins.push(new BundleAnalyzerPlugin({ diff --git a/demo/TypeScriptApp/webpack.config.js b/demo/TypeScriptApp/webpack.config.js index 64e87be0..30e2c763 100644 --- a/demo/TypeScriptApp/webpack.config.js +++ b/demo/TypeScriptApp/webpack.config.js @@ -6,6 +6,7 @@ const nativescriptTarget = require("nativescript-dev-webpack/nativescript-target const CleanWebpackPlugin = require("clean-webpack-plugin"); const CopyWebpackPlugin = require("copy-webpack-plugin"); const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); +const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin'); const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); const TerserPlugin = require("terser-webpack-plugin"); @@ -40,12 +41,14 @@ module.exports = env => { // You can provide the following flags when running 'tns run android|ios' snapshot, // --env.snapshot + production, // --env.production uglify, // --env.uglify report, // --env.report sourceMap, // --env.sourceMap hiddenSourceMap, // --env.hiddenSourceMap hmr, // --env.hmr, - unitTesting, // --env.unitTesting + unitTesting, // --env.unitTesting, + verbose, // --env.verbose } = env; const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; const externals = nsWebpack.getConvertedExternals(env.externals); @@ -59,14 +62,21 @@ module.exports = env => { const tsConfigPath = resolve(projectRoot, "tsconfig.tns.json"); - if (platform === "ios") { + const areCoreModulesExternal = Array.isArray(env.externals) && env.externals.some(e => e.indexOf("tns-core-modules") > -1); + if (platform === "ios" && !areCoreModulesExternal) { entries["tns_modules/tns-core-modules/inspector_modules"] = "inspector_modules"; }; let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); + const itemsToClean = [`${dist}/**/*`]; + if (platform === "android") { + itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "src", "main", "assets", "snapshots")}`); + itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); + } + const config = { - mode: uglify ? "production" : "development", + mode: production ? "production" : "development", context: appFullPath, externals, watchOptions: { @@ -212,10 +222,13 @@ module.exports = env => { loader: "ts-loader", options: { configFile: tsConfigPath, - transpileOnly: !!hmr, + // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#faster-builds + // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#hot-module-replacement + transpileOnly: true, allowTsInNodeModules: true, compilerOptions: { - sourceMap: isAnySourceMapEnabled + sourceMap: isAnySourceMapEnabled, + declaration: false } }, } @@ -229,7 +242,7 @@ module.exports = env => { "process": undefined, }), // Remove all files from the out dir. - new CleanWebpackPlugin([`${dist}/**/*`]), + new CleanWebpackPlugin(itemsToClean, { verbose: !!verbose }), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ { from: { glob: "fonts/**" } }, @@ -246,21 +259,20 @@ module.exports = env => { }), // Does IPC communication with the {N} CLI to notify events when running in watch mode. new nsWebpack.WatchStateLoggerPlugin(), + // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#faster-builds + // https://github.com/TypeStrong/ts-loader/blob/ea2fcf925ec158d0a536d1e766adfec6567f5fb4/README.md#hot-module-replacement + new ForkTsCheckerWebpackPlugin({ + tsconfig: tsConfigPath, + async: false, + useTypescriptIncrementalApi: true, + memoryLimit: 4096 + }), + new ExtraWatchWebpackPlugin({ + files: [`node_modules/**/*.${platform}.ts`] + }) ], }; - // Copy the native app resources to the out dir - // only if doing a full build (tns run/build) and not previewing (tns preview) - if (!externals || externals.length === 0) { - config.plugins.push(new CopyWebpackPlugin([ - { - from: `${appResourcesFullPath}/${appResourcesPlatformDir}`, - to: `${dist}/App_Resources/${appResourcesPlatformDir}`, - context: projectRoot - }, - ])); - } - if (report) { // Generate report files for bundles content config.plugins.push(new BundleAnalyzerPlugin({ @@ -285,12 +297,6 @@ module.exports = env => { if (hmr) { config.plugins.push(new webpack.HotModuleReplacementPlugin()); - - // With HMR ts-loader should run in `transpileOnly` mode, - // so assure type-checking with fork-ts-checker-webpack-plugin - config.plugins.push(new ForkTsCheckerWebpackPlugin({ - tsconfig: tsConfigPath - })); } From 00009ea0f49c00756c73ca87d7c445e7090b5e97 Mon Sep 17 00:00:00 2001 From: fatme Date: Sat, 15 Jun 2019 18:10:01 +0300 Subject: [PATCH 12/13] fix: don't use short imports in demo apps --- demo/JavaScriptApp/app/activity.android.js | 2 +- demo/JavaScriptApp/app/app.js | 2 +- demo/JavaScriptApp/app/main-page.android.js | 2 +- demo/JavaScriptApp/app/main-page.ios.js | 2 +- demo/JavaScriptApp/app/main-view-model.js | 2 +- demo/TypeScriptApp/app/activity.android.ts | 2 +- demo/TypeScriptApp/app/app.ts | 2 +- demo/TypeScriptApp/app/main-page.ios.ts | 8 ++++---- demo/TypeScriptApp/app/main-view-model.ts | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/demo/JavaScriptApp/app/activity.android.js b/demo/JavaScriptApp/app/activity.android.js index 14120ab4..443eb271 100644 --- a/demo/JavaScriptApp/app/activity.android.js +++ b/demo/JavaScriptApp/app/activity.android.js @@ -1,4 +1,4 @@ -const frame = require("ui/frame"); +const frame = require("tns-core-modules/ui/frame"); const superProto = androidx.appcompat.app.AppCompatActivity.prototype; androidx.appcompat.app.AppCompatActivity.extend("org.myApp.MainActivity", { diff --git a/demo/JavaScriptApp/app/app.js b/demo/JavaScriptApp/app/app.js index 3294b628..614b1678 100644 --- a/demo/JavaScriptApp/app/app.js +++ b/demo/JavaScriptApp/app/app.js @@ -4,7 +4,7 @@ You can use this file to perform app-level initialization, but the primary purpose of the file is to pass control to the app’s first module. */ -var application = require("application"); +var application = require("tns-core-modules/application"); application.start({ moduleName: "main-page" }); diff --git a/demo/JavaScriptApp/app/main-page.android.js b/demo/JavaScriptApp/app/main-page.android.js index 31b03cd3..70a0ab21 100644 --- a/demo/JavaScriptApp/app/main-page.android.js +++ b/demo/JavaScriptApp/app/main-page.android.js @@ -1,4 +1,4 @@ -var frameModule = require("ui/frame"); +var frameModule = require("tns-core-modules/ui/frame"); var createViewModel = require("./main-view-model").createViewModel; function onNavigatingTo(args) { diff --git a/demo/JavaScriptApp/app/main-page.ios.js b/demo/JavaScriptApp/app/main-page.ios.js index 1330474f..094ffd4a 100644 --- a/demo/JavaScriptApp/app/main-page.ios.js +++ b/demo/JavaScriptApp/app/main-page.ios.js @@ -1,4 +1,4 @@ -var frameModule = require("ui/frame"); +var frameModule = require("tns-core-modules/ui/frame"); var createViewModel = require("./main-view-model").createViewModel; function onNavigatingTo(args) { diff --git a/demo/JavaScriptApp/app/main-view-model.js b/demo/JavaScriptApp/app/main-view-model.js index c0993f5a..20ab082e 100644 --- a/demo/JavaScriptApp/app/main-view-model.js +++ b/demo/JavaScriptApp/app/main-view-model.js @@ -1,4 +1,4 @@ -var Observable = require("data/observable").Observable; +var Observable = require("tns-core-modules/data/observable").Observable; function getMessage(counter) { if (counter <= 0) { diff --git a/demo/TypeScriptApp/app/activity.android.ts b/demo/TypeScriptApp/app/activity.android.ts index 2bbd6398..176e23d1 100644 --- a/demo/TypeScriptApp/app/activity.android.ts +++ b/demo/TypeScriptApp/app/activity.android.ts @@ -1,4 +1,4 @@ -import {setActivityCallbacks, AndroidActivityCallbacks} from "ui/frame"; +import {setActivityCallbacks, AndroidActivityCallbacks} from "tns-core-modules/ui/frame"; @JavaProxy("org.myApp.MainActivity") class Activity extends androidx.appcompat.app.AppCompatActivity { diff --git a/demo/TypeScriptApp/app/app.ts b/demo/TypeScriptApp/app/app.ts index 25278f50..87b66a81 100644 --- a/demo/TypeScriptApp/app/app.ts +++ b/demo/TypeScriptApp/app/app.ts @@ -4,7 +4,7 @@ You can use this file to perform app-level initialization, but the primary purpose of the file is to pass control to the app’s first module. */ -import * as app from 'application'; +import * as app from 'tns-core-modules/application'; app.start({ moduleName: 'main-page' }); diff --git a/demo/TypeScriptApp/app/main-page.ios.ts b/demo/TypeScriptApp/app/main-page.ios.ts index 9cc631bc..02f3fa4c 100644 --- a/demo/TypeScriptApp/app/main-page.ios.ts +++ b/demo/TypeScriptApp/app/main-page.ios.ts @@ -4,11 +4,11 @@ a code-behind file. The code-behind is a great place to place your view logic, and to set up your page’s data binding. */ -import { EventData } from 'data/observable'; -import { Page } from 'ui/page'; +import { EventData } from 'tns-core-modules/data/observable'; +import { Page } from 'tns-core-modules/ui/page'; import { HelloWorldModel } from './main-view-model'; -import { Label } from 'ui/label'; -import * as frameModule from 'ui/frame'; +import { Label } from 'tns-core-modules/ui/label'; +import * as frameModule from 'tns-core-modules/ui/frame'; // Event handler for Page "navigatingTo" event attached in main-page.xml export function onNavigatingTo(args: EventData) { diff --git a/demo/TypeScriptApp/app/main-view-model.ts b/demo/TypeScriptApp/app/main-view-model.ts index c88ea9e5..56936641 100644 --- a/demo/TypeScriptApp/app/main-view-model.ts +++ b/demo/TypeScriptApp/app/main-view-model.ts @@ -1,4 +1,4 @@ -import {Observable} from 'data/observable'; +import {Observable} from 'tns-core-modules/data/observable'; export class HelloWorldModel extends Observable { From 321abc4764eb22b41f11c904a6c5c16b91b4d79e Mon Sep 17 00:00:00 2001 From: fatme Date: Sat, 15 Jun 2019 18:17:52 +0300 Subject: [PATCH 13/13] fix: update dependencies of demo apps so they are compatible with 6.0 release --- demo/AngularApp/package.json | 3 +-- demo/JavaScriptApp/package.json | 3 +-- demo/TypeScriptApp/package.json | 5 ++--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/demo/AngularApp/package.json b/demo/AngularApp/package.json index ad3c59d4..e2241aaa 100644 --- a/demo/AngularApp/package.json +++ b/demo/AngularApp/package.json @@ -42,9 +42,8 @@ "mocha": "~5.2.0", "mochawesome": "~3.1.2", "nativescript-dev-appium": "next", - "nativescript-dev-sass": "next", - "nativescript-dev-typescript": "next", "nativescript-dev-webpack": "next", + "node-sass": "^4.12.0", "typescript": "~3.4.5" }, "scripts": { diff --git a/demo/JavaScriptApp/package.json b/demo/JavaScriptApp/package.json index 4118a33c..58364992 100644 --- a/demo/JavaScriptApp/package.json +++ b/demo/JavaScriptApp/package.json @@ -27,9 +27,8 @@ "mocha": "~5.2.0", "mochawesome": "~3.1.2", "nativescript-dev-appium": "next", - "nativescript-dev-sass": "next", "nativescript-dev-webpack": "next", - "node-sass": "^4.7.1" + "node-sass": "4.12.0" }, "scripts": { "setup": "npm pack ../../ && npm i -D nativescript-dev-webpack*.tgz", diff --git a/demo/TypeScriptApp/package.json b/demo/TypeScriptApp/package.json index 62c8f58c..f98d9675 100644 --- a/demo/TypeScriptApp/package.json +++ b/demo/TypeScriptApp/package.json @@ -27,10 +27,9 @@ "mocha": "~5.2.0", "mochawesome": "~3.1.2", "nativescript-dev-appium": "next", - "nativescript-dev-sass": "next", - "nativescript-dev-typescript": "next", "nativescript-dev-webpack": "next", - "typescript": "~3.2.2" + "typescript": "~3.2.2", + "node-sass": "^4.12.0" }, "scripts": { "setup": "npm pack ../../ && npm i -D nativescript-dev-webpack*.tgz",