From fd52211590a0c1d953f81e61b292579138552e0e Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Tue, 6 Mar 2018 09:09:33 +0200 Subject: [PATCH 01/41] refactor: get app directory from CLI --- index.js | 56 ++++++++++++++++++--------- installer.js | 19 +++++----- lib/after-prepare.js | 10 ++--- lib/before-cleanApp.js | 12 +++--- lib/before-prepareJS.js | 4 +- lib/before-watch.js | 4 +- lib/before-watchPatterns.js | 17 ++++++--- lib/compiler.js | 67 ++++++++++++++++++++++----------- lib/utils.js | 33 ++++++++++++---- nsCliHelpers.js | 25 ++++++++++++ package.json | 1 + projectHelpers.js | 47 +++++++++++++++++++++++ templates/webpack.angular.js | 39 ++++++++++++++----- templates/webpack.javascript.js | 36 +++++++++++++----- templates/webpack.typescript.js | 34 ++++++++++++----- verify/update.js | 9 ++++- 16 files changed, 304 insertions(+), 109 deletions(-) create mode 100644 nsCliHelpers.js diff --git a/index.js b/index.js index 635752e3..c33cfbed 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,14 @@ const path = require("path"); const { existsSync } = require("fs"); -const { getPackageJson, getProjectDir, isAngular, resolveAndroidAppPath } = require("./projectHelpers"); +const { + getPackageJson, + getProjectDir, + isAngular, + isAndroid, + isIos, + resolveAndroidAppPath, +} = require("./projectHelpers"); const PROJECT_DIR = getProjectDir(); const APP_DIR = path.join(PROJECT_DIR, "app"); @@ -12,23 +19,39 @@ if (isAngular({ projectDir: PROJECT_DIR })) { Object.assign(exports, require('./plugins/angular')); } -exports.getEntryModule = function () { - const maybePackageJsonEntry = getPackageJsonEntry(); - if (!maybePackageJsonEntry) { - throw new Error("app/package.json must contain a `main` attribute."); +exports.getAotEntryModule = function (appDirectory = APP_DIR) { + const entry = getPackageJsonEntry(appDirectory); + const aotEntry = `${entry}.aot.ts`; + + const aotEntryPath = path.resolve(appDirectory, aotEntry); + if (!existsSync(aotEntryPath)) { + throw new Error(`For ahead-of-time compilation you need to have an entry module ` + + `at ${aotEntryPath} that bootstraps the app with a static platform instead of dynamic one!`) } - const maybeAotEntry = getAotEntry(maybePackageJsonEntry); - return maybeAotEntry || maybePackageJsonEntry; + return aotEntry; +} + +exports.getEntryModule = function (appDirectory = APP_DIR) { + const entry = getPackageJsonEntry(appDirectory); + + const tsEntryPath = path.resolve(appDirectory, `${entry}.ts`); + const jsEntryPath = path.resolve(appDirectory, `${entry}.js`); + if (!existsSync(tsEntryPath) && !existsSync(jsEntryPath)) { + throw new Error(`The entry module ${entry} specified in ` + + `${appDirectory}/package.json doesn't exist!`) + } + + return entry; }; exports.getAppPath = platform => { - if (/ios/i.test(platform)) { + if (isIos(platform)) { const appName = path.basename(PROJECT_DIR); const sanitizedName = sanitize(appName); return `platforms/ios/${sanitizedName}/app`; - } else if (/android/i.test(platform)) { + } else if (isAndroid(platform)) { return resolveAndroidAppPath(PROJECT_DIR); } else { throw new Error(`Invalid platform: ${platform}`); @@ -40,16 +63,13 @@ const sanitize = name => name .filter(char => /[a-zA-Z0-9]/.test(char)) .join(""); -function getPackageJsonEntry() { - const packageJsonSource = getPackageJson(APP_DIR); +function getPackageJsonEntry(appDirectory) { + const packageJsonSource = getPackageJson(appDirectory); const entry = packageJsonSource.main; - return entry ? entry.replace(/\.js$/i, "") : null; -} - -function getAotEntry(entry) { - const aotEntry = `${entry}.aot.ts`; - const aotEntryPath = path.join(APP_DIR, aotEntry); + if (!entry) { + throw new Error(`${appDirectory}/package.json must contain a 'main' attribute!`); + } - return existsSync(aotEntryPath) ? aotEntry : null; + return entry.replace(/\.js$/i, ""); } diff --git a/installer.js b/installer.js index 94b2b7ed..2ce9d7de 100644 --- a/installer.js +++ b/installer.js @@ -1,28 +1,27 @@ -const path = require("path"); -const fs = require("fs"); - const helpers = require("./projectHelpers"); const projectFilesManager = require("./projectFilesManager"); const dependencyManager = require("./dependencyManager"); -const PROJECT_DIR = helpers.getProjectDir(); -const APP_DIR = path.resolve(PROJECT_DIR, "app"); - function install() { - const packageJson = helpers.getPackageJson(PROJECT_DIR); + const projectDir = helpers.getProjectDir(); + const appPath = helpers.getAppPath(); + const packageJson = helpers.getPackageJson(projectDir); - projectFilesManager.addProjectFiles(PROJECT_DIR, APP_DIR); + projectFilesManager.addProjectFiles(projectDir, appPath); const postinstallOptions = dependencyManager.addProjectDeps(packageJson); packageJson.devDependencies = postinstallOptions.deps; - helpers.writePackageJson(packageJson, PROJECT_DIR); + helpers.writePackageJson(packageJson, projectDir); dependencyManager.showHelperMessages(postinstallOptions); } function uninstall() { - projectFilesManager.removeProjectFiles(PROJECT_DIR, APP_DIR); + const projectDir = helpers.getProjectDir(); + const appPath = helpers.getAppPath(); + projectFilesManager.removeProjectFiles(projectDir, appPath); + console.log("NativeScript Webpack removed!"); } diff --git a/lib/after-prepare.js b/lib/after-prepare.js index 85da7ddc..884527b4 100644 --- a/lib/after-prepare.js +++ b/lib/after-prepare.js @@ -1,7 +1,7 @@ -const snapshotGenerator = require("../snapshot/android/project-snapshot-generator"); -const utils = require("./utils"); +const { installSnapshotArtefacts } = require("../snapshot/android/project-snapshot-generator"); +const { shouldSnapshot } = require("./utils"); -module.exports = function ($mobileHelper, $projectData, hookArgs) { +module.exports = function ($projectData, hookArgs) { const env = hookArgs.env || {}; const shouldSnapshotOptions = { platform: hookArgs.platform, @@ -9,7 +9,7 @@ module.exports = function ($mobileHelper, $projectData, hookArgs) { release: hookArgs.appFilesUpdaterOptions.release }; - if (env.snapshot && utils.shouldSnapshot($mobileHelper, shouldSnapshotOptions)) { - snapshotGenerator.installSnapshotArtefacts($projectData.projectDir); + if (env.snapshot && shouldSnapshot(shouldSnapshotOptions)) { + installSnapshotArtefacts($projectData.projectDir); } } diff --git a/lib/before-cleanApp.js b/lib/before-cleanApp.js index 99d1c5c7..83968a37 100644 --- a/lib/before-cleanApp.js +++ b/lib/before-cleanApp.js @@ -1,6 +1,8 @@ -const ProjectSnapshotGenerator = require("../snapshot/android/project-snapshot-generator"); -module.exports = function ($mobileHelper, hookArgs) { - if ($mobileHelper.isAndroidPlatform(hookArgs.platformInfo.platform)) { - ProjectSnapshotGenerator.cleanSnapshotArtefacts(hookArgs.platformInfo.projectData.projectDir); - } +const { cleanSnapshotArtefacts } = require("../snapshot/android/project-snapshot-generator"); +const { isAndroid } = require("../projectHelpers"); + +module.exports = function (hookArgs) { + if (isAndroid(hookArgs.platformInfo.platform)) { + cleanSnapshotArtefacts(hookArgs.platformInfo.projectData.projectDir); + } } diff --git a/lib/before-prepareJS.js b/lib/before-prepareJS.js index bb2ea12c..056a66d2 100644 --- a/lib/before-prepareJS.js +++ b/lib/before-prepareJS.js @@ -1,6 +1,6 @@ const { runWebpackCompiler } = require("./compiler"); -module.exports = function ($mobileHelper, $projectData, $logger, hookArgs) { +module.exports = function ($projectData, $logger, hookArgs) { const env = hookArgs.config.env || {}; const platform = hookArgs.config.platform; const appFilesUpdaterOptions = hookArgs.config.appFilesUpdaterOptions; @@ -10,6 +10,6 @@ module.exports = function ($mobileHelper, $projectData, $logger, hookArgs) { bundle: appFilesUpdaterOptions.bundle, release: appFilesUpdaterOptions.release, }; - const result = config.bundle && runWebpackCompiler.bind(runWebpackCompiler, config, $mobileHelper, $projectData, $logger, hookArgs); + const result = config.bundle && runWebpackCompiler.bind(runWebpackCompiler, config, $projectData, $logger, hookArgs); return result; } diff --git a/lib/before-watch.js b/lib/before-watch.js index 6e989d4b..c37906c9 100644 --- a/lib/before-watch.js +++ b/lib/before-watch.js @@ -1,6 +1,6 @@ const { runWebpackCompiler } = require("./compiler"); -module.exports = function ($mobileHelper, $projectData, $logger, hookArgs) { +module.exports = function ($projectData, $logger, hookArgs) { if (hookArgs.config) { const appFilesUpdaterOptions = hookArgs.config.appFilesUpdaterOptions; if (appFilesUpdaterOptions.bundle) { @@ -15,7 +15,7 @@ module.exports = function ($mobileHelper, $projectData, $logger, hookArgs) { watch: true }; - return runWebpackCompiler(config, $mobileHelper, $projectData, $logger, hookArgs); + return runWebpackCompiler(config, $projectData, $logger, hookArgs); })); } } diff --git a/lib/before-watchPatterns.js b/lib/before-watchPatterns.js index 0e2703a7..ea25cba6 100644 --- a/lib/before-watchPatterns.js +++ b/lib/before-watchPatterns.js @@ -1,12 +1,17 @@ const { basename } = require("path"); -const { buildEnvData, getCompilationContext } = require("./utils"); +const { + buildEnvData, + getCompilationContext, + setProcessInitDirectory, +} = require("./utils"); -module.exports = function (hookArgs) { +module.exports = function ($projectData, hookArgs) { const { liveSyncData } = hookArgs; if (!liveSyncData || !liveSyncData.bundle) { return; } + setProcessInitDirectory($projectData.projectDir); const { platforms } = hookArgs; const { env } = liveSyncData; return (args, originalMethod) => { @@ -16,7 +21,7 @@ module.exports = function (hookArgs) { } const compilationContexts = platforms.map(platform => - getContext(platform, env)); + getContext($projectData, platform, env)); const ignorePatterns = compilationContexts.map( context => `!${context}` @@ -27,7 +32,7 @@ module.exports = function (hookArgs) { }; } -function getContext(platform, env) { - const fullEnvData = buildEnvData(platform, env); - return getCompilationContext(fullEnvData); +function getContext($projectData, platform, env) { + const fullEnvData = buildEnvData($projectData, platform, env); + return getCompilationContext($projectData.projectDir, fullEnvData); } diff --git a/lib/compiler.js b/lib/compiler.js index 5a5b571d..2ec22042 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -3,7 +3,9 @@ const { spawn } = require("child_process"); const { join, resolve: pathResolve } = require("path"); const { existsSync } = require("fs"); const readline = require("readline"); + const { messages } = require("../plugins/WatchStateLoggerPlugin"); +const { safeGet } = require("../projectHelpers"); const { buildEnvData, getCompilationContext } = require("./utils"); let hasBeenInvoked = false; @@ -11,17 +13,11 @@ let hasBeenInvoked = false; let webpackProcess = null; let hasLoggedSnapshotWarningMessage = false; -function logdSnapshotWarningMessage($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."); - } -} - exports.getWebpackProcess = function getWebpackProcess() { return webpackProcess; } -exports.runWebpackCompiler = function runWebpackCompiler(config, $mobileHelper, $projectData, $logger, hookArgs) { +exports.runWebpackCompiler = function runWebpackCompiler(config, $projectData, $logger, hookArgs) { if (config.bundle) { return new Promise(function (resolveBase, rejectBase) { if (webpackProcess) { @@ -42,19 +38,15 @@ exports.runWebpackCompiler = function runWebpackCompiler(config, $mobileHelper, console.log(`Running webpack for ${config.platform}...`); - const envData = buildEnvData(config.platform, config.env); - const envFlagNames = Object.keys(envData); - - const snapshotEnvIndex = envFlagNames.indexOf("snapshot"); - if (snapshotEnvIndex !== -1 && !utils.shouldSnapshot($mobileHelper, config)) { - logdSnapshotWarningMessage($logger); - envFlagNames.splice(snapshotEnvIndex, 1); - } + const projectDir = getProjectDir($projectData); + const { platform, env } = config; + const envData = buildEnvData($projectData, platform, env); + const envParams = buildEnvCommandLineParams(config, envData, $logger); // Adding `npm i source-map-support --save-dev` in an app will make source maps work // and stack traces will point to .ts if .ts files and proper source maps exist. let sourceMapSupportArgs = []; - const appSourceMapSupportInstallPath = pathResolve($projectData.projectDir, "node_modules", "source-map-support", "register.js"); + const appSourceMapSupportInstallPath = pathResolve(projectDir, "node_modules", "source-map-support", "register.js"); const devDepSourceMapSupportInstallPath = pathResolve(__dirname, "..", "node_modules", "source-map-support", "register.js"); if (existsSync(appSourceMapSupportInstallPath)) { sourceMapSupportArgs = ["--require", appSourceMapSupportInstallPath]; @@ -65,11 +57,11 @@ exports.runWebpackCompiler = function runWebpackCompiler(config, $mobileHelper, const args = [ "--preserve-symlinks", ...sourceMapSupportArgs, - join($projectData.projectDir, "node_modules", "webpack", "bin", "webpack.js"), - "--config=webpack.config.js", + pathResolve(projectDir, "node_modules", "webpack", "bin", "webpack.js"), + `--config=${pathResolve(projectDir, "webpack.config.js")}`, "--progress", ...(config.watch ? ["--watch"] : []), - ...envFlagNames.map(item => `--env.${item}`), + ...envParams, ].filter(a => !!a); const childProcess = spawn("node", args, { @@ -77,7 +69,7 @@ exports.runWebpackCompiler = function runWebpackCompiler(config, $mobileHelper, // 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: $projectData.projectDir + cwd: projectDir }); let isFirstWebpackWatchCompilation = true; @@ -94,10 +86,10 @@ exports.runWebpackCompiler = function runWebpackCompiler(config, $mobileHelper, } if (hookArgs.filesToSync && hookArgs.startSyncFilesTimeout) { - const compilationContext = getCompilationContext(envData); + const compilationContext = getCompilationContext(projectDir, envData); hookArgs.filesToSync.push( ...message.emittedFiles.map( - emittedFile => join($projectData.projectDir, compilationContext, emittedFile) + emittedFile => join(projectDir, compilationContext, emittedFile) ) ); hookArgs.startSyncFilesTimeout(); @@ -128,3 +120,34 @@ exports.runWebpackCompiler = function runWebpackCompiler(config, $mobileHelper, }); } } + +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); + } + + return envFlagNames.map(item => `--env.${item}=${envData[item]}`); +} + +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 getProjectDir($projectData) { + const projectDir = safeGet($projectData, "projectDir"); + if (!projectDir) { + throw new Error("Cannot find project dir in project data!"); + } + + return projectDir; +} + diff --git a/lib/utils.js b/lib/utils.js index 3a4329d3..cac7e08a 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,17 +1,31 @@ const os = require("os"); const path = require("path"); -const { getProjectDir, getWebpackConfig } = require("../projectHelpers"); +const { + getAppPathFromProjectData, + getAppResourcesPathFromProjectData, + getProjectDir, + getWebpackConfig, + isAndroid, +} = require("../projectHelpers"); -function buildEnvData(platform, env) { - return Object.assign({}, +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; } -function getCompilationContext(env) { - const projectDir = getProjectDir(); +function getCompilationContext(projectDir, env) { const config = getWebpackConfig(projectDir, env); const { context } = config; @@ -20,15 +34,18 @@ function getCompilationContext(env) { "."; } -function shouldSnapshot($mobileHelper, config) { - const platformSupportsSnapshot = $mobileHelper.isAndroidPlatform(config.platform); +function shouldSnapshot(config) { + const platformSupportsSnapshot = isAndroid(config.platform); const osSupportsSnapshot = os.type() !== "Windows_NT"; +} - return config.bundle && config.release && platformSupportsSnapshot && osSupportsSnapshot; +function setProcessInitDirectory(dir) { + process.env.INIT_CWD = dir; } module.exports = { buildEnvData, getCompilationContext, shouldSnapshot, + setProcessInitDirectory, }; diff --git a/nsCliHelpers.js b/nsCliHelpers.js new file mode 100644 index 00000000..45a3c776 --- /dev/null +++ b/nsCliHelpers.js @@ -0,0 +1,25 @@ +const { getPath } = require("global-modules-path"); + +const PROJECT_DATA_GETTERS = { + appPath: "getAppDirectoryRelativePath", + appResourcesPath: "getAppResourcesRelativeDirectoryPath", +}; + +function getProjectData(projectDir) { + const cli = getNsCli(); + const projectData = cli.projectDataService.getProjectData(projectDir); + + return projectData; +} + +function getNsCli() { + const cliPath = getPath("nativescript", "tns"); + const cli = require(cliPath); + + return cli; +} + +module.exports = { + PROJECT_DATA_GETTERS, + getProjectData, +}; diff --git a/package.json b/package.json index 78709a08..b03ae04f 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "generate-android-snapshot": "./bin/generate-android-snapshot" }, "dependencies": { + "global-modules-path": "2.0.0", "minimatch": "3.0.4", "nativescript-hook": "0.2.2", "proxy-lib": "0.4.0", diff --git a/projectHelpers.js b/projectHelpers.js index cabeb51c..16f68ecd 100644 --- a/projectHelpers.js +++ b/projectHelpers.js @@ -3,6 +3,10 @@ const fs = require("fs"); const semver = require("semver"); const { EOL } = require("os"); +const { getProjectData, PROJECT_DATA_GETTERS } = require("./nsCliHelpers"); + +const APP_DIR = "app"; + const isTypeScript = ({ projectDir, packageJson } = {}) => { packageJson = packageJson || getPackageJson(projectDir); @@ -48,6 +52,7 @@ const getAndroidRuntimeVersion = (projectDir) => { const getWebpackConfig = (projectDir, env, configPath = "webpack.config.js") => { const configAbsolutePath = path.resolve(projectDir, configPath); let config; + try { config = require(configAbsolutePath); } catch (e) { @@ -137,16 +142,58 @@ const resolveAndroidConfigurationsPath = projectDir => { const getPackageJsonPath = projectDir => path.resolve(projectDir, "package.json"); +const isAndroid = platform => /android/i.test(platform); +const isIos = platform => /ios/i.test(platform); + +function getAppPath() { + const projectDir = getProjectDir(); + const projectData = getProjectData(projectDir); + const appDir = getAppPathFromProjectData(projectData) || APP_DIR; + + const appPath = path.resolve(projectDir, appDir); + + return appPath; +} + +function getAppPathFromProjectData(data) { + return safeGet(data, PROJECT_DATA_GETTERS.appPath); +} + +function getAppResourcesPathFromProjectData(data) { + return safeGet(data, PROJECT_DATA_GETTERS.appResourcesPath); +} + +function safeGet(object, property) { + if (!object) { + return; + } + + const value = object[property]; + if (!value) { + return; + } + + return typeof value === "function" ? + value.bind(object)() : + value; +} + module.exports = { + getAppPath, + getAppPathFromProjectData, + getAppResourcesPathFromProjectData, getAndroidProjectPath, getAndroidRuntimeVersion, getPackageJson, getProjectDir, getWebpackConfig, + isAndroid, + isIos, isAngular, isSass, isTypeScript, resolveAndroidAppPath, resolveAndroidConfigurationsPath, writePackageJson, + safeGet, }; diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index c0ae7065..d959a8f1 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -4,7 +4,6 @@ const webpack = require("webpack"); const nsWebpack = require("nativescript-dev-webpack"); const nativescriptTarget = require("nativescript-dev-webpack/nativescript-target"); const CopyWebpackPlugin = require("copy-webpack-plugin"); -const ExtractTextPlugin = require("extract-text-webpack-plugin"); const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); @@ -15,21 +14,41 @@ module.exports = env => { throw new Error("You need to provide a target platform!"); } const platforms = ["ios", "android"]; - const { snapshot, uglify, report, aot } = env; + const { + // The 'appPath' and 'appResourcesDir' values are fetched from + // the nsconfig.json configuration file + // when bundling with `tns run android|ios --bundle`. + appPath = "app", + appResourcesPath = "app/App_Resources", + + // Aot, snapshot, uglify and report can be enabled by providing + // the `--env.snapshot`, `--env.uglify` or `--env.report` flags + // when running 'tns run android|ios' + aot, + snapshot, + uglify, + report, + } = env; const ngToolsWebpackOptions = { tsConfigPath: join(__dirname, "tsconfig.json") }; + const projectRoot = __dirname; + const appFullPath = resolve(projectRoot, appPath); + const appResourcesFullPath = resolve(projectRoot, appResourcesPath); + const config = { - context: resolve(__dirname, "app"), + context: appFullPath, watchOptions: { ignored: [ - resolve(__dirname, "./app/App_Resources"), + appResourcesFullPath, // Don't watch hidden files "**/.*", ] }, target: nativescriptTarget, entry: { - bundle: aot ? "./main.aot.ts" : "./main.ts", + bundle: aot ? + `./${nsWebpack.getAotEntryModule(appFullPath)}` : + `./${nsWebpack.getEntryModule(appFullPath)}`, vendor: "./vendor", }, output: { @@ -47,7 +66,7 @@ module.exports = env => { "node_modules", ], alias: { - '~': resolve("./app") + '~': appFullPath }, // don't resolve symlinks to symlinked modules symlinks: false @@ -105,7 +124,7 @@ module.exports = env => { }), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ - { from: "App_Resources/**" }, + { from: `${appResourcesFullPath}/**`, context: projectRoot }, { from: "fonts/**" }, { from: "**/*.jpg" }, { from: "**/*.png" }, @@ -140,14 +159,14 @@ module.exports = env => { analyzerMode: "static", openAnalyzer: false, generateStatsFile: true, - reportFilename: join(__dirname, "report", `report.html`), - statsFilename: join(__dirname, "report", `stats.json`), + reportFilename: resolve(projectRoot, "report", `report.html`), + statsFilename: resolve(projectRoot, "report", `stats.json`), })); } if (snapshot) { config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ chunk: "vendor", - projectRoot: __dirname, + projectRoot, webpackConfig: config, targetArchs: ["arm", "arm64", "ia32"], tnsJavaClassesOptions: { packages: ["tns-core-modules" ] }, diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index 9a54b4e9..def08781 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -14,20 +14,37 @@ module.exports = env => { throw new Error("You need to provide a target platform!"); } const platforms = ["ios", "android"]; - const { snapshot, uglify, report } = env; + const { + // The 'appPath' and 'appResourcesPath' values are fetched from + // the nsconfig.json configuration file + // when bundling with `tns run android|ios --bundle`. + appPath = "app", + appResourcesPath = "app/App_Resources", + + // Snapshot, uglify and report can be enabled by providing + // the `--env.snapshot`, `--env.uglify` or `--env.report` flags + // when running 'tns run android|ios' + snapshot, + uglify, + report, + } = env; + + const projectRoot = __dirname; + const appFullPath = resolve(projectRoot, appPath); + const appResourcesFullPath = resolve(projectRoot, appResourcesPath); const config = { - context: resolve(__dirname, "app"), + context: appFullPath, watchOptions: { ignored: [ - resolve(__dirname, "./app/App_Resources"), + appResourcesFullPath, // Don't watch hidden files "**/.*", ] }, target: nativescriptTarget, entry: { - bundle: `./${nsWebpack.getEntryModule()}`, + bundle: `./${nsWebpack.getEntryModule(appFullPath)}`, vendor: "./vendor" }, output: { @@ -45,7 +62,7 @@ module.exports = env => { "node_modules", ], alias: { - '~': resolve("./app") + '~': appFullPath }, // don't resolve symlinks to symlinked modules symlinks: false @@ -90,7 +107,7 @@ module.exports = env => { }), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ - { from: "App_Resources/**" }, + { from: `${appResourcesFullPath}/**`, context: projectRoot }, { from: "fonts/**" }, { from: "**/*.jpg" }, { from: "**/*.png" }, @@ -106,7 +123,6 @@ module.exports = env => { new nsWebpack.PlatformFSPlugin({ platform, platforms, - // ignore: ["App_Resources"] }), // Does IPC communication with the {N} CLI to notify events when running in watch mode. new nsWebpack.WatchStateLoggerPlugin(), @@ -118,14 +134,14 @@ module.exports = env => { analyzerMode: "static", openAnalyzer: false, generateStatsFile: true, - reportFilename: join(__dirname, "report", `report.html`), - statsFilename: join(__dirname, "report", `stats.json`), + reportFilename: resolve(projectRoot, "report", `report.html`), + statsFilename: resolve(projectRoot, "report", `stats.json`), })); } if (snapshot) { config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ chunk: "vendor", - projectRoot: __dirname, + projectRoot, webpackConfig: config, targetArchs: ["arm", "arm64", "ia32"], tnsJavaClassesOptions: { packages: ["tns-core-modules" ] }, diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index 99c1f2b6..cbb13ea9 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -14,20 +14,37 @@ module.exports = env => { throw new Error("You need to provide a target platform!"); } const platforms = ["ios", "android"]; - const { snapshot, uglify, report } = env; + const { + // The 'appPath' and 'appResourcesDir' values are fetched from + // the nsconfig.json configuration file + // when bundling with `tns run android|ios --bundle`. + appPath = "app", + appResourcesPath = "app/App_Resources", + + // Snapshot, uglify and report can be enabled by providing + // the `--env.snapshot`, `--env.uglify` or `--env.report` flags + // when running 'tns run android|ios' + snapshot, + uglify, + report, + } = env; + + const projectRoot = __dirname; + const appFullPath = resolve(projectRoot, appPath); + const appResourcesFullPath = resolve(projectRoot, appResourcesPath); const config = { - context: resolve(__dirname, "app"), + context: appFullPath, watchOptions: { ignored: [ - resolve(__dirname, "./app/App_Resources"), + appResourcesFullPath, // Don't watch hidden files "**/.*", ] }, target: nativescriptTarget, entry: { - bundle: `./${nsWebpack.getEntryModule()}`, + bundle: `./${nsWebpack.getEntryModule(appFullPath)}`, vendor: "./vendor" }, output: { @@ -92,7 +109,7 @@ module.exports = env => { }), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ - { from: "App_Resources/**" }, + { from: `${appResourcesFullPath}/**`, context: projectRoot }, { from: "fonts/**" }, { from: "**/*.jpg" }, { from: "**/*.png" }, @@ -108,7 +125,6 @@ module.exports = env => { new nsWebpack.PlatformFSPlugin({ platform, platforms, - // ignore: ["App_Resources"] }), // Does IPC communication with the {N} CLI to notify events when running in watch mode. new nsWebpack.WatchStateLoggerPlugin(), @@ -120,14 +136,14 @@ module.exports = env => { analyzerMode: "static", openAnalyzer: false, generateStatsFile: true, - reportFilename: join(__dirname, "report", `report.html`), - statsFilename: join(__dirname, "report", `stats.json`), + reportFilename: resolve(projectRoot, "report", `report.html`), + statsFilename: resolve(projectRoot, "report", `stats.json`), })); } if (snapshot) { config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ chunk: "vendor", - projectRoot: __dirname, + projectRoot, webpackConfig: config, targetArchs: ["arm", "arm64", "ia32"], tnsJavaClassesOptions: { packages: ["tns-core-modules" ] }, diff --git a/verify/update.js b/verify/update.js index a5eac1b7..fa37c172 100644 --- a/verify/update.js +++ b/verify/update.js @@ -1,7 +1,12 @@ const { spawn } = require("child_process"); const { resolve: pathResolve } = require("path"); -const { getPackageJson, getProjectDir, writePackageJson } = require("../projectHelpers"); +const { + getAppPath, + getPackageJson, + getProjectDir, + writePackageJson, +} = require("../projectHelpers"); const { forceUpdateProjectFiles } = require("../projectFilesManager"); const { forceUpdateProjectDeps } = require("../dependencyManager"); @@ -44,7 +49,7 @@ function updateDeps(projectDir) { function updateConfigs(projectDir) { console.info("Updating configuration files..."); - const appDir = pathResolve(projectDir, "app"); + const appDir = getAppPath(); forceUpdateProjectFiles(projectDir, appDir); } From 3591fc6c4dc0d93517b8c6bc2693aac516599193 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Wed, 14 Mar 2018 18:17:11 +0200 Subject: [PATCH 02/41] test: refactor to use NativeScriptCommonModule instead of NativeScriptModule --- demo/AngularApp/app/ninjas/details/ninja.module.ts | 6 +++--- demo/AngularApp/app/ninjas/ninjas.module.ts | 6 +++--- demo/JavaScriptApp/package.json | 11 +++++++---- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/demo/AngularApp/app/ninjas/details/ninja.module.ts b/demo/AngularApp/app/ninjas/details/ninja.module.ts index 1104172f..dd67895b 100644 --- a/demo/AngularApp/app/ninjas/details/ninja.module.ts +++ b/demo/AngularApp/app/ninjas/details/ninja.module.ts @@ -1,5 +1,5 @@ +import { NativeScriptCommonModule } from "nativescript-angular/common"; import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core"; -import { NativeScriptModule } from "nativescript-angular/nativescript.module"; import { NativeScriptRouterModule } from "nativescript-angular/router"; import { NinjaComponent } from "./ninja.component"; @@ -8,9 +8,9 @@ import { routes } from "./ninja.routes"; @NgModule({ schemas: [NO_ERRORS_SCHEMA], imports: [ - NativeScriptModule, NativeScriptRouterModule, - NativeScriptRouterModule.forChild(routes) + NativeScriptRouterModule.forChild(routes), + NativeScriptCommonModule, ], declarations: [NinjaComponent] }) diff --git a/demo/AngularApp/app/ninjas/ninjas.module.ts b/demo/AngularApp/app/ninjas/ninjas.module.ts index dabc4856..403b5a8d 100644 --- a/demo/AngularApp/app/ninjas/ninjas.module.ts +++ b/demo/AngularApp/app/ninjas/ninjas.module.ts @@ -1,5 +1,5 @@ +import { NativeScriptCommonModule } from "nativescript-angular/common"; import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core"; -import { NativeScriptModule } from "nativescript-angular/nativescript.module"; import { NativeScriptRouterModule } from "nativescript-angular/router"; import { NinjasComponent } from "./ninjas.component"; @@ -8,9 +8,9 @@ import { routes } from "./ninjas.routes"; @NgModule({ schemas: [NO_ERRORS_SCHEMA], imports: [ - NativeScriptModule, NativeScriptRouterModule, - NativeScriptRouterModule.forChild(routes) + NativeScriptRouterModule.forChild(routes), + NativeScriptCommonModule, ], declarations: [NinjasComponent] }) diff --git a/demo/JavaScriptApp/package.json b/demo/JavaScriptApp/package.json index 25dd1ff0..343e5744 100644 --- a/demo/JavaScriptApp/package.json +++ b/demo/JavaScriptApp/package.json @@ -24,6 +24,9 @@ "css-loader": "~0.28.7", "extract-text-webpack-plugin": "~3.0.0", "lazy": "1.0.11", + "mocha": "~3.5.0", + "mocha-junit-reporter": "^1.13.0", + "mocha-multi": "^0.11.0", "nativescript-dev-appium": "next", "nativescript-dev-sass": "^1.3.5", "nativescript-dev-webpack": "file:../..", @@ -32,9 +35,9 @@ "raw-loader": "~0.5.1", "resolve-url-loader": "~2.1.0", "sass-loader": "^6.0.6", - "webpack": "~3.8.1", - "webpack-bundle-analyzer": "^2.8.2", - "webpack-sources": "~1.0.1" + "webpack": "~3.10.0", + "webpack-bundle-analyzer": "^2.9.1", + "webpack-sources": "^1.1.0" }, "scripts": { "ns-bundle": "ns-bundle", @@ -46,4 +49,4 @@ "generate-android-snapshot": "generate-android-snapshot --targetArchs arm,arm64,ia32 --install", "e2e": "mocha --opts ./e2e/config/mocha.opts" } -} \ No newline at end of file +} From 2e9405615f71bba45ffcb242805141dbc10e3ac5 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Thu, 15 Mar 2018 17:58:39 +0200 Subject: [PATCH 03/41] fix: return right value from shouldSnapshot --- lib/utils.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/utils.js b/lib/utils.js index cac7e08a..441b12fc 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -37,6 +37,8 @@ function getCompilationContext(projectDir, env) { function shouldSnapshot(config) { const platformSupportsSnapshot = isAndroid(config.platform); const osSupportsSnapshot = os.type() !== "Windows_NT"; + + return config.bundle && config.release && platformSupportsSnapshot && osSupportsSnapshot; } function setProcessInitDirectory(dir) { From 4a04dbc8f65e38446660b63d82183217dcb6aaa2 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Mon, 19 Mar 2018 19:28:38 +0200 Subject: [PATCH 04/41] fix: get project data safely --- nsCliHelpers.js | 19 ++++++++++++++++++- projectHelpers.js | 22 +++++----------------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/nsCliHelpers.js b/nsCliHelpers.js index 45a3c776..318e574c 100644 --- a/nsCliHelpers.js +++ b/nsCliHelpers.js @@ -7,7 +7,8 @@ const PROJECT_DATA_GETTERS = { function getProjectData(projectDir) { const cli = getNsCli(); - const projectData = cli.projectDataService.getProjectData(projectDir); + const projectDataService = cli.projectDataService; + const projectData = safeGet(cli, "getProjectData", projectDir); return projectData; } @@ -19,7 +20,23 @@ function getNsCli() { return cli; } +function safeGet(object, property, args) { + if (!object) { + return; + } + + const value = object[property]; + if (!value) { + return; + } + + return typeof value === "function" ? + value.bind(object)(...args) : + value; +} + module.exports = { PROJECT_DATA_GETTERS, getProjectData, + safeGet, }; diff --git a/projectHelpers.js b/projectHelpers.js index 16f68ecd..0ae0656f 100644 --- a/projectHelpers.js +++ b/projectHelpers.js @@ -3,7 +3,11 @@ const fs = require("fs"); const semver = require("semver"); const { EOL } = require("os"); -const { getProjectData, PROJECT_DATA_GETTERS } = require("./nsCliHelpers"); +const { + PROJECT_DATA_GETTERS, + getProjectData, + safeGet, +} = require("./nsCliHelpers"); const APP_DIR = "app"; @@ -163,21 +167,6 @@ function getAppResourcesPathFromProjectData(data) { return safeGet(data, PROJECT_DATA_GETTERS.appResourcesPath); } -function safeGet(object, property) { - if (!object) { - return; - } - - const value = object[property]; - if (!value) { - return; - } - - return typeof value === "function" ? - value.bind(object)() : - value; -} - module.exports = { getAppPath, getAppPathFromProjectData, @@ -195,5 +184,4 @@ module.exports = { resolveAndroidAppPath, resolveAndroidConfigurationsPath, writePackageJson, - safeGet, }; From 376d8206013fb276b3752f4e5e82032c2112c5c8 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Mon, 19 Mar 2018 19:31:30 +0200 Subject: [PATCH 05/41] refactor: get projectDir directly from projectData --- lib/compiler.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/lib/compiler.js b/lib/compiler.js index 2ec22042..9f66cd92 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -5,7 +5,6 @@ const { existsSync } = require("fs"); const readline = require("readline"); const { messages } = require("../plugins/WatchStateLoggerPlugin"); -const { safeGet } = require("../projectHelpers"); const { buildEnvData, getCompilationContext } = require("./utils"); let hasBeenInvoked = false; @@ -38,7 +37,7 @@ exports.runWebpackCompiler = function runWebpackCompiler(config, $projectData, $ console.log(`Running webpack for ${config.platform}...`); - const projectDir = getProjectDir($projectData); + const projectDir = $projectData.projectDir; const { platform, env } = config; const envData = buildEnvData($projectData, platform, env); const envParams = buildEnvCommandLineParams(config, envData, $logger); @@ -142,12 +141,3 @@ function logSnapshotWarningMessage($logger) { } } -function getProjectDir($projectData) { - const projectDir = safeGet($projectData, "projectDir"); - if (!projectDir) { - throw new Error("Cannot find project dir in project data!"); - } - - return projectDir; -} - From 4f7a93d4d608aa7a9e82f2219626964f38c63951 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Mon, 19 Mar 2018 19:46:32 +0200 Subject: [PATCH 06/41] refactor: export APP_DIR constant from projectHelpers --- index.js | 7 ++++--- projectHelpers.js | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index c33cfbed..31544e28 100644 --- a/index.js +++ b/index.js @@ -2,6 +2,7 @@ const path = require("path"); const { existsSync } = require("fs"); const { + APP_DIR, getPackageJson, getProjectDir, isAngular, @@ -11,7 +12,7 @@ const { } = require("./projectHelpers"); const PROJECT_DIR = getProjectDir(); -const APP_DIR = path.join(PROJECT_DIR, "app"); +const APP_PATH = path.join(PROJECT_DIR, APP_DIR); Object.assign(exports, require('./plugins')); @@ -19,7 +20,7 @@ if (isAngular({ projectDir: PROJECT_DIR })) { Object.assign(exports, require('./plugins/angular')); } -exports.getAotEntryModule = function (appDirectory = APP_DIR) { +exports.getAotEntryModule = function (appDirectory = APP_PATH) { const entry = getPackageJsonEntry(appDirectory); const aotEntry = `${entry}.aot.ts`; @@ -32,7 +33,7 @@ exports.getAotEntryModule = function (appDirectory = APP_DIR) { return aotEntry; } -exports.getEntryModule = function (appDirectory = APP_DIR) { +exports.getEntryModule = function (appDirectory = APP_PATH) { const entry = getPackageJsonEntry(appDirectory); const tsEntryPath = path.resolve(appDirectory, `${entry}.ts`); diff --git a/projectHelpers.js b/projectHelpers.js index 0ae0656f..b42f4a91 100644 --- a/projectHelpers.js +++ b/projectHelpers.js @@ -168,6 +168,7 @@ function getAppResourcesPathFromProjectData(data) { } module.exports = { + APP_DIR, getAppPath, getAppPathFromProjectData, getAppResourcesPathFromProjectData, From 916d8f9815ebe48483f010f4cca322d32632db32 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Mon, 19 Mar 2018 19:58:05 +0200 Subject: [PATCH 07/41] fix: default value for args for safeGet function --- nsCliHelpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nsCliHelpers.js b/nsCliHelpers.js index 318e574c..66b2f8e6 100644 --- a/nsCliHelpers.js +++ b/nsCliHelpers.js @@ -20,7 +20,7 @@ function getNsCli() { return cli; } -function safeGet(object, property, args) { +function safeGet(object, property, args = []) { if (!object) { return; } From db588f3d2dbdc792d991d3b755ff9b87fb835cda Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Sat, 17 Mar 2018 15:20:08 +0200 Subject: [PATCH 08/41] fix(prepare): clean platforms/.../app/ when running webpack Every time we are running a new build with webpack the platforms/.../app/ dir should be deleted as there may be old assets left. Ex. When the app bundled with snapshot enabled: ``` tns build android --bundle --env.snapshot ``` this produces some assets: ``` platforms/android/.../app/vendor.js platforms/android/.../app/_embedded_script.js // ... ``` Then, if the project is bundled without snapshot: ``` tns build android --bundle ``` the produced assets will override the ones that are already in `platforms/android/.../app`. However, since the build is without snapshot, an `_embedded_script.js` won't be generated to override the one that's left in `platforms/android/.../app` from the previous build. We'll be using `CleanWebpackPlugin` to clean the dist folder. ** Important **: Currently we're running two webpack builds when doing `tns run android|ios` - one on prepare and one when the watcher starts. This means that the dist folder will be cleaned two times. This will be resolved when https://github.com/NativeScript/nativescript-cli/issues/3404 is implemented. fixes https://github.com/NativeScript/nativescript-dev-webpack/issues/463 --- dependencyManager.js | 1 + templates/webpack.angular.js | 12 +++++++++--- templates/webpack.javascript.js | 12 +++++++++--- templates/webpack.typescript.js | 12 +++++++++--- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/dependencyManager.js b/dependencyManager.js index c4cb50a6..6d292dcc 100644 --- a/dependencyManager.js +++ b/dependencyManager.js @@ -61,6 +61,7 @@ function getRequiredDeps(packageJson) { "webpack": "~3.10.0", "webpack-bundle-analyzer": "^2.9.1", "webpack-sources": "~1.1.0", + "clean-webpack-plugin": "~0.1.19", "copy-webpack-plugin": "~4.3.0", "raw-loader": "~0.5.1", "css-loader": "~0.28.7", diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index d959a8f1..e4f7afb5 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -3,6 +3,7 @@ const { resolve, join } = require("path"); const webpack = require("webpack"); 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 { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); @@ -13,6 +14,11 @@ module.exports = env => { if (!platform) { throw new Error("You need to provide a target platform!"); } + + const projectRoot = __dirname; + // Default destination inside platforms//... + const dist = resolve(projectRoot, nsWebpack.getAppPath(platform)); + const platforms = ["ios", "android"]; const { // The 'appPath' and 'appResourcesDir' values are fetched from @@ -31,7 +37,6 @@ module.exports = env => { } = env; const ngToolsWebpackOptions = { tsConfigPath: join(__dirname, "tsconfig.json") }; - const projectRoot = __dirname; const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); @@ -53,8 +58,7 @@ module.exports = env => { }, output: { pathinfo: true, - // Default destination inside platforms//... - path: resolve(nsWebpack.getAppPath(platform)), + path: dist, libraryTarget: "commonjs2", filename: "[name].js", }, @@ -122,6 +126,8 @@ module.exports = env => { new webpack.DefinePlugin({ "global.TNS_WEBPACK": "true", }), + // Remove all files from the out dir. + new CleanWebpackPlugin([ `${dist}/**/*` ]), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ { from: `${appResourcesFullPath}/**`, context: projectRoot }, diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index def08781..997ddc6b 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -3,6 +3,7 @@ const { resolve, join } = require("path"); const webpack = require("webpack"); 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 { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); @@ -13,6 +14,11 @@ module.exports = env => { if (!platform) { throw new Error("You need to provide a target platform!"); } + + const projectRoot = __dirname; + // Default destination inside platforms//... + const dist = resolve(projectRoot, nsWebpack.getAppPath(platform)); + const platforms = ["ios", "android"]; const { // The 'appPath' and 'appResourcesPath' values are fetched from @@ -29,7 +35,6 @@ module.exports = env => { report, } = env; - const projectRoot = __dirname; const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); @@ -49,8 +54,7 @@ module.exports = env => { }, output: { pathinfo: true, - // Default destination inside platforms//... - path: resolve(nsWebpack.getAppPath(platform)), + path: dist, libraryTarget: "commonjs2", filename: "[name].js", }, @@ -105,6 +109,8 @@ module.exports = env => { new webpack.DefinePlugin({ "global.TNS_WEBPACK": "true", }), + // Remove all files from the out dir. + new CleanWebpackPlugin([ `${dist}/**/*` ]), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ { from: `${appResourcesFullPath}/**`, context: projectRoot }, diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index cbb13ea9..14214da0 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -3,6 +3,7 @@ const { resolve, join } = require("path"); const webpack = require("webpack"); 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 { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); @@ -13,6 +14,11 @@ module.exports = env => { if (!platform) { throw new Error("You need to provide a target platform!"); } + + const projectRoot = __dirname; + // Default destination inside platforms//... + const dist = resolve(projectRoot, nsWebpack.getAppPath(platform)); + const platforms = ["ios", "android"]; const { // The 'appPath' and 'appResourcesDir' values are fetched from @@ -29,7 +35,6 @@ module.exports = env => { report, } = env; - const projectRoot = __dirname; const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); @@ -49,8 +54,7 @@ module.exports = env => { }, output: { pathinfo: true, - // Default destination inside platforms//... - path: resolve(nsWebpack.getAppPath(platform)), + path: dist, libraryTarget: "commonjs2", filename: "[name].js", }, @@ -107,6 +111,8 @@ module.exports = env => { new webpack.DefinePlugin({ "global.TNS_WEBPACK": "true", }), + // Remove all files from the out dir. + new CleanWebpackPlugin([ `${dist}/**/*` ]), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ { from: `${appResourcesFullPath}/**`, context: projectRoot }, From 7eccdab64f8517f9a2e797aae0f49ad6742bded3 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Sat, 17 Mar 2018 15:53:05 +0200 Subject: [PATCH 09/41] fix-next: copy only the target platform App Resources When building for Android the App_Resources for iOS should be copied to the dist directory and vice-versa. --- templates/webpack.angular.js | 18 +++++++++++++----- templates/webpack.javascript.js | 16 ++++++++++++---- templates/webpack.typescript.js | 18 +++++++++++++----- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index e4f7afb5..32e6d0e0 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -1,4 +1,4 @@ -const { resolve, join } = require("path"); +const { relative, resolve, join } = require("path"); const webpack = require("webpack"); const nsWebpack = require("nativescript-dev-webpack"); @@ -15,13 +15,14 @@ module.exports = env => { throw new Error("You need to provide a target platform!"); } + const platforms = ["ios", "android"]; const projectRoot = __dirname; // Default destination inside platforms//... const dist = resolve(projectRoot, nsWebpack.getAppPath(platform)); + const appResourcesPlatformDir = platform === "android" ? "Android" : "iOS"; - const platforms = ["ios", "android"]; const { - // The 'appPath' and 'appResourcesDir' values are fetched from + // The 'appPath' and 'appResourcesPath' values are fetched from // the nsconfig.json configuration file // when bundling with `tns run android|ios --bundle`. appPath = "app", @@ -128,14 +129,21 @@ module.exports = env => { }), // Remove all files from the out dir. new CleanWebpackPlugin([ `${dist}/**/*` ]), + // Copy native app resources to out dir. + new CopyWebpackPlugin([ + { + from: `${appResourcesFullPath}/${appResourcesPlatformDir}`, + to: `${dist}/App_Resources/${appResourcesPlatformDir}`, + context: projectRoot + }, + ]), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ - { from: `${appResourcesFullPath}/**`, context: projectRoot }, { from: "fonts/**" }, { from: "**/*.jpg" }, { from: "**/*.png" }, { from: "**/*.xml" }, - ]), + ], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }), // Generate a bundle starter script and activate it in package.json new nsWebpack.GenerateBundleStarterPlugin([ "./vendor", diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index 997ddc6b..866192bf 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -1,4 +1,4 @@ -const { resolve, join } = require("path"); +const { relative, resolve, join } = require("path"); const webpack = require("webpack"); const nsWebpack = require("nativescript-dev-webpack"); @@ -15,11 +15,12 @@ module.exports = env => { throw new Error("You need to provide a target platform!"); } + const platforms = ["ios", "android"]; const projectRoot = __dirname; // Default destination inside platforms//... const dist = resolve(projectRoot, nsWebpack.getAppPath(platform)); + const appResourcesPlatformDir = platform === "android" ? "Android" : "iOS"; - const platforms = ["ios", "android"]; const { // The 'appPath' and 'appResourcesPath' values are fetched from // the nsconfig.json configuration file @@ -111,14 +112,21 @@ module.exports = env => { }), // Remove all files from the out dir. new CleanWebpackPlugin([ `${dist}/**/*` ]), + // Copy native app resources to out dir. + new CopyWebpackPlugin([ + { + from: `${appResourcesFullPath}/${appResourcesPlatformDir}`, + to: `${dist}/App_Resources/${appResourcesPlatformDir}`, + context: projectRoot + }, + ]), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ - { from: `${appResourcesFullPath}/**`, context: projectRoot }, { from: "fonts/**" }, { from: "**/*.jpg" }, { from: "**/*.png" }, { from: "**/*.xml" }, - ]), + ], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }), // Generate a bundle starter script and activate it in package.json new nsWebpack.GenerateBundleStarterPlugin([ "./vendor", diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index 14214da0..a3d91f02 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -1,4 +1,4 @@ -const { resolve, join } = require("path"); +const { relative, resolve, join } = require("path"); const webpack = require("webpack"); const nsWebpack = require("nativescript-dev-webpack"); @@ -15,13 +15,14 @@ module.exports = env => { throw new Error("You need to provide a target platform!"); } + const platforms = ["ios", "android"]; const projectRoot = __dirname; // Default destination inside platforms//... const dist = resolve(projectRoot, nsWebpack.getAppPath(platform)); + const appResourcesPlatformDir = platform === "android" ? "Android" : "iOS"; - const platforms = ["ios", "android"]; const { - // The 'appPath' and 'appResourcesDir' values are fetched from + // The 'appPath' and 'appResourcesPath' values are fetched from // the nsconfig.json configuration file // when bundling with `tns run android|ios --bundle`. appPath = "app", @@ -113,14 +114,21 @@ module.exports = env => { }), // Remove all files from the out dir. new CleanWebpackPlugin([ `${dist}/**/*` ]), + // Copy native app resources to out dir. + new CopyWebpackPlugin([ + { + from: `${appResourcesFullPath}/${appResourcesPlatformDir}`, + to: `${dist}/App_Resources/${appResourcesPlatformDir}`, + context: projectRoot + }, + ]), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ - { from: `${appResourcesFullPath}/**`, context: projectRoot }, { from: "fonts/**" }, { from: "**/*.jpg" }, { from: "**/*.png" }, { from: "**/*.xml" }, - ]), + ], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }), // Generate a bundle starter script and activate it in package.json new nsWebpack.GenerateBundleStarterPlugin([ "./vendor", From 727c789bd96e703a29effb7b2adf577dc4bea032 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Sat, 17 Mar 2018 20:13:21 +0200 Subject: [PATCH 10/41] fix: remove NsNodeGlobalsPlugin as it's not needed anymore --- nativescript-target/NsNodeGlobalsPlugin.js | 26 ---------------------- nativescript-target/index.js | 4 +--- 2 files changed, 1 insertion(+), 29 deletions(-) delete mode 100644 nativescript-target/NsNodeGlobalsPlugin.js diff --git a/nativescript-target/NsNodeGlobalsPlugin.js b/nativescript-target/NsNodeGlobalsPlugin.js deleted file mode 100644 index 217c6ba0..00000000 --- a/nativescript-target/NsNodeGlobalsPlugin.js +++ /dev/null @@ -1,26 +0,0 @@ -// HACK: Prevent webpack from replacing "global" -// Fixes StackOverflow error caused by DefinePlugin with webpack 2.2+ - -var ConstDependency = require("webpack/lib/dependencies/ConstDependency"); - -function NsNodeGlobalsPlugin() {} -NsNodeGlobalsPlugin.prototype.apply = function(compiler) { - compiler.plugin("compilation", function(compilation, params) { - params.normalModuleFactory.plugin("parser", function(parser, parserOptions) { - parser.plugin("expression global", function(expr) { - var dep = new ConstDependency("global", expr.range); - dep.loc = expr.loc; - this.state.current.addDependency(dep); - return true; - }); - parser.plugin("expression __dirname", function(expr) { - var dep = new ConstDependency("__dirname", expr.range); - dep.loc = expr.loc; - this.state.current.addDependency(dep); - return true; - }); - }); - }); -}; - -module.exports = NsNodeGlobalsPlugin; diff --git a/nativescript-target/index.js b/nativescript-target/index.js index b426b223..5779c13d 100644 --- a/nativescript-target/index.js +++ b/nativescript-target/index.js @@ -2,7 +2,6 @@ module.exports = function nativescriptTarget(compiler) { var options = this; var webpackLib = "webpack/lib"; - var NsNodeGlobalsPlugin = require("./NsNodeGlobalsPlugin"); // Custom template plugin var NsJsonpTemplatePlugin = require("./NsJsonpTemplatePlugin"); @@ -11,10 +10,9 @@ module.exports = function nativescriptTarget(compiler) { var LoaderTargetPlugin = require(webpackLib + "/LoaderTargetPlugin"); compiler.apply( - new NsNodeGlobalsPlugin(), new NsJsonpTemplatePlugin(options.output), new FunctionModulePlugin(options.output), new NodeSourcePlugin(options.node), new LoaderTargetPlugin("web") ); -} \ No newline at end of file +} From fee4be7d9c60838c6c49ea20114fc7008b833e3e Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Wed, 21 Mar 2018 15:25:01 +0200 Subject: [PATCH 11/41] chore: bump versions of deps to all supporting webpack 4 --- dependencyManager.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dependencyManager.js b/dependencyManager.js index 6d292dcc..556b3ddf 100644 --- a/dependencyManager.js +++ b/dependencyManager.js @@ -58,26 +58,27 @@ function addDependency(deps, name, version, force) { function getRequiredDeps(packageJson) { const deps = { - "webpack": "~3.10.0", + "webpack": "~4.1.0", + "webpack-cli": "~2.0.12", "webpack-bundle-analyzer": "^2.9.1", "webpack-sources": "~1.1.0", "clean-webpack-plugin": "~0.1.19", - "copy-webpack-plugin": "~4.3.0", + "copy-webpack-plugin": "~4.5.1", "raw-loader": "~0.5.1", "css-loader": "~0.28.7", "nativescript-worker-loader": "~0.8.1", "resolve-url-loader": "~2.2.1", "extract-text-webpack-plugin": "~3.0.2", - "uglifyjs-webpack-plugin": "~1.1.6", + "uglifyjs-webpack-plugin": "~1.2.4", }; if (isAngular({packageJson})) { Object.assign(deps, { "@angular/compiler-cli": packageJson.dependencies["@angular/core"], - "@ngtools/webpack": "~1.9.4", + "@ngtools/webpack": "~6.0.0-beta.5", }); } else if (isTypeScript({packageJson})) { - Object.assign(deps, { "awesome-typescript-loader": "~3.1.3" }); + Object.assign(deps, { "awesome-typescript-loader": "~5.0.0-1" }); } if (isSass({packageJson})) { From bd4ce6f33a468d802a164de303b79796c00c4c83 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Wed, 21 Mar 2018 16:47:24 +0200 Subject: [PATCH 12/41] refactor: remove vendor chunk from templates --- templates/webpack.angular.js | 18 +++++++++++------- templates/webpack.javascript.js | 18 +++++++++++------- templates/webpack.typescript.js | 18 +++++++++++------- 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index 32e6d0e0..085762b6 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -42,6 +42,16 @@ module.exports = env => { const appResourcesFullPath = resolve(projectRoot, appResourcesPath); const config = { + mode: "development", + devtool: "none", + optimization: { + splitChunks: { + chunks: "all", + cacheGroups: { + commons: { name: "commons" } + } + } + }, context: appFullPath, watchOptions: { ignored: [ @@ -55,7 +65,6 @@ module.exports = env => { bundle: aot ? `./${nsWebpack.getAotEntryModule(appFullPath)}` : `./${nsWebpack.getEntryModule(appFullPath)}`, - vendor: "./vendor", }, output: { pathinfo: true, @@ -119,10 +128,6 @@ module.exports = env => { ], }, plugins: [ - // Vendor libs go to the vendor.js chunk - new webpack.optimize.CommonsChunkPlugin({ - name: ["vendor"], - }), // Define useful constants like TNS_WEBPACK new webpack.DefinePlugin({ "global.TNS_WEBPACK": "true", @@ -146,7 +151,6 @@ module.exports = env => { ], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }), // Generate a bundle starter script and activate it in package.json new nsWebpack.GenerateBundleStarterPlugin([ - "./vendor", "./bundle", ]), // Support for web workers since v3.2 @@ -179,7 +183,7 @@ module.exports = env => { } if (snapshot) { config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ - chunk: "vendor", + chunk: "commons", projectRoot, webpackConfig: config, targetArchs: ["arm", "arm64", "ia32"], diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index 866192bf..221d1d88 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -40,6 +40,16 @@ module.exports = env => { const appResourcesFullPath = resolve(projectRoot, appResourcesPath); const config = { + mode: "development", + devtool: "none", + optimization: { + splitChunks: { + chunks: "all", + cacheGroups: { + commons: { name: "commons" } + } + } + }, context: appFullPath, watchOptions: { ignored: [ @@ -51,7 +61,6 @@ module.exports = env => { target: nativescriptTarget, entry: { bundle: `./${nsWebpack.getEntryModule(appFullPath)}`, - vendor: "./vendor" }, output: { pathinfo: true, @@ -102,10 +111,6 @@ module.exports = env => { ] }, plugins: [ - // Vendor libs go to the vendor.js chunk - new webpack.optimize.CommonsChunkPlugin({ - name: ["vendor"], - }), // Define useful constants like TNS_WEBPACK new webpack.DefinePlugin({ "global.TNS_WEBPACK": "true", @@ -129,7 +134,6 @@ module.exports = env => { ], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }), // Generate a bundle starter script and activate it in package.json new nsWebpack.GenerateBundleStarterPlugin([ - "./vendor", "./bundle", ]), // Support for web workers since v3.2 @@ -154,7 +158,7 @@ module.exports = env => { } if (snapshot) { config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ - chunk: "vendor", + chunk: "commons", projectRoot, webpackConfig: config, targetArchs: ["arm", "arm64", "ia32"], diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index a3d91f02..6e6e0334 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -40,6 +40,16 @@ module.exports = env => { const appResourcesFullPath = resolve(projectRoot, appResourcesPath); const config = { + mode: "development", + devtool: "none", + optimization: { + splitChunks: { + chunks: "all", + cacheGroups: { + commons: { name: "commons" } + } + } + }, context: appFullPath, watchOptions: { ignored: [ @@ -51,7 +61,6 @@ module.exports = env => { target: nativescriptTarget, entry: { bundle: `./${nsWebpack.getEntryModule(appFullPath)}`, - vendor: "./vendor" }, output: { pathinfo: true, @@ -104,10 +113,6 @@ module.exports = env => { ] }, plugins: [ - // Vendor libs go to the vendor.js chunk - new webpack.optimize.CommonsChunkPlugin({ - name: ["vendor"], - }), // Define useful constants like TNS_WEBPACK new webpack.DefinePlugin({ "global.TNS_WEBPACK": "true", @@ -131,7 +136,6 @@ module.exports = env => { ], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }), // Generate a bundle starter script and activate it in package.json new nsWebpack.GenerateBundleStarterPlugin([ - "./vendor", "./bundle", ]), // Support for web workers since v3.2 @@ -156,7 +160,7 @@ module.exports = env => { } if (snapshot) { config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ - chunk: "vendor", + chunk: "commons", projectRoot, webpackConfig: config, targetArchs: ["arm", "arm64", "ia32"], From 1819f2851849af7a44cf2536b9ad6e5a24b5fa82 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Sun, 18 Mar 2018 09:54:58 +0200 Subject: [PATCH 13/41] fix: upgrade nativescript target to webpack 4 --- dependencyManager.js | 2 +- .../NsJsonpChunkTemplatePlugin.js | 68 ++- .../NsJsonpHotUpdateChunkTemplatePlugin.js | 27 - .../NsJsonpMainTemplatePlugin.js | 479 ++++++++++++------ nativescript-target/NsJsonpTemplatePlugin.js | 32 +- nativescript-target/index.js | 12 +- package.json | 3 +- 7 files changed, 385 insertions(+), 238 deletions(-) delete mode 100644 nativescript-target/NsJsonpHotUpdateChunkTemplatePlugin.js diff --git a/dependencyManager.js b/dependencyManager.js index 556b3ddf..e3d5727e 100644 --- a/dependencyManager.js +++ b/dependencyManager.js @@ -67,7 +67,7 @@ function getRequiredDeps(packageJson) { "raw-loader": "~0.5.1", "css-loader": "~0.28.7", "nativescript-worker-loader": "~0.8.1", - "resolve-url-loader": "~2.2.1", + "resolve-url-loader": "~2.3.0", "extract-text-webpack-plugin": "~3.0.2", "uglifyjs-webpack-plugin": "~1.2.4", }; diff --git a/nativescript-target/NsJsonpChunkTemplatePlugin.js b/nativescript-target/NsJsonpChunkTemplatePlugin.js index 2661dbb9..98c6a556 100644 --- a/nativescript-target/NsJsonpChunkTemplatePlugin.js +++ b/nativescript-target/NsJsonpChunkTemplatePlugin.js @@ -2,33 +2,47 @@ MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ -var ConcatSource = require("webpack-sources").ConcatSource; -var Template = require("webpack/lib/Template"); +"use strict"; -function JsonpChunkTemplatePlugin() { } -module.exports = JsonpChunkTemplatePlugin; - -JsonpChunkTemplatePlugin.prototype.apply = function (chunkTemplate) { +const ConcatSource = require("webpack-sources").ConcatSource; - //JSONP version - chunkTemplate.plugin("render", function (modules, chunk) { - var jsonpFunction = this.outputOptions.jsonpFunction; - var source = new ConcatSource(); - source.add(jsonpFunction + "(" + JSON.stringify(chunk.ids) + ","); - source.add(modules); - var entries = [chunk.entryModule].filter(Boolean).map(function (m) { - return m.id; +class JsonpChunkTemplatePlugin { + apply(chunkTemplate) { + chunkTemplate.hooks.render.tap( + "JsonpChunkTemplatePlugin", + (modules, chunk) => { + const jsonpFunction = chunkTemplate.outputOptions.jsonpFunction; + const globalObject = chunkTemplate.outputOptions.globalObject; + const source = new ConcatSource(); + source.add( + `(${globalObject}[${JSON.stringify(jsonpFunction)}] = ${ + globalObject + }[${JSON.stringify(jsonpFunction)}] || []).push([${JSON.stringify( + chunk.ids + )},` + ); + source.add(modules); + const entries = [chunk.entryModule].filter(Boolean).map(m => + [m.id].concat( + Array.from(chunk.groupsIterable)[0] + .chunks.filter(c => c !== chunk) + .map(c => c.id) + ) + ); + if (entries.length > 0) { + source.add(`,${JSON.stringify(entries)}`); + } + source.add("])"); + return source; + } + ); + chunkTemplate.hooks.hash.tap("JsonpChunkTemplatePlugin", hash => { + hash.update("JsonpChunkTemplatePlugin"); + hash.update("4"); + hash.update(`${chunkTemplate.outputOptions.jsonpFunction}`); + hash.update(`${chunkTemplate.outputOptions.globalObject}`); }); - if (entries.length > 0) { - source.add("," + JSON.stringify(entries)); - } - source.add(")"); - return source; - }); - chunkTemplate.plugin("hash", function (hash) { - hash.update("JsonpChunkTemplatePlugin"); - hash.update("3"); - hash.update(this.outputOptions.jsonpFunction + ""); - hash.update(this.outputOptions.library + ""); - }); -}; + } +} +module.exports = JsonpChunkTemplatePlugin; + diff --git a/nativescript-target/NsJsonpHotUpdateChunkTemplatePlugin.js b/nativescript-target/NsJsonpHotUpdateChunkTemplatePlugin.js deleted file mode 100644 index 9fd49de5..00000000 --- a/nativescript-target/NsJsonpHotUpdateChunkTemplatePlugin.js +++ /dev/null @@ -1,27 +0,0 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ -var ConcatSource = require("webpack-sources").ConcatSource; -var Template = require("webpack/lib/Template"); - -function NsJsonpHotUpdateChunkTemplatePlugin() {} -module.exports = NsJsonpHotUpdateChunkTemplatePlugin; - -//JSONP version -NsJsonpHotUpdateChunkTemplatePlugin.prototype.apply = function(hotUpdateChunkTemplate) { - hotUpdateChunkTemplate.plugin("render", function(modulesSource, modules, removedModules, hash, id) { - var jsonpFunction = this.outputOptions.hotUpdateFunction; - var source = new ConcatSource(); - source.add(jsonpFunction + "(" + JSON.stringify(id) + ","); - source.add(modulesSource); - source.add(")"); - return source; - }); - hotUpdateChunkTemplate.plugin("hash", function(hash) { - hash.update("JsonpHotUpdateChunkTemplatePlugin"); - hash.update("3"); - hash.update(this.outputOptions.hotUpdateFunction + ""); - hash.update(this.outputOptions.library + ""); - }); -}; diff --git a/nativescript-target/NsJsonpMainTemplatePlugin.js b/nativescript-target/NsJsonpMainTemplatePlugin.js index 063ec2a9..3945dedf 100644 --- a/nativescript-target/NsJsonpMainTemplatePlugin.js +++ b/nativescript-target/NsJsonpMainTemplatePlugin.js @@ -1,165 +1,324 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ -var Template = require("webpack/lib/Template"); +const Template = require("webpack/lib/Template"); +const SyncWaterfallHook = require("tapable").SyncWaterfallHook; -function JsonpMainTemplatePlugin() { } -module.exports = JsonpMainTemplatePlugin; +class NsJsonpMainTemplatePlugin { + apply(mainTemplate) { + const needChunkOnDemandLoadingCode = chunk => { + for (const chunkGroup of chunk.groupsIterable) { + if (chunkGroup.getNumberOfChildren() > 0) return true; + } + return false; + }; + const needChunkLoadingCode = chunk => { + for (const chunkGroup of chunk.groupsIterable) { + if (chunkGroup.chunks.length > 1) return true; + if (chunkGroup.getNumberOfChildren() > 0) return true; + } + return false; + }; + const needEntryDeferringCode = chunk => { + for (const chunkGroup of chunk.groupsIterable) { + if (chunkGroup.chunks.length > 1) return true; + } + return false; + }; + if (!mainTemplate.hooks.jsonpScript) { + mainTemplate.hooks.jsonpScript = new SyncWaterfallHook([ + "source", + "chunk", + "hash" + ]); + } -JsonpMainTemplatePlugin.prototype.constructor = JsonpMainTemplatePlugin; -JsonpMainTemplatePlugin.prototype.apply = function (mainTemplate) { - mainTemplate.plugin("local-vars", function (source, chunk) { - if (chunk.chunks.length > 0) { - return this.asString([ - source, - "// objects to store loaded and loading chunks", - "var installedChunks = {", - this.indent( - chunk.ids.map(function (id) { - return id + ": 0"; - }).join(",\n") - ), - "};" - ]); - } - return source; - }); - - mainTemplate.plugin("require-ensure", function (_, chunk, hash) { - var chunkFilename = this.outputOptions.chunkFilename; - var chunkMaps = chunk.getChunkMaps(); - var insertMoreModules = [ - "var moreModules = chunk.modules, chunkIds = chunk.ids;", - "for(var moduleId in moreModules) {", - this.indent(this.renderAddModule(hash, chunk, "moduleId", "moreModules[moduleId]")), - "}" - ]; + mainTemplate.hooks.localVars.tap( + "JsonpMainTemplatePlugin", + (source, chunk) => { + if (needChunkLoadingCode(chunk)) { + return Template.asString([ + source, + "", + "// object to store loaded and loading chunks", + "var installedChunks = {", + Template.indent( + chunk.ids.map(id => `${JSON.stringify(id)}: 0`).join(",\n") + ), + "};", + "", + needEntryDeferringCode(chunk) ? "var deferredModules = [];" : "" + ]); + } + return source; + } + ); + mainTemplate.hooks.requireEnsure.tap( + "JsonpMainTemplatePlugin", + (source, chunk, hash) => { - var request = this.applyPluginsWaterfall("asset-path", JSON.stringify("./" + chunkFilename), { - hash: "\" + " + this.renderCurrentHashCode(hash) + " + \"", - hashWithLength: function (length) { - return "\" + " + this.renderCurrentHashCode(hash, length) + " + \""; - }.bind(this), - chunk: { - id: "\" + chunkId + \"", - hash: "\" + " + JSON.stringify(chunkMaps.hash) + "[chunkId] + \"", - hashWithLength: function (length) { - var shortChunkHashMap = {}; - Object.keys(chunkMaps.hash).forEach(function (chunkId) { - if (typeof chunkMaps.hash[chunkId] === "string") - shortChunkHashMap[chunkId] = chunkMaps.hash[chunkId].substr(0, length); - }); - return "\" + " + JSON.stringify(shortChunkHashMap) + "[chunkId] + \""; - }, - name: "\" + (" + JSON.stringify(chunkMaps.name) + "[chunkId]||chunkId) + \"" - } - }); + const chunkFilename = mainTemplate.outputOptions.chunkFilename; + const chunkMaps = chunk.getChunkMaps(); - return this.asString([ - "// \"0\" is the signal for \"already loaded\"", - "if(installedChunks[chunkId] !== 0) {", - this.indent([ - "var chunk = require(" + request + ");" - ]), - "}", - "return Promise.resolve();" - ]); - }); - mainTemplate.plugin("require-extensions", function (source, chunk) { - if (chunk.chunks.length === 0) return source; - return this.asString([ - source, - "", - "// on error function for async loading", - this.requireFn + ".oe = function(err) { console.error(err); throw err; };" - ]); - }); - mainTemplate.plugin("bootstrap", function (source, chunk, hash) { - if (chunk.chunks.length > 0) { - var jsonpFunction = this.outputOptions.jsonpFunction; - return this.asString([ - source, - "", - "// install a JSONP callback for chunk loading", - "var parentJsonpFunction = global[" + JSON.stringify(jsonpFunction) + "];", - "global[" + JSON.stringify(jsonpFunction) + "] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {", - this.indent([ - "// add \"moreModules\" to the modules object,", - "// then flag all \"chunkIds\" as loaded and fire callback", - "var moduleId, chunkId, i = 0, resolves = [], result;", - "for(;i < chunkIds.length; i++) {", - this.indent([ - "chunkId = chunkIds[i];", - "if(installedChunks[chunkId])", - this.indent("resolves.push(installedChunks[chunkId][0]);"), - "installedChunks[chunkId] = 0;" - ]), - "}", - "for(moduleId in moreModules) {", - this.indent([ - "if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {", - this.indent(this.renderAddModule(hash, chunk, "moduleId", "moreModules[moduleId]")), - "}" - ]), - "}", - "if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);", - "while(resolves.length)", - this.indent("resolves.shift()();"), - this.entryPointInChildren(chunk) ? [ - "if(executeModules) {", - this.indent([ - "for(i=0; i < executeModules.length; i++) {", - this.indent("result = " + this.requireFn + "(" + this.requireFn + ".s = executeModules[i]);"), - "}" - ]), - "}", - "return result;", - ] : "" - ]), - "};" - ]); - } - return source; - }); - mainTemplate.plugin("hot-bootstrap", function (source, chunk, hash) { - var hotUpdateChunkFilename = this.outputOptions.hotUpdateChunkFilename; - var hotUpdateMainFilename = this.outputOptions.hotUpdateMainFilename; - var hotUpdateFunction = this.outputOptions.hotUpdateFunction; - var currentHotUpdateChunkFilename = this.applyPluginsWaterfall("asset-path", JSON.stringify(hotUpdateChunkFilename), { - hash: "\" + " + this.renderCurrentHashCode(hash) + " + \"", - hashWithLength: function (length) { - return "\" + " + this.renderCurrentHashCode(hash, length) + " + \""; - }.bind(this), - chunk: { - id: "\" + chunkId + \"" - } - }); - var currentHotUpdateMainFilename = this.applyPluginsWaterfall("asset-path", JSON.stringify(hotUpdateMainFilename), { - hash: "\" + " + this.renderCurrentHashCode(hash) + " + \"", - hashWithLength: function (length) { - return "\" + " + this.renderCurrentHashCode(hash, length) + " + \""; - }.bind(this) - }); + const request = mainTemplate.getAssetPath( + JSON.stringify(`./${chunkFilename}`), + { + hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`, + hashWithLength: length => + `" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`, + chunk: { + id: '" + chunkId + "', + hash: `" + ${JSON.stringify(chunkMaps.hash)}[chunkId] + "`, + hashWithLength(length) { + const shortChunkHashMap = Object.create(null); + for (const chunkId of Object.keys(chunkMaps.hash)) { + if (typeof chunkMaps.hash[chunkId] === "string") + shortChunkHashMap[chunkId] = chunkMaps.hash[chunkId].substr( + 0, + length + ); + } + return `" + ${JSON.stringify(shortChunkHashMap)}[chunkId] + "`; + }, + name: `" + (${JSON.stringify( + chunkMaps.name + )}[chunkId]||chunkId) + "` + } + } + ); + + return Template.asString([ + source, + "", + "// JSONP chunk loading for javascript", + "", + "var installedChunkData = installedChunks[chunkId];", + 'if(installedChunkData !== 0) { // 0 means "already installed".', + Template.indent([`var chunk = require(${request})`]), + "}" + ]); + } + ); + mainTemplate.hooks.requireExtensions.tap( + "JsonpMainTemplatePlugin", + (source, chunk) => { + if (!needChunkOnDemandLoadingCode(chunk)) return source; + + return Template.asString([ + source, + "", + "// on error function for async loading", + `${ + mainTemplate.requireFn + }.oe = function(err) { console.error(err); throw err; };` + ]); + } + ); + mainTemplate.hooks.bootstrap.tap( + "JsonpMainTemplatePlugin", + (source, chunk, hash) => { + if (needChunkLoadingCode(chunk)) { + const withDefer = needEntryDeferringCode(chunk); + return Template.asString([ + source, + "", + "// install a JSONP callback for chunk loading", + "function webpackJsonpCallback(data) {", + Template.indent([ + "var chunkIds = data[0];", + "var moreModules = data[1];", + withDefer ? "var executeModules = data[2];" : "", + '// add "moreModules" to the modules object,', + '// then flag all "chunkIds" as loaded and fire callback', + "var moduleId, chunkId, i = 0, resolves = [];", + "for(;i < chunkIds.length; i++) {", + Template.indent([ + "chunkId = chunkIds[i];", + "if(installedChunks[chunkId]) {", + Template.indent("resolves.push(installedChunks[chunkId][0]);"), + "}", + "installedChunks[chunkId] = 0;" + ]), + "}", + "for(moduleId in moreModules) {", + Template.indent([ + "if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {", + Template.indent( + mainTemplate.renderAddModule( + hash, + chunk, + "moduleId", + "moreModules[moduleId]" + ) + ), + "}" + ]), + "}", + "if(parentJsonpFunction) parentJsonpFunction(data);", + "while(resolves.length) {", + Template.indent("resolves.shift()();"), + "}", + withDefer + ? Template.asString([ + "", + "// add entry modules from loaded chunk to deferred list", + "deferredModules.push.apply(deferredModules, executeModules || []);", + "", + "// run deferred modules when all chunks ready", + "return checkDeferredModules();" + ]) + : "" + ]), + "};", + withDefer + ? Template.asString([ + "function checkDeferredModules() {", + Template.indent([ + "var result;", + "for(var i = 0; i < deferredModules.length; i++) {", + Template.indent([ + "var deferredModule = deferredModules[i];", + "var fulfilled = true;", + "for(var j = 1; j < deferredModule.length; j++) {", + Template.indent([ + "var depId = deferredModule[j];", + "if(installedChunks[depId] !== 0) fulfilled = false;" + ]), + "}", + "if(fulfilled) {", + Template.indent([ + "deferredModules.splice(i--, 1);", + "result = " + + mainTemplate.requireFn + + "(" + + mainTemplate.requireFn + + ".s = deferredModule[0]);" + ]), + "}" + ]), + "}", + "return result;" + ]), + "}" + ]) + : "" + ]); + } + return source; + } + ); + mainTemplate.hooks.beforeStartup.tap( + "JsonpMainTemplatePlugin", + (source, chunk, hash) => { + if (needChunkLoadingCode(chunk)) { + var jsonpFunction = mainTemplate.outputOptions.jsonpFunction; + var globalObject = mainTemplate.outputOptions.globalObject; + return Template.asString([ + `var jsonpArray = ${globalObject}[${JSON.stringify( + jsonpFunction + )}] = ${globalObject}[${JSON.stringify(jsonpFunction)}] || [];`, + "var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);", + "jsonpArray.push = webpackJsonpCallback;", + "jsonpArray = jsonpArray.slice();", + "for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);", + "var parentJsonpFunction = oldJsonpFunction;", + "", + source + ]); + } + return source; + } + ); + mainTemplate.hooks.startup.tap( + "JsonpMainTemplatePlugin", + (source, chunk, hash) => { + if (needEntryDeferringCode(chunk)) { + if (chunk.hasEntryModule()) { + const entries = [chunk.entryModule].filter(Boolean).map(m => + [m.id].concat( + Array.from(chunk.groupsIterable)[0] + .chunks.filter(c => c !== chunk) + .map(c => c.id) + ) + ); + return Template.asString([ + "// add entry module to deferred list", + `deferredModules.push(${entries + .map(e => JSON.stringify(e)) + .join(", ")});`, + "// run deferred modules when ready", + "return checkDeferredModules();" + ]); + } else { + return Template.asString([ + "// run deferred modules from other chunks", + "checkDeferredModules();" + ]); + } + } + return source; + } + ); + mainTemplate.hooks.hotBootstrap.tap( + "JsonpMainTemplatePlugin", + (source, chunk, hash) => { + const globalObject = mainTemplate.outputOptions.globalObject; + const hotUpdateChunkFilename = + mainTemplate.outputOptions.hotUpdateChunkFilename; + const hotUpdateMainFilename = + mainTemplate.outputOptions.hotUpdateMainFilename; + const crossOriginLoading = + mainTemplate.outputOptions.crossOriginLoading; + const hotUpdateFunction = mainTemplate.outputOptions.hotUpdateFunction; + const currentHotUpdateChunkFilename = mainTemplate.getAssetPath( + JSON.stringify(hotUpdateChunkFilename), + { + hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`, + hashWithLength: length => + `" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`, + chunk: { + id: '" + chunkId + "' + } + } + ); + const currentHotUpdateMainFilename = mainTemplate.getAssetPath( + JSON.stringify(hotUpdateMainFilename), + { + hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`, + hashWithLength: length => + `" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "` + } + ); + const runtimeSource = Template.getFunctionContent( + require("./JsonpMainTemplate.runtime.js") + ) + .replace(/\/\/\$semicolon/g, ";") + .replace(/\$require\$/g, mainTemplate.requireFn) + .replace( + /\$crossOriginLoading\$/g, + crossOriginLoading + ? `script.crossOrigin = ${JSON.stringify(crossOriginLoading)}` + : "" + ) + .replace(/\$hotMainFilename\$/g, currentHotUpdateMainFilename) + .replace(/\$hotChunkFilename\$/g, currentHotUpdateChunkFilename) + .replace(/\$hash\$/g, JSON.stringify(hash)); + return `${source} +function hotDisposeChunk(chunkId) { + delete installedChunks[chunkId]; +} +var parentHotUpdateCallback = ${globalObject}[${JSON.stringify( + hotUpdateFunction + )}]; +${globalObject}[${JSON.stringify(hotUpdateFunction)}] = ${runtimeSource}`; + } + ); + mainTemplate.hooks.hash.tap("JsonpMainTemplatePlugin", hash => { + hash.update("jsonp"); + hash.update("5"); + hash.update(`${mainTemplate.outputOptions.globalObject}`); + hash.update(`${mainTemplate.outputOptions.chunkFilename}`); + hash.update(`${mainTemplate.outputOptions.jsonpFunction}`); + hash.update(`${mainTemplate.outputOptions.hotUpdateFunction}`); + }); + } +} +module.exports = NsJsonpMainTemplatePlugin; - return source + "\n" + - "function hotDisposeChunk(chunkId) {\n" + - "\tdelete installedChunks[chunkId];\n" + - "}\n" + - "var parentHotUpdateCallback = this[" + JSON.stringify(hotUpdateFunction) + "];\n" + - "this[" + JSON.stringify(hotUpdateFunction) + "] = " + Template.getFunctionContent(require("./JsonpMainTemplate.runtime.js")) - .replace(/\/\/\$semicolon/g, ";") - .replace(/\$require\$/g, this.requireFn) - .replace(/\$hotMainFilename\$/g, currentHotUpdateMainFilename) - .replace(/\$hotChunkFilename\$/g, currentHotUpdateChunkFilename) - .replace(/\$hash\$/g, JSON.stringify(hash)); - }); - mainTemplate.plugin("hash", function (hash) { - hash.update("jsonp"); - hash.update("4"); - hash.update(this.outputOptions.filename + ""); - hash.update(this.outputOptions.chunkFilename + ""); - hash.update(this.outputOptions.jsonpFunction + ""); - hash.update(this.outputOptions.hotUpdateFunction + ""); - }); -}; diff --git a/nativescript-target/NsJsonpTemplatePlugin.js b/nativescript-target/NsJsonpTemplatePlugin.js index 0841a3a8..18ee9cd7 100644 --- a/nativescript-target/NsJsonpTemplatePlugin.js +++ b/nativescript-target/NsJsonpTemplatePlugin.js @@ -1,17 +1,17 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ -var NsJsonpMainTemplatePlugin = require("./NsJsonpMainTemplatePlugin"); -var NsJsonpChunkTemplatePlugin = require("./NsJsonpChunkTemplatePlugin"); -var NsJsonpHotUpdateChunkTemplatePlugin = require("./NsJsonpHotUpdateChunkTemplatePlugin"); +const NsJsonpMainTemplatePlugin = require("./NsJsonpMainTemplatePlugin"); +const JsonpChunkTemplatePlugin = require("webpack/lib/web/JsonpChunkTemplatePlugin"); +const JsonpHotUpdateChunkTemplatePlugin = require("webpack/lib/web/JsonpHotUpdateChunkTemplatePlugin"); -function JsonpTemplatePlugin() {} -module.exports = JsonpTemplatePlugin; -JsonpTemplatePlugin.prototype.apply = function(compiler) { - compiler.plugin("this-compilation", function(compilation) { - compilation.mainTemplate.apply(new NsJsonpMainTemplatePlugin()); - compilation.chunkTemplate.apply(new NsJsonpChunkTemplatePlugin()); - compilation.hotUpdateChunkTemplate.apply(new NsJsonpHotUpdateChunkTemplatePlugin()); - }); -}; +class NsJsonpTemplatePlugin { + apply(compiler) { + compiler.hooks.thisCompilation.tap("NsJsonpTemplatePlugin", compilation => { + new NsJsonpMainTemplatePlugin().apply(compilation.mainTemplate); + new JsonpChunkTemplatePlugin().apply(compilation.chunkTemplate); + new JsonpHotUpdateChunkTemplatePlugin().apply( + compilation.hotUpdateChunkTemplate + ); + }) + } +} + +module.exports = NsJsonpTemplatePlugin; diff --git a/nativescript-target/index.js b/nativescript-target/index.js index 5779c13d..3e483b33 100644 --- a/nativescript-target/index.js +++ b/nativescript-target/index.js @@ -1,13 +1,13 @@ module.exports = function nativescriptTarget(compiler) { - var options = this; - var webpackLib = "webpack/lib"; + const options = this; + const webpackLib = "webpack/lib"; // Custom template plugin - var NsJsonpTemplatePlugin = require("./NsJsonpTemplatePlugin"); + const NsJsonpTemplatePlugin = require("./NsJsonpTemplatePlugin"); - var FunctionModulePlugin = require(webpackLib + "/FunctionModulePlugin"); - var NodeSourcePlugin = require(webpackLib + "/node/NodeSourcePlugin"); - var LoaderTargetPlugin = require(webpackLib + "/LoaderTargetPlugin"); + const FunctionModulePlugin = require(webpackLib + "/FunctionModulePlugin"); + const NodeSourcePlugin = require(webpackLib + "/node/NodeSourcePlugin"); + const LoaderTargetPlugin = require(webpackLib + "/LoaderTargetPlugin"); compiler.apply( new NsJsonpTemplatePlugin(options.output), diff --git a/package.json b/package.json index b03ae04f..c0e5a4b2 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,8 @@ "request": "2.83.0", "schema-utils": "0.4.3", "semver": "5.4.1", - "shelljs": "0.6.0" + "shelljs": "0.6.0", + "tapable": "^1.0.0" }, "devDependencies": { "@ngtools/webpack": "~1.9.0", From 0f6ad110a9359bfddc34c63e182ba895215adeec Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Thu, 22 Mar 2018 14:14:44 +0200 Subject: [PATCH 14/41] fix: fix common chunk for angular --- templates/webpack.angular.js | 49 ++++++++++++++++++++------------- templates/webpack.javascript.js | 19 +++++++------ templates/webpack.typescript.js | 19 +++++++------ 3 files changed, 50 insertions(+), 37 deletions(-) diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index 085762b6..4afc40c2 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -43,15 +43,6 @@ module.exports = env => { const config = { mode: "development", - devtool: "none", - optimization: { - splitChunks: { - chunks: "all", - cacheGroups: { - commons: { name: "commons" } - } - } - }, context: appFullPath, watchOptions: { ignored: [ @@ -71,6 +62,7 @@ module.exports = env => { path: dist, libraryTarget: "commonjs2", filename: "[name].js", + globalObject: "global", }, resolve: { extensions: [".ts", ".js", ".scss", ".css"], @@ -96,6 +88,23 @@ module.exports = env => { "setImmediate": false, "fs": "empty", }, + devtool: "none", + optimization: { + splitChunks: { + chunks: "all", + cacheGroups: { + vendors: false, + vendor: { + name: "commons", + chunks: "initial", + test: (module, chunks) => { + const moduleName = module.nameForCondition ? module.nameForCondition() : ''; + return /[\\/]node_modules[\\/]/.test(moduleName); + }, + }, + } + }, + }, module: { rules: [ { test: /\.html$|\.xml$/, use: "raw-loader" }, @@ -121,10 +130,12 @@ module.exports = env => { { test: /\.scss$/, exclude: /[\/|\\]app\.scss$/, use: ["raw-loader", "resolve-url-loader", "sass-loader"] }, // Compile TypeScript files with ahead-of-time compiler. - { test: /.ts$/, use: [ - "nativescript-dev-webpack/moduleid-compat-loader", - { loader: "@ngtools/webpack", options: ngToolsWebpackOptions }, - ]}, + { + test: /.ts$/, use: [ + "nativescript-dev-webpack/moduleid-compat-loader", + { loader: "@ngtools/webpack", options: ngToolsWebpackOptions }, + ] + }, ], }, plugins: [ @@ -133,14 +144,14 @@ module.exports = env => { "global.TNS_WEBPACK": "true", }), // Remove all files from the out dir. - new CleanWebpackPlugin([ `${dist}/**/*` ]), + new CleanWebpackPlugin([`${dist}/**/*`]), // Copy native app resources to out dir. new CopyWebpackPlugin([ - { - from: `${appResourcesFullPath}/${appResourcesPlatformDir}`, - to: `${dist}/App_Resources/${appResourcesPlatformDir}`, - context: projectRoot - }, + { + from: `${appResourcesFullPath}/${appResourcesPlatformDir}`, + to: `${dist}/App_Resources/${appResourcesPlatformDir}`, + context: projectRoot + }, ]), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index 221d1d88..e1e432ed 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -41,15 +41,6 @@ module.exports = env => { const config = { mode: "development", - devtool: "none", - optimization: { - splitChunks: { - chunks: "all", - cacheGroups: { - commons: { name: "commons" } - } - } - }, context: appFullPath, watchOptions: { ignored: [ @@ -67,6 +58,7 @@ module.exports = env => { path: dist, libraryTarget: "commonjs2", filename: "[name].js", + globalObject: "global", }, resolve: { extensions: [".js", ".scss", ".css"], @@ -92,6 +84,15 @@ module.exports = env => { "setImmediate": false, "fs": "empty", }, + devtool: "none", + optimization: { + splitChunks: { + chunks: "all", + cacheGroups: { + commons: { name: "commons" } + } + } + }, module: { rules: [ { test: /\.(html|xml)$/, use: "raw-loader" }, diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index 6e6e0334..e27665b8 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -41,15 +41,6 @@ module.exports = env => { const config = { mode: "development", - devtool: "none", - optimization: { - splitChunks: { - chunks: "all", - cacheGroups: { - commons: { name: "commons" } - } - } - }, context: appFullPath, watchOptions: { ignored: [ @@ -67,6 +58,7 @@ module.exports = env => { path: dist, libraryTarget: "commonjs2", filename: "[name].js", + globalObject: "global", }, resolve: { extensions: [".ts", ".js", ".scss", ".css"], @@ -92,6 +84,15 @@ module.exports = env => { "setImmediate": false, "fs": "empty", }, + devtool: "none", + optimization: { + splitChunks: { + chunks: "all", + cacheGroups: { + commons: { name: "commons" } + } + } + }, module: { rules: [ { test: /\.(html|xml)$/, use: "raw-loader" }, From 50604e346e82a25fc740d2bc1201f1ba82321ef4 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Thu, 22 Mar 2018 20:22:41 +0200 Subject: [PATCH 15/41] refactor: remove obsolete loaders --- platform-css-loader.js | 18 ------------------ tns-aot-loader.js | 16 ---------------- 2 files changed, 34 deletions(-) delete mode 100644 platform-css-loader.js delete mode 100644 tns-aot-loader.js diff --git a/platform-css-loader.js b/platform-css-loader.js deleted file mode 100644 index 0c58f1ca..00000000 --- a/platform-css-loader.js +++ /dev/null @@ -1,18 +0,0 @@ -var cssSuffixMatcher = /(@import.*)\.css/g; -var themeMatcher = /(@import[^'"]*)(['"]~?\/?)nativescript-theme-core(.*)/g; - -module.exports = function(source, sourcemap) { - var newSource = source.replace(cssSuffixMatcher, function (fullMatch, importPrefix) { - return importPrefix; - }).replace(themeMatcher, function(fullMatch, importPrefix, pathStart, rest) { - var quote = pathStart[0]; - return importPrefix + quote + "~nativescript-theme-core" + rest; - }); - - // Support for tests - if (this.callback) { - this.callback(null, newSource, sourcemap); - } else { - return newSource; - } -}; diff --git a/tns-aot-loader.js b/tns-aot-loader.js deleted file mode 100644 index 3d9d116b..00000000 --- a/tns-aot-loader.js +++ /dev/null @@ -1,16 +0,0 @@ -function fixRelativeImports(fileName, source) { - let result = source; - - result = result.replace(/(\.\.\/)+platform\'/g, 'platform\''); - result = result.replace(/(\.\.\/)+ui\/frame\'/g, 'ui/frame\''); - result = result.replace(/(\.\.\/)+ui\/page\'/g, 'ui/page\''); - - return result; -} - - -module.exports = function (source, map) { - this.cacheable(); - var resultSource = fixRelativeImports(this.resource, source); - this.callback(null, resultSource, map); -}; \ No newline at end of file From c0d18674076ec72cd99ae2ed84b8190aefcd5a64 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Thu, 22 Mar 2018 21:24:01 +0200 Subject: [PATCH 16/41] wip --- loader.js | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 loader.js diff --git a/loader.js b/loader.js new file mode 100644 index 00000000..ecdb19f3 --- /dev/null +++ b/loader.js @@ -0,0 +1,8 @@ +module.exports = function(source) { + this.cacheable(); + const { modules } = this.query; + const imports = modules.map(m => `require("${m}");`).join("\n"); + const augmentedSource = `${imports}\n${source}`; + + this.callback(null, augmentedSource); +}; From 8d99b38ffa7e2b0abcb39eebf367595f689ba3ef Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Wed, 28 Mar 2018 17:19:25 +0300 Subject: [PATCH 17/41] chore: bump webpack version to 4.3 --- dependencyManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencyManager.js b/dependencyManager.js index e3d5727e..a8102ac5 100644 --- a/dependencyManager.js +++ b/dependencyManager.js @@ -58,7 +58,7 @@ function addDependency(deps, name, version, force) { function getRequiredDeps(packageJson) { const deps = { - "webpack": "~4.1.0", + "webpack": "~4.3.0", "webpack-cli": "~2.0.12", "webpack-bundle-analyzer": "^2.9.1", "webpack-sources": "~1.1.0", From d7ef95b14318973a305fff7c39f118ebc8d21e7d Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Wed, 28 Mar 2018 17:39:52 +0300 Subject: [PATCH 18/41] feat: add loader for registering android app components --- loader.js => android-app-components-loader.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) rename loader.js => android-app-components-loader.js (62%) diff --git a/loader.js b/android-app-components-loader.js similarity index 62% rename from loader.js rename to android-app-components-loader.js index ecdb19f3..5e2ecfd3 100644 --- a/loader.js +++ b/android-app-components-loader.js @@ -2,7 +2,13 @@ module.exports = function(source) { this.cacheable(); const { modules } = this.query; const imports = modules.map(m => `require("${m}");`).join("\n"); - const augmentedSource = `${imports}\n${source}`; + const augmentedSource = ` + if (!global["__snapshot"]) { + ${imports} + } + + ${source} + `; this.callback(null, augmentedSource); }; From 9ccf5d92f9e77c64f424b06bc6f22d322b1afab6 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Wed, 28 Mar 2018 18:01:04 +0300 Subject: [PATCH 19/41] chore: update package dependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c0e5a4b2..a68ee6e5 100644 --- a/package.json +++ b/package.json @@ -71,9 +71,9 @@ "tapable": "^1.0.0" }, "devDependencies": { - "@ngtools/webpack": "~1.9.0", + "@ngtools/webpack": "~6.0.0-beta.5", "@types/node": "^8.0.0", "source-map-support": "^0.5.0", - "typescript": "^2.6.1" + "typescript": "~2.7.2" } } From c86df1235df2046a5047a9068ea0d915a14b85c9 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Wed, 28 Mar 2018 18:53:31 +0300 Subject: [PATCH 20/41] feat: update snapshot plugin for webpack 4 - Remove tns-java-classes generation. - Concatenate multiple chunks in order to generate snapshot. --- plugins/NativeScriptSnapshotPlugin/index.js | 62 +++++++---------- .../NativeScriptSnapshotPlugin/options.json | 18 ++--- ...oject-snapshot-generator-cli-ags-parser.js | 6 -- .../android/project-snapshot-generator.js | 36 ++-------- .../bundle-preamble.js | 6 +- snapshot/android/snapshot-generator.js | 11 ++-- .../android/tns-java-classes-generator.js | 66 ------------------- templates/vendor-platform.android.ts | 9 --- templates/vendor-platform.ios.ts | 3 - 9 files changed, 43 insertions(+), 174 deletions(-) delete mode 100644 snapshot/android/tns-java-classes-generator.js delete mode 100644 templates/vendor-platform.android.ts delete mode 100644 templates/vendor-platform.ios.ts diff --git a/plugins/NativeScriptSnapshotPlugin/index.js b/plugins/NativeScriptSnapshotPlugin/index.js index 54d17047..de36bff0 100644 --- a/plugins/NativeScriptSnapshotPlugin/index.js +++ b/plugins/NativeScriptSnapshotPlugin/index.js @@ -9,27 +9,23 @@ const schema = require("./options.json"); exports.NativeScriptSnapshotPlugin = (function() { function NativeScriptSnapshotPlugin(options) { NativeScriptSnapshotPlugin.validateSchema(options); + if (options.chunk) { + options.chunks = options.chunks || []; + options.chunks.push(options.chunk); + } - ProjectSnapshotGenerator.call(this, options); // Call the parent constructor + ProjectSnapshotGenerator.call(this, options); if (this.options.webpackConfig) { if (this.options.webpackConfig.output && this.options.webpackConfig.output.libraryTarget) { this.options.webpackConfig.output.libraryTarget = undefined; } - - if (this.options.webpackConfig.entry) { - if (typeof this.options.webpackConfig.entry === "string" || - this.options.webpackConfig.entry instanceof Array) - this.options.webpackConfig.entry = { bundle: this.options.webpackConfig.entry }; - } - - this.options.webpackConfig.entry["tns-java-classes"] = this.getTnsJavaClassesBuildPath(); } } NativeScriptSnapshotPlugin.validateSchema = function(options) { - if (!options.chunk) { - const error = NativeScriptSnapshotPlugin.extendError({ message: `No chunk specified!` }); + if (!options.chunk && !options.chunks) { + const error = NativeScriptSnapshotPlugin.extendError({ message: `No chunks specified!` }); throw error; } @@ -44,56 +40,44 @@ exports.NativeScriptSnapshotPlugin = (function() { NativeScriptSnapshotPlugin.prototype = Object.create(ProjectSnapshotGenerator.prototype); NativeScriptSnapshotPlugin.prototype.constructor = NativeScriptSnapshotPlugin; - NativeScriptSnapshotPlugin.prototype.getTnsJavaClassesBuildPath = function () { - return resolve(this.getBuildPath(), "../tns-java-classes.js"); - } - - NativeScriptSnapshotPlugin.prototype.generate = function (webpackChunk) { + NativeScriptSnapshotPlugin.prototype.generate = function (webpackChunks) { const options = this.options; - - const inputFile = join(options.webpackConfig.output.path, webpackChunk.files[0]); - - console.log(`\n Snapshotting bundle at ${inputFile}`); + const inputFiles = webpackChunks.map(chunk => join(options.webpackConfig.output.path, chunk.files[0])); + console.log(`\n Snapshotting bundle from ${inputFiles}`); const preparedAppRootPath = resolveAndroidAppPath(this.options.projectRoot); const preprocessedInputFile = join(preparedAppRootPath, "_embedded_script_.js"); return ProjectSnapshotGenerator.prototype.generate.call(this, { - inputFile, + inputFiles, preprocessedInputFile, targetArchs: options.targetArchs, useLibs: options.useLibs, androidNdkPath: options.androidNdkPath, - tnsJavaClassesPath: join(preparedAppRootPath, "tns-java-classes.js") }).then(() => { - // Make the original file empty - if (inputFile !== preprocessedInputFile) { - closeSync(openSync(inputFile, "w")); // truncates the input file content - } + // Make the original files empty + inputFiles.forEach(inputFile => + closeSync(openSync(inputFile, "w")) // truncates the input file content + ); }); } NativeScriptSnapshotPlugin.prototype.apply = function (compiler) { const options = this.options; - // Generate tns-java-classes.js file - debugger; - ProjectSnapshotGenerator.prototype.generateTnsJavaClassesFile.call(this, { - output: this.getTnsJavaClassesBuildPath(), - options: options.tnsJavaClassesOptions - }); - - // Generate snapshots compiler.plugin("after-emit", function (compilation, callback) { - debugger; - const chunkToSnapshot = compilation.chunks.find(chunk => chunk.name == options.chunk); - if (!chunkToSnapshot) { - const error = NativeScriptSnapshotPlugin.extendError({ message: `No chunk named '${options.chunk}' found.` }); + const chunksToSnapshot = options.chunks + .map(name => ({ name, chunk: compilation.chunks.find(chunk => chunk.name === name) })); + const unexistingChunks = chunksToSnapshot.filter(pair => !pair.chunk); + + if (unexistingChunks.length) { + const message = `The following chunks does not exist: ` + unexistingChunks.map(pair => pair.name).join(", "); + const error = NativeScriptSnapshotPlugin.extendError({ message }); compilation.errors.push(error); return callback(); } - this.generate(chunkToSnapshot) + this.generate(chunksToSnapshot.map(pair => pair.chunk)) .then(() => { console.log("Successfully generated snapshots!"); return callback(); diff --git a/plugins/NativeScriptSnapshotPlugin/options.json b/plugins/NativeScriptSnapshotPlugin/options.json index fb1b0560..64130006 100644 --- a/plugins/NativeScriptSnapshotPlugin/options.json +++ b/plugins/NativeScriptSnapshotPlugin/options.json @@ -4,6 +4,12 @@ "chunk": { "type": "string" }, + "chunks": { + "type": "array", + "items": { + "type": "string" + } + }, "projectRoot": { "type": "string" }, @@ -11,18 +17,6 @@ "targetArchs": { "type": "array" }, - "tnsJavaClassesOptions": { - "additionalProperties": false, - "type": "object", - "properties": { - "modules": { - "type": "array" - }, - "packages": { - "type": "array" - } - } - }, "useLibs": { "type": "boolean" } diff --git a/snapshot/android/project-snapshot-generator-cli-ags-parser.js b/snapshot/android/project-snapshot-generator-cli-ags-parser.js index 5207e075..76af75b1 100644 --- a/snapshot/android/project-snapshot-generator-cli-ags-parser.js +++ b/snapshot/android/project-snapshot-generator-cli-ags-parser.js @@ -4,12 +4,6 @@ module.exports = function parseProjectSnapshotGeneratorArgs() { if (result.targetArchs) { result.targetArchs = parseStringArray(result.targetArchs); } - if (result.tnsJavaClassesOptions && result.tnsJavaClassesOptions.packages !== undefined) { - result.tnsJavaClassesOptions.packages = parseStringArray(result.tnsJavaClassesOptions.packages); - } - if (result.tnsJavaClassesOptions && result.tnsJavaClassesOptions.modules !== undefined) { - result.tnsJavaClassesOptions.modules = parseStringArray(result.tnsJavaClassesOptions.modules); - } if (result.useLibs !== undefined) { result.useLibs = parseBool(result.useLibs); diff --git a/snapshot/android/project-snapshot-generator.js b/snapshot/android/project-snapshot-generator.js index a856e0fa..31813e87 100644 --- a/snapshot/android/project-snapshot-generator.js +++ b/snapshot/android/project-snapshot-generator.js @@ -5,7 +5,6 @@ const shelljs = require("shelljs"); const semver = require("semver"); const SnapshotGenerator = require("./snapshot-generator"); -const TnsJavaClassesGenerator = require("./tns-java-classes-generator"); const { CONSTANTS, createDirectory, @@ -89,11 +88,6 @@ ProjectSnapshotGenerator.installSnapshotArtefacts = function (projectRoot) { shelljs.mkdir("-p", configDestinationPath); shelljs.cp(join(buildPath, "include.gradle"), join(configDestinationPath, "include.gradle")); - // Copy tns-java-classes.js - if (shelljs.test("-e", join(buildPath, "tns-java-classes.js"))) { - shelljs.cp(join(buildPath, "tns-java-classes.js"), join(appPath, "tns-java-classes.js")); - } - if (shelljs.test("-e", join(buildPath, "ndk-build/libs"))) { // useLibs = true const libsDestinationPath = join(platformPath, "src", SnapshotGenerator.SNAPSHOT_PACKAGE_NANE, "jniLibs"); @@ -200,15 +194,6 @@ ProjectSnapshotGenerator.prototype.validateAndroidRuntimeVersion = function () { } } -ProjectSnapshotGenerator.prototype.generateTnsJavaClassesFile = function (generationOptions) { - const tnsJavaClassesGenerator = new TnsJavaClassesGenerator(); - return tnsJavaClassesGenerator.generate({ - projectRoot: this.options.projectRoot, - output: generationOptions.output, - options: generationOptions.options - }); -} - ProjectSnapshotGenerator.prototype.generate = function (generationOptions) { generationOptions = generationOptions || {}; @@ -219,17 +204,6 @@ ProjectSnapshotGenerator.prototype.generate = function (generationOptions) { shelljs.rm("-rf", this.getBuildPath()); shelljs.mkdir("-p", this.getBuildPath()); - // Generate tns-java-classes.js if needed - const tnsJavaClassesDestination = join(this.getBuildPath(), "tns-java-classes.js"); - if (generationOptions.tnsJavaClassesPath) { - if (generationOptions.tnsJavaClassesPath != tnsJavaClassesDestination) { - shelljs.cp(generationOptions.tnsJavaClassesPath, tnsJavaClassesDestination); - } - } - else { - this.generateTnsJavaClassesFile({ output: tnsJavaClassesDestination, options: generationOptions.tnsJavaClassesOptions }); - } - const snapshotToolsPath = resolveRelativePath(generationOptions.snapshotToolsPath) || CONSTANTS.SNAPSHOT_TMP_DIR; const androidNdkPath = generationOptions.androidNdkPath || process.env.ANDROID_NDK_HOME; @@ -246,15 +220,17 @@ ProjectSnapshotGenerator.prototype.generate = function (generationOptions) { throw new Error(noV8VersionFoundMessage); } - return generator.generate({ + const options = { snapshotToolsPath, - inputFile: generationOptions.inputFile || join(this.options.projectRoot, "__snapshot.js"), targetArchs: generationOptions.targetArchs || ["arm", "arm64", "ia32"], v8Version: generationOptions.v8Version || v8Version, preprocessedInputFile: generationOptions.preprocessedInputFile, useLibs: generationOptions.useLibs || false, - androidNdkPath - }).then(() => { + inputFiles: generationOptions.inputFiles || [join(this.options.projectRoot, "__snapshot.js")], + androidNdkPath, + }; + + return generator.generate(options).then(() => { console.log("Snapshots build finished succesfully!"); if (generationOptions.install) { diff --git a/snapshot/android/snapshot-generator-tools/bundle-preamble.js b/snapshot/android/snapshot-generator-tools/bundle-preamble.js index 910f5330..46e171f5 100644 --- a/snapshot/android/snapshot-generator-tools/bundle-preamble.js +++ b/snapshot/android/snapshot-generator-tools/bundle-preamble.js @@ -20,9 +20,9 @@ Object.defineProperty(global, "__snapshot", { global.__requireOverride = (function() { return function(moduleId, dirname) { /* - The android runtime laods in advance all JS modules that contain a native class successor generated statically at build time. - In case of snapshot this file always is the bundled one. Since it is snapshoted it is already laoded in the heap and is not meant - to be required. The tns-java-classes.js file is responsible for actually executing the modules containing native java classes. + The android runtime loads in advance all JS modules that contain a native class successor generated statically at build time. + In case of snapshot this file always is the bundled one. Since it is snapshoted it is already loaded in the heap and is not meant + to be required. The main entry file (bundle.js) is responsible for actually executing the modules containing native java classes. */ var resolvedModuleId = moduleId.replace(/^\.\/tns_modules\//, ""); if (resolvedModuleId === './_embedded_script_.js') { diff --git a/snapshot/android/snapshot-generator.js b/snapshot/android/snapshot-generator.js index a318c583..2f699a48 100644 --- a/snapshot/android/snapshot-generator.js +++ b/snapshot/android/snapshot-generator.js @@ -42,11 +42,13 @@ module.exports = SnapshotGenerator; SnapshotGenerator.SNAPSHOT_PACKAGE_NANE = "nativescript-android-snapshot"; -SnapshotGenerator.prototype.preprocessInputFile = function(inputFile, outputFile) { +SnapshotGenerator.prototype.preprocessInputFiles = function(inputFiles, outputFile) { // Make some modifcations on the original bundle and save it on the specified path const bundlePreambleContent = fs.readFileSync(BUNDLE_PREAMBLE_PATH, "utf8"); const bundleEndingContent = fs.readFileSync(BUNDLE_ENDING_PATH, "utf8"); - const snapshotFileContent = bundlePreambleContent + "\n" + fs.readFileSync(inputFile, "utf8") + "\n" + bundleEndingContent; + + const inputFilesContent = inputFiles.map(file => fs.readFileSync(file, "utf8")).join("\n"); + const snapshotFileContent = bundlePreambleContent + "\n" + inputFilesContent + "\n" + bundleEndingContent; fs.writeFileSync(outputFile, snapshotFileContent, { encoding: "utf8" }); } @@ -151,14 +153,11 @@ SnapshotGenerator.prototype.buildIncludeGradle = function() { SnapshotGenerator.prototype.generate = function(options) { // Arguments validation options = options || {}; - if (!options.inputFile) { throw new Error("inputFile option is not specified."); } - if (!shelljs.test("-e", options.inputFile)) { throw new Error("Can't find V8 snapshot input file: '" + options.inputFile + "'."); } - if (!options.targetArchs || options.targetArchs.length == 0) { throw new Error("No target archs specified."); } if (!options.v8Version) { throw new Error("No v8 version specified."); } if (!options.snapshotToolsPath) { throw new Error("snapshotToolsPath option is not specified."); } const preprocessedInputFile = options.preprocessedInputFile || join(this.buildPath, "inputFile.preprocessed"); - this.preprocessInputFile(options.inputFile, preprocessedInputFile); + this.preprocessInputFiles(options.inputFiles, preprocessedInputFile); // generates the actual .blob and .c files return this.runMksnapshotTool( diff --git a/snapshot/android/tns-java-classes-generator.js b/snapshot/android/tns-java-classes-generator.js deleted file mode 100644 index 296a806e..00000000 --- a/snapshot/android/tns-java-classes-generator.js +++ /dev/null @@ -1,66 +0,0 @@ -const fs = require("fs"); -const { join, dirname } = require("path"); -const shelljs = require("shelljs"); - -function TnsJavaClassesGenerator() {} -module.exports = TnsJavaClassesGenerator; - -TnsJavaClassesGenerator.prototype.generate = function(generationOptions) { - // Arguments validation - generationOptions = generationOptions || {}; - if (!generationOptions.projectRoot) { throw new Error("No projectRoot specified."); } - var initialSettings = generationOptions.options || { modules: [], packages: [] }; - initialSettings.modules = initialSettings.modules || []; - initialSettings.packages = initialSettings.packages || []; - - const packageJsonPath = join(generationOptions.projectRoot, "package.json"); - const nodeModulesPath = join(generationOptions.projectRoot, "node_modules"); - - /* - "tns-java-classes": { - "modules": ["packageX/moduleX", "./app/moduleY"], - "packages": ["package1", "package2"] - } - */ - var tnsJavaClassesSettings = this.getTnsJavaClassesSettings(packageJsonPath); - Array.prototype.push.apply(initialSettings.modules, tnsJavaClassesSettings.modules); - Array.prototype.push.apply(initialSettings.packages, tnsJavaClassesSettings.packages); - - var nodeModules = fs.readdirSync(nodeModulesPath).filter((moduleName) => initialSettings.packages.indexOf(moduleName) >= 0); - for(var i = 0; i < nodeModules.length; i++) { - var moduleName = nodeModules[i]; - var modulePackageJsonPath = join(nodeModulesPath, moduleName, "package.json"); - var moduleTnsJavaClassesSettings = this.getTnsJavaClassesSettings(modulePackageJsonPath); - // Backward compatibilty with modules 3.0.1 and below - if (moduleName == "tns-core-modules" && moduleTnsJavaClassesSettings.modules.length == 0) { - moduleTnsJavaClassesSettings = { modules: ["ui/frame/activity", "ui/frame/fragment"] }; - } - Array.prototype.push.apply(initialSettings.modules, moduleTnsJavaClassesSettings.modules); - } - - // Generate the file - var tnsJavaClassesFileContent = initialSettings.modules.map(moduleName => "require(\"" + moduleName + "\");").join("\n"); - if (generationOptions.output) { - shelljs.mkdir("-p", dirname(generationOptions.output)); - if (generationOptions.outputAppend) { - var currentFileContent = shelljs.test("-e", generationOptions.output) ? fs.readFileSync(generationOptions.output, "utf8") : ""; - tnsJavaClassesFileContent = currentFileContent + tnsJavaClassesFileContent; - } - fs.writeFileSync(generationOptions.output, tnsJavaClassesFileContent, { encoding: "utf8" }); - } - return tnsJavaClassesFileContent; -} - -TnsJavaClassesGenerator.prototype.getTnsJavaClassesSettings = function(packageJsonPath) { - var packageJson = shelljs.test("-e", packageJsonPath) ? JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) : {}; - if (packageJson.snapshot && - packageJson.snapshot.android && - packageJson.snapshot.android["tns-java-classes"]) { - var extendedJavaClasses = packageJson.snapshot.android["tns-java-classes"]; - extendedJavaClasses.modules = extendedJavaClasses.modules || []; - extendedJavaClasses.packages = extendedJavaClasses.packages || []; - return extendedJavaClasses; - } - - return { modules: [], packages: [] }; -} \ No newline at end of file diff --git a/templates/vendor-platform.android.ts b/templates/vendor-platform.android.ts deleted file mode 100644 index 719f2649..00000000 --- a/templates/vendor-platform.android.ts +++ /dev/null @@ -1,9 +0,0 @@ -require("application"); -if (!global["__snapshot"]) { - // In case snapshot generation is enabled these modules will get into the bundle - // but will not be required/evaluated. - // The snapshot webpack plugin will add them to the tns-java-classes.js bundle file. - // This way, they will be evaluated on app start as early as possible. - require("ui/frame"); - require("ui/frame/activity"); -} diff --git a/templates/vendor-platform.ios.ts b/templates/vendor-platform.ios.ts deleted file mode 100644 index 5ce49d81..00000000 --- a/templates/vendor-platform.ios.ts +++ /dev/null @@ -1,3 +0,0 @@ -// There is a bug in angular: https://github.com/angular/angular-cli/pull/8589/files -// Legendary stuff, its webpack plugin pretty much doesn't work with empty TypeScript files in v1.8.3 -void 0; From 46782c447ae193453c16a53f268b5b5aee8361fc Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Wed, 28 Mar 2018 19:10:58 +0300 Subject: [PATCH 21/41] refactor: update webpack config templates --- projectFilesManager.js | 5 +-- templates/vendor.angular.ts | 2 -- templates/vendor.nativescript.ts | 2 -- templates/webpack.angular.js | 52 +++++++++++++++++++++++--------- templates/webpack.javascript.js | 40 +++++++++++++++++++++--- templates/webpack.typescript.js | 47 ++++++++++++++++++++++++----- 6 files changed, 114 insertions(+), 34 deletions(-) diff --git a/projectFilesManager.js b/projectFilesManager.js index 1398c26b..d77054dc 100644 --- a/projectFilesManager.js +++ b/projectFilesManager.js @@ -95,10 +95,7 @@ function getProjectTemplates(projectDir) { } function getAppTemplates(projectDir, appDir) { - const templates = { - "vendor-platform.android.ts": tsOrJs(projectDir, "vendor-platform.android"), - "vendor-platform.ios.ts": tsOrJs(projectDir, "vendor-platform.ios"), - }; + const templates = {}; if (isAngular({projectDir})) { templates["vendor.angular.ts"] = tsOrJs(projectDir, "vendor"); diff --git a/templates/vendor.angular.ts b/templates/vendor.angular.ts index 4526eca9..fd29170f 100644 --- a/templates/vendor.angular.ts +++ b/templates/vendor.angular.ts @@ -5,8 +5,6 @@ const appCssContext = require.context("~/", false, /^\.\/app\.(css|scss|less|sas global.registerWebpackModules(appCssContext); application.loadAppCss(); -require("./vendor-platform"); - require("reflect-metadata"); require("@angular/platform-browser"); require("@angular/core"); diff --git a/templates/vendor.nativescript.ts b/templates/vendor.nativescript.ts index 8a381374..b35ccd2a 100644 --- a/templates/vendor.nativescript.ts +++ b/templates/vendor.nativescript.ts @@ -5,6 +5,4 @@ const appCssContext = require.context("~/", false, /^\.\/app\.(css|scss|less|sas global.registerWebpackModules(appCssContext); application.loadAppCss(); -require("./vendor-platform"); - require("bundle-entry-points"); diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index 4afc40c2..5406f4d5 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -41,6 +41,12 @@ module.exports = env => { const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); + const entryModule = aot ? + nsWebpack.getAotEntryModule(appFullPath) : + nsWebpack.getEntryModule(appFullPath); + const entryPath = `./${entryModule}`; + const vendorPath = `./vendor`; + const config = { mode: "development", context: appFullPath, @@ -53,9 +59,8 @@ module.exports = env => { }, target: nativescriptTarget, entry: { - bundle: aot ? - `./${nsWebpack.getAotEntryModule(appFullPath)}` : - `./${nsWebpack.getEntryModule(appFullPath)}`, + bundle: entryPath, + vendor: vendorPath, }, output: { pathinfo: true, @@ -90,17 +95,14 @@ module.exports = env => { }, devtool: "none", optimization: { + runtimeChunk: { name: "vendor" }, splitChunks: { - chunks: "all", cacheGroups: { - vendors: false, - vendor: { + common: { name: "commons", - chunks: "initial", - test: (module, chunks) => { - const moduleName = module.nameForCondition ? module.nameForCondition() : ''; - return /[\\/]node_modules[\\/]/.test(moduleName); - }, + chunks: "all", + test: /vendor/, + enforce: true, }, } }, @@ -162,6 +164,8 @@ module.exports = env => { ], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }), // Generate a bundle starter script and activate it in package.json new nsWebpack.GenerateBundleStarterPlugin([ + "./vendor", + "./commons", "./bundle", ]), // Support for web workers since v3.2 @@ -174,7 +178,6 @@ module.exports = env => { platformOptions: { platform, platforms, - // ignore: ["App_Resources"] }, }, ngToolsWebpackOptions) ), @@ -182,6 +185,25 @@ module.exports = env => { new nsWebpack.WatchStateLoggerPlugin(), ], }; + + if (platform === "android") { + // Add your custom Activities, Services and other android app components here. + const appComponents = [ + "tns-core-modules/ui/frame", + "tns-core-modules/ui/frame/activity", + ]; + + // Require all Android app components + // in the entry module (bundle.ts) and the vendor module (vendor.ts). + config.module.rules.push({ + test: new RegExp(`${entryPath}.ts|${vendorPath}.ts`), + use: { + loader: "nativescript-dev-webpack/android-app-components-loader", + options: { modules: appComponents } + } + }); + } + if (report) { // Generate report files for bundles content config.plugins.push(new BundleAnalyzerPlugin({ @@ -192,16 +214,17 @@ module.exports = env => { statsFilename: resolve(projectRoot, "report", `stats.json`), })); } + if (snapshot) { config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ - chunk: "commons", + chunks: [ "vendor", "commons" ], projectRoot, webpackConfig: config, targetArchs: ["arm", "arm64", "ia32"], - tnsJavaClassesOptions: { packages: ["tns-core-modules" ] }, useLibs: false })); } + if (uglify) { config.plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true })); @@ -213,5 +236,6 @@ module.exports = env => { } })); } + return config; }; diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index e1e432ed..a217dced 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -39,6 +39,10 @@ module.exports = env => { const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); + const entryModule = nsWebpack.getEntryModule(appFullPath); + const entryPath = `./${entryModule}`; + const vendorPath = `./vendor`; + const config = { mode: "development", context: appFullPath, @@ -51,7 +55,8 @@ module.exports = env => { }, target: nativescriptTarget, entry: { - bundle: `./${nsWebpack.getEntryModule(appFullPath)}`, + bundle: entryPath, + vendor: vendorPath, }, output: { pathinfo: true, @@ -135,7 +140,9 @@ module.exports = env => { ], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }), // Generate a bundle starter script and activate it in package.json new nsWebpack.GenerateBundleStarterPlugin([ - "./bundle", + "./runtime", // install webpackJsonpCallback + "./vendor", // require app/vendor.js + "./bundle", // require the entry module (app/app.js) ]), // Support for web workers since v3.2 new NativeScriptWorkerPlugin(), @@ -147,6 +154,25 @@ module.exports = env => { new nsWebpack.WatchStateLoggerPlugin(), ], }; + + if (platform === "android") { + // Add your custom Activities, Services and other android app components here. + const appComponents = [ + "tns-core-modules/ui/frame", + "tns-core-modules/ui/frame/activity", + ]; + + // Register all Android app components + // in the entry module (bundle.js). + config.module.rules.push({ + test: new RegExp(`${entryPath}.js|${vendorPath}.js`), + use: { + loader: "nativescript-dev-webpack/android-app-components-loader", + options: { modules: appComponents } + } + }); + } + if (report) { // Generate report files for bundles content config.plugins.push(new BundleAnalyzerPlugin({ @@ -157,16 +183,21 @@ module.exports = env => { statsFilename: resolve(projectRoot, "report", `stats.json`), })); } + if (snapshot) { config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ - chunk: "commons", + chunks: [ + "runtime", + "vendors-bundle-vendor", + "vendor", + ], projectRoot, webpackConfig: config, targetArchs: ["arm", "arm64", "ia32"], - tnsJavaClassesOptions: { packages: ["tns-core-modules" ] }, useLibs: false })); } + if (uglify) { config.plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true })); @@ -178,5 +209,6 @@ module.exports = env => { } })); } + return config; }; diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index e27665b8..7fa6501d 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -39,6 +39,10 @@ module.exports = env => { const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); + const entryModule = nsWebpack.getEntryModule(appFullPath); + const entryPath = `./${entryModule}`; + const vendorPath = `./vendor`; + const config = { mode: "development", context: appFullPath, @@ -51,7 +55,8 @@ module.exports = env => { }, target: nativescriptTarget, entry: { - bundle: `./${nsWebpack.getEntryModule(appFullPath)}`, + bundle: entryPath, + vendor: vendorPath, }, output: { pathinfo: true, @@ -86,11 +91,10 @@ module.exports = env => { }, devtool: "none", optimization: { + runtimeChunk: { name: "runtime" }, splitChunks: { - chunks: "all", - cacheGroups: { - commons: { name: "commons" } - } + automaticNameDelimiter: "-", + chunks: "initial", } }, module: { @@ -137,7 +141,9 @@ module.exports = env => { ], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }), // Generate a bundle starter script and activate it in package.json new nsWebpack.GenerateBundleStarterPlugin([ - "./bundle", + "./runtime", // install webpackJsonpCallback + "./vendor", // require app/vendor.js + "./bundle", // require the entry module (app/app.js) ]), // Support for web workers since v3.2 new NativeScriptWorkerPlugin(), @@ -149,6 +155,25 @@ module.exports = env => { new nsWebpack.WatchStateLoggerPlugin(), ], }; + + if (platform === "android") { + // Add your custom Activities, Services and other android app components here. + const appComponents = [ + "tns-core-modules/ui/frame", + "tns-core-modules/ui/frame/activity", + ]; + + // Register all Android app components + // in the entry module (bundle.js). + config.module.rules.push({ + test: new RegExp(`${entryPath}.js|${vendorPath}.js`), + use: { + loader: "nativescript-dev-webpack/android-app-components-loader", + options: { modules: appComponents } + } + }); + } + if (report) { // Generate report files for bundles content config.plugins.push(new BundleAnalyzerPlugin({ @@ -159,16 +184,21 @@ module.exports = env => { statsFilename: resolve(projectRoot, "report", `stats.json`), })); } + if (snapshot) { config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ - chunk: "commons", + chunks: [ + "runtime", + "vendors-bundle-vendor", + "vendor", + ], projectRoot, webpackConfig: config, targetArchs: ["arm", "arm64", "ia32"], - tnsJavaClassesOptions: { packages: ["tns-core-modules" ] }, useLibs: false })); } + if (uglify) { config.plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true })); @@ -180,5 +210,6 @@ module.exports = env => { } })); } + return config; }; From fc3a9405ac9193c7f1c11af0d91417e21f1d05ad Mon Sep 17 00:00:00 2001 From: Stanimira Vlaeva Date: Wed, 28 Mar 2018 10:28:58 +0300 Subject: [PATCH 22/41] refactor: remove old update scripts (#475) --- projectFilesManager.js | 87 ------------------------------------------ 1 file changed, 87 deletions(-) diff --git a/projectFilesManager.js b/projectFilesManager.js index d77054dc..edc9502a 100644 --- a/projectFilesManager.js +++ b/projectFilesManager.js @@ -3,33 +3,6 @@ const fs = require("fs"); const { isTypeScript, isAngular } = require("./projectHelpers"); -const FRAME_MATCH = /(\s*)(require\("ui\/frame"\);)(\s*)(require\("ui\/frame\/activity"\);)/g; -const SCOPED_FRAME = `if (!global["__snapshot"]) { - // In case snapshot generation is enabled these modules will get into the bundle - // but will not be required/evaluated. - // The snapshot webpack plugin will add them to the tns-java-classes.js bundle file. - // This way, they will be evaluated on app start as early as possible. -$1 $2$3 $4 -}`; - -const CONFIG_MATCH = /(exports = [^]+?)\s*return ({[^]+target:\s*nativescriptTarget[^]+?};)/; -const CONFIG_REPLACE = `$1 - - const config = $2 - - if (env.snapshot) { - plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ - chunk: "vendor", - projectRoot: __dirname, - webpackConfig: config, - targetArchs: ["arm", "arm64", "ia32"], - tnsJavaClassesOptions: { packages: ["tns-core-modules" ] }, - useLibs: false - })); - } - - return config;`; - function addProjectFiles(projectDir, appDir) { const projectTemplates = getProjectTemplates(projectDir); Object.keys(projectTemplates).forEach(function(templateName) { @@ -119,65 +92,6 @@ function getFullTemplatesPath(projectDir, templates) { return updatedTemplates; } -function editExistingProjectFiles(projectDir) { - const webpackConfigPath = getFullPath(projectDir, "webpack.config.js"); - const webpackCommonPath = getFullPath(projectDir, "webpack.common.js"); - - const configChangeFunctions = [ - replaceStyleUrlResolvePlugin, - addSnapshotPlugin, - ]; - - editFileContent(webpackConfigPath, ...configChangeFunctions); - editFileContent(webpackCommonPath, ...configChangeFunctions); - - const extension = isAngular({projectDir}) ? "ts" : "js"; - const vendorAndroidPath = getFullPath( - projectDir, - `app/vendor-platform.android.${extension}` - ); - - editFileContent(vendorAndroidPath, addSnapshotToVendor); -} - -function editFileContent(path, ...funcs) { - if (!fs.existsSync(path)) { - return; - } - - let content = fs.readFileSync(path, "utf8"); - funcs.forEach(fn => content = fn(content)); - - fs.writeFileSync(path, content, "utf8"); -} - -function replaceStyleUrlResolvePlugin(config) { - if (config.indexOf("StyleUrlResolvePlugin") === -1) { - return config; - } - - console.info("Replacing deprecated StyleUrlsResolvePlugin with UrlResolvePlugin..."); - return config.replace(/StyleUrlResolvePlugin/g, "UrlResolvePlugin"); -} - -function addSnapshotPlugin(config) { - if (config.indexOf("NativeScriptSnapshotPlugin") > -1) { - return config; - } - - console.info("Adding NativeScriptSnapshotPlugin configuration..."); - return config.replace(CONFIG_MATCH, CONFIG_REPLACE); -} - -function addSnapshotToVendor(content) { - if (content.indexOf("__snapshot") > -1) { - return content; - } - - console.info("Adding __snapshot configuration to app/vendor-platform.android ..."); - return content.replace(FRAME_MATCH, SCOPED_FRAME); -} - function getFullPath(projectDir, filePath) { return path.resolve(projectDir, filePath); } @@ -191,6 +105,5 @@ module.exports = { addProjectFiles, removeProjectFiles, forceUpdateProjectFiles, - editExistingProjectFiles, }; From ed04170526090fd22c737042669da976b33acf5c Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Thu, 29 Mar 2018 10:19:58 +0300 Subject: [PATCH 23/41] refactor(demo): remove vendor-platform from gitignore --- demo/.gitignore | 5 ----- 1 file changed, 5 deletions(-) diff --git a/demo/.gitignore b/demo/.gitignore index 3f3200bc..2e39e4be 100644 --- a/demo/.gitignore +++ b/demo/.gitignore @@ -11,11 +11,6 @@ test-results.xml tsconfig.aot.json vendor.js -vendor-platform.android.js -vendor-platform.ios.js - vendor.ts -vendor-platform.android.ts -vendor-platform.ios.ts webpack.config.js From 0efee0ce1e033e7ba947ea3c0dadc34eca3261ab Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Thu, 29 Mar 2018 10:24:07 +0300 Subject: [PATCH 24/41] fix(templates): split chunks for js --- templates/webpack.javascript.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index a217dced..e8142007 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -91,11 +91,10 @@ module.exports = env => { }, devtool: "none", optimization: { + runtimeChunk: { name: "runtime" }, splitChunks: { - chunks: "all", - cacheGroups: { - commons: { name: "commons" } - } + automaticNameDelimiter: "-", + chunks: "initial", } }, module: { From a3606c8be5d403ea01152b437841bcf515c8da32 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Thu, 29 Mar 2018 10:40:52 +0300 Subject: [PATCH 25/41] fix(templates/ts): use .ts for entries in android app components loader --- templates/webpack.typescript.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index 7fa6501d..1ba24e1e 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -166,7 +166,7 @@ module.exports = env => { // Register all Android app components // in the entry module (bundle.js). config.module.rules.push({ - test: new RegExp(`${entryPath}.js|${vendorPath}.js`), + test: new RegExp(`${entryPath}.ts|${vendorPath}.ts`), use: { loader: "nativescript-dev-webpack/android-app-components-loader", options: { modules: appComponents } From efec44a0ee22624fea61e1471d10e04439815b22 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Thu, 29 Mar 2018 14:22:34 +0300 Subject: [PATCH 26/41] fix: unshift instead of push the android-app-components-loader --- templates/webpack.angular.js | 2 +- templates/webpack.javascript.js | 2 +- templates/webpack.typescript.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index 5406f4d5..abceb12a 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -195,7 +195,7 @@ module.exports = env => { // Require all Android app components // in the entry module (bundle.ts) and the vendor module (vendor.ts). - config.module.rules.push({ + config.module.rules.unshift({ test: new RegExp(`${entryPath}.ts|${vendorPath}.ts`), use: { loader: "nativescript-dev-webpack/android-app-components-loader", diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index e8142007..ae0c075b 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -163,7 +163,7 @@ module.exports = env => { // Register all Android app components // in the entry module (bundle.js). - config.module.rules.push({ + config.module.rules.unshift({ test: new RegExp(`${entryPath}.js|${vendorPath}.js`), use: { loader: "nativescript-dev-webpack/android-app-components-loader", diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index 1ba24e1e..0f98ef53 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -165,7 +165,7 @@ module.exports = env => { // Register all Android app components // in the entry module (bundle.js). - config.module.rules.push({ + config.module.rules.unshift({ test: new RegExp(`${entryPath}.ts|${vendorPath}.ts`), use: { loader: "nativescript-dev-webpack/android-app-components-loader", From 7aa0aee34546f4cffa0a4fa20ca24f41dc5ab5da Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Thu, 29 Mar 2018 14:29:07 +0300 Subject: [PATCH 27/41] fix(templates/webpack.angular): test against correct entry path for angular --- templates/webpack.angular.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index abceb12a..2f1f3039 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -43,7 +43,7 @@ module.exports = env => { const entryModule = aot ? nsWebpack.getAotEntryModule(appFullPath) : - nsWebpack.getEntryModule(appFullPath); + `${nsWebpack.getEntryModule(appFullPath)}.ts`; const entryPath = `./${entryModule}`; const vendorPath = `./vendor`; @@ -196,7 +196,7 @@ module.exports = env => { // Require all Android app components // in the entry module (bundle.ts) and the vendor module (vendor.ts). config.module.rules.unshift({ - test: new RegExp(`${entryPath}.ts|${vendorPath}.ts`), + test: new RegExp(`${entryPath}|${vendorPath}.ts`), use: { loader: "nativescript-dev-webpack/android-app-components-loader", options: { modules: appComponents } From 27e0a950ea559df3cf28c812ef59ed9e7588f85d Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Thu, 29 Mar 2018 14:32:39 +0300 Subject: [PATCH 28/41] chore: update JavaScript demo dependencies --- demo/JavaScriptApp/package.json | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/demo/JavaScriptApp/package.json b/demo/JavaScriptApp/package.json index 343e5744..76679cf5 100644 --- a/demo/JavaScriptApp/package.json +++ b/demo/JavaScriptApp/package.json @@ -9,7 +9,7 @@ "version": "next" }, "tns-android": { - "version": "next" + "version": "4.0.0-2018.3.22.2" } }, "dependencies": { @@ -20,9 +20,10 @@ "babel-traverse": "6.26.0", "babel-types": "6.26.0", "babylon": "6.18.0", - "copy-webpack-plugin": "~4.0.1", + "clean-webpack-plugin": "~0.1.19", + "copy-webpack-plugin": "~4.5.1", "css-loader": "~0.28.7", - "extract-text-webpack-plugin": "~3.0.0", + "extract-text-webpack-plugin": "~3.0.2", "lazy": "1.0.11", "mocha": "~3.5.0", "mocha-junit-reporter": "^1.13.0", @@ -33,11 +34,16 @@ "nativescript-worker-loader": "~0.8.1", "node-sass": "^4.7.1", "raw-loader": "~0.5.1", - "resolve-url-loader": "~2.1.0", - "sass-loader": "^6.0.6", - "webpack": "~3.10.0", + "resolve-url-loader": "~2.3.0", + "sass-loader": "~6.0.6", + "uglifyjs-webpack-plugin": "~1.2.4", + "webpack": "~4.3.0", "webpack-bundle-analyzer": "^2.9.1", - "webpack-sources": "^1.1.0" + "webpack-cli": "~2.0.12", + "webpack-sources": "~1.1.0", + "@types/chai": "^4.0.2", + "@types/mocha": "^2.2.41", + "@types/node": "^7.0.5" }, "scripts": { "ns-bundle": "ns-bundle", From 94a09e9f34e3bf1639d7422089eb3b69f14e7053 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Thu, 29 Mar 2018 14:36:45 +0300 Subject: [PATCH 29/41] chore: update TypeScript demo dependencies --- demo/TypeScriptApp/package.json | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/demo/TypeScriptApp/package.json b/demo/TypeScriptApp/package.json index e8e12a12..c2b30189 100644 --- a/demo/TypeScriptApp/package.json +++ b/demo/TypeScriptApp/package.json @@ -6,7 +6,7 @@ "nativescript": { "id": "org.nativescript.TypeScriptApp", "tns-android": { - "version": "next" + "version": "4.0.0-2018.3.22.2" }, "tns-ios": { "version": "next" @@ -17,16 +17,12 @@ "tns-core-modules": "next" }, "devDependencies": { - "awesome-typescript-loader": "~3.1.3", "@types/chai": "^4.0.2", "@types/mocha": "^2.2.41", "@types/node": "^7.0.5", "babel-traverse": "6.26.0", "babel-types": "6.26.0", "babylon": "6.18.0", - "copy-webpack-plugin": "~4.0.1", - "css-loader": "~0.28.7", - "extract-text-webpack-plugin": "~3.0.0", "lazy": "1.0.11", "mocha": "~3.5.0", "mocha-junit-reporter": "^1.13.0", @@ -36,14 +32,20 @@ "nativescript-dev-typescript": "next", "nativescript-dev-webpack": "file:../..", "nativescript-worker-loader": "~0.8.1", - "node-sass": "^4.7.2", - "raw-loader": "~0.5.1", - "resolve-url-loader": "~2.1.0", - "sass-loader": "^6.0.6", - "typescript": "~2.6.2", - "webpack": "~3.10.0", + "typescript": "~2.7.2", + "webpack": "~4.3.0", + "webpack-cli": "~2.0.12", "webpack-bundle-analyzer": "^2.9.1", - "webpack-sources": "^1.1.0" + "webpack-sources": "~1.1.0", + "clean-webpack-plugin": "~0.1.19", + "copy-webpack-plugin": "~4.5.1", + "raw-loader": "~0.5.1", + "css-loader": "~0.28.7", + "resolve-url-loader": "~2.3.0", + "extract-text-webpack-plugin": "~3.0.2", + "uglifyjs-webpack-plugin": "~1.2.4", + "awesome-typescript-loader": "~5.0.0-1", + "sass-loader": "~6.0.6" }, "scripts": { "ns-bundle": "ns-bundle", From 494aad696804938599d14b8953a872c9682c622a Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Thu, 29 Mar 2018 14:42:13 +0300 Subject: [PATCH 30/41] chore: update Angular demo dependencies --- demo/AngularApp/package.json | 44 +++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/demo/AngularApp/package.json b/demo/AngularApp/package.json index 9bb7e114..194cac4a 100644 --- a/demo/AngularApp/package.json +++ b/demo/AngularApp/package.json @@ -6,25 +6,25 @@ "nativescript": { "id": "org.nativescript.AngularApp", "tns-android": { - "version": "next" + "version": "4.0.0-2018.3.22.2" }, "tns-ios": { "version": "next" } }, "dependencies": { - "@angular/common": "~5.2.0", - "@angular/compiler": "~5.2.0", - "@angular/core": "~5.2.0", - "@angular/forms": "~5.2.0", - "@angular/http": "~5.2.0", - "@angular/platform-browser": "~5.2.0", - "@angular/platform-browser-dynamic": "~5.2.0", - "@angular/router": "~5.2.0", - "nativescript-angular": "next", + "@angular/common": "~6.0.0-rc.0", + "@angular/compiler": "~6.0.0-rc.0", + "@angular/core": "~6.0.0-rc.0", + "@angular/forms": "~6.0.0-rc.0", + "@angular/http": "~6.0.0-rc.0", + "@angular/platform-browser": "~6.0.0-rc.0", + "@angular/platform-browser-dynamic": "~6.0.0-rc.0", + "@angular/router": "~6.0.0-rc.0", + "nativescript-angular": "file:nativescript-angular-6.0.0-rc.0.tgz", "nativescript-theme-core": "~1.0.2", "reflect-metadata": "~0.1.8", - "rxjs": "^5.5.0", + "rxjs": "~6.0.0-beta.1", "tns-core-modules": "next", "zone.js": "^0.8.4" }, @@ -39,9 +39,6 @@ "babylon": "6.18.0", "chai": "~4.1.1", "chai-as-promised": "~7.1.1", - "copy-webpack-plugin": "~4.3.0", - "css-loader": "~0.28.7", - "extract-text-webpack-plugin": "~3.0.2", "lazy": "1.0.11", "mocha": "~3.5.0", "mocha-junit-reporter": "^1.13.0", @@ -51,14 +48,19 @@ "nativescript-dev-typescript": "next", "nativescript-dev-webpack": "file:../..", "nativescript-worker-loader": "~0.8.1", - "node-sass": "^4.7.1", - "raw-loader": "~0.5.1", - "resolve-url-loader": "~2.2.1", - "sass-loader": "^6.0.6", - "typescript": "~2.6.2", - "webpack": "~3.10.0", + "typescript": "~2.7.2", + "webpack": "~4.3.0", + "webpack-cli": "~2.0.12", "webpack-bundle-analyzer": "^2.9.1", - "webpack-sources": "^1.1.0" + "webpack-sources": "~1.1.0", + "clean-webpack-plugin": "~0.1.19", + "copy-webpack-plugin": "~4.5.1", + "raw-loader": "~0.5.1", + "css-loader": "~0.28.7", + "resolve-url-loader": "~2.3.0", + "extract-text-webpack-plugin": "~3.0.2", + "uglifyjs-webpack-plugin": "~1.2.4", + "sass-loader": "~6.0.6" }, "scripts": { "ns-bundle": "ns-bundle", From c87caab024619b8cd73df6447ed0f1e250b477e8 Mon Sep 17 00:00:00 2001 From: Manol Donev Date: Thu, 29 Mar 2018 18:14:18 +0300 Subject: [PATCH 31/41] fix(deps): add missing @angular-devkit/core dependency for @ngtools/webpack --- dependencyManager.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dependencyManager.js b/dependencyManager.js index a8102ac5..21f92ff2 100644 --- a/dependencyManager.js +++ b/dependencyManager.js @@ -75,7 +75,8 @@ function getRequiredDeps(packageJson) { if (isAngular({packageJson})) { Object.assign(deps, { "@angular/compiler-cli": packageJson.dependencies["@angular/core"], - "@ngtools/webpack": "~6.0.0-beta.5", + "@ngtools/webpack": "~6.0.0-beta.8", + "@angular-devkit/core": "~0.4.8", }); } else if (isTypeScript({packageJson})) { Object.assign(deps, { "awesome-typescript-loader": "~5.0.0-1" }); From 582915646a0dd1936755510b3ce26cf61ff2c6d7 Mon Sep 17 00:00:00 2001 From: Manol Donev Date: Tue, 3 Apr 2018 19:32:04 +0300 Subject: [PATCH 32/41] refactor: update webpack config templates --- templates/webpack.angular.js | 27 ++++++++--------- templates/webpack.javascript.js | 52 ++++++++++++++++--------------- templates/webpack.typescript.js | 54 +++++++++++++++++---------------- 3 files changed, 67 insertions(+), 66 deletions(-) diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index 2f1f3039..5549be21 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -42,10 +42,10 @@ module.exports = env => { const appResourcesFullPath = resolve(projectRoot, appResourcesPath); const entryModule = aot ? - nsWebpack.getAotEntryModule(appFullPath) : + nsWebpack.getAotEntryModule(appFullPath) : `${nsWebpack.getEntryModule(appFullPath)}.ts`; const entryPath = `./${entryModule}`; - const vendorPath = `./vendor`; + const vendorPath = `./vendor.ts`; const config = { mode: "development", @@ -106,6 +106,15 @@ module.exports = env => { }, } }, + minimize: !!uglify, + minimizer: [ + // Override default minimizer to work around an Android issue by setting compress = false + new UglifyJsPlugin({ + uglifyOptions: { + compress: platform !== "android" + } + }) + ], }, module: { rules: [ @@ -196,7 +205,7 @@ module.exports = env => { // Require all Android app components // in the entry module (bundle.ts) and the vendor module (vendor.ts). config.module.rules.unshift({ - test: new RegExp(`${entryPath}|${vendorPath}.ts`), + test: new RegExp(`${entryPath}|${vendorPath}`), use: { loader: "nativescript-dev-webpack/android-app-components-loader", options: { modules: appComponents } @@ -225,17 +234,5 @@ module.exports = env => { })); } - if (uglify) { - config.plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true })); - - // Work around an Android issue by setting compress = false - const compress = platform !== "android"; - config.plugins.push(new UglifyJsPlugin({ - uglifyOptions: { - compress, - } - })); - } - return config; }; diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index ae0c075b..9d6bae75 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -40,8 +40,8 @@ module.exports = env => { const appResourcesFullPath = resolve(projectRoot, appResourcesPath); const entryModule = nsWebpack.getEntryModule(appFullPath); - const entryPath = `./${entryModule}`; - const vendorPath = `./vendor`; + const entryPath = `./${entryModule}.js`; + const vendorPath = `./vendor.js`; const config = { mode: "development", @@ -91,11 +91,26 @@ module.exports = env => { }, devtool: "none", optimization: { - runtimeChunk: { name: "runtime" }, + runtimeChunk: { name: "vendor" }, splitChunks: { - automaticNameDelimiter: "-", - chunks: "initial", - } + cacheGroups: { + common: { + name: "common", + chunks: "all", + test: /vendor/, + enforce: true, + }, + } + }, + minimize: !!uglify, + minimizer: [ + // Override default minimizer to work around an Android issue by setting compress = false + new UglifyJsPlugin({ + uglifyOptions: { + compress: platform !== "android" + } + }) + ], }, module: { rules: [ @@ -139,8 +154,8 @@ module.exports = env => { ], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }), // Generate a bundle starter script and activate it in package.json new nsWebpack.GenerateBundleStarterPlugin([ - "./runtime", // install webpackJsonpCallback - "./vendor", // require app/vendor.js + "./vendor", // install webpackJsonpCallback + "./common", // require app/vendor.js "./bundle", // require the entry module (app/app.js) ]), // Support for web workers since v3.2 @@ -161,10 +176,10 @@ module.exports = env => { "tns-core-modules/ui/frame/activity", ]; - // Register all Android app components - // in the entry module (bundle.js). + // Require all Android app components + // in the entry module (bundle.js) and the vendor module (vendor.js). config.module.rules.unshift({ - test: new RegExp(`${entryPath}.js|${vendorPath}.js`), + test: new RegExp(`${entryPath}|${vendorPath}`), use: { loader: "nativescript-dev-webpack/android-app-components-loader", options: { modules: appComponents } @@ -186,8 +201,7 @@ module.exports = env => { if (snapshot) { config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ chunks: [ - "runtime", - "vendors-bundle-vendor", + "common", "vendor", ], projectRoot, @@ -197,17 +211,5 @@ module.exports = env => { })); } - if (uglify) { - config.plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true })); - - // Work around an Android issue by setting compress = false - const compress = platform !== "android"; - config.plugins.push(new UglifyJsPlugin({ - uglifyOptions: { - compress, - } - })); - } - return config; }; diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index 0f98ef53..073fae37 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -40,8 +40,8 @@ module.exports = env => { const appResourcesFullPath = resolve(projectRoot, appResourcesPath); const entryModule = nsWebpack.getEntryModule(appFullPath); - const entryPath = `./${entryModule}`; - const vendorPath = `./vendor`; + const entryPath = `./${entryModule}.ts`; + const vendorPath = `./vendor.ts`; const config = { mode: "development", @@ -73,7 +73,7 @@ module.exports = env => { "node_modules", ], alias: { - '~': resolve("./app") + '~': appFullPath }, // don't resolve symlinks to symlinked modules symlinks: false @@ -91,11 +91,26 @@ module.exports = env => { }, devtool: "none", optimization: { - runtimeChunk: { name: "runtime" }, + runtimeChunk: { name: "vendor" }, splitChunks: { - automaticNameDelimiter: "-", - chunks: "initial", - } + cacheGroups: { + common: { + name: "common", + chunks: "all", + test: /vendor/, + enforce: true, + }, + } + }, + minimize: !!uglify, + minimizer: [ + // Override default minimizer to work around an Android issue by setting compress = false + new UglifyJsPlugin({ + uglifyOptions: { + compress: platform !== "android" + } + }) + ], }, module: { rules: [ @@ -141,8 +156,8 @@ module.exports = env => { ], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }), // Generate a bundle starter script and activate it in package.json new nsWebpack.GenerateBundleStarterPlugin([ - "./runtime", // install webpackJsonpCallback - "./vendor", // require app/vendor.js + "./vendor", // install webpackJsonpCallback + "./common", // require app/vendor.js "./bundle", // require the entry module (app/app.js) ]), // Support for web workers since v3.2 @@ -163,10 +178,10 @@ module.exports = env => { "tns-core-modules/ui/frame/activity", ]; - // Register all Android app components - // in the entry module (bundle.js). + // Require all Android app components + // in the entry module (bundle.ts) and the vendor module (vendor.ts). config.module.rules.unshift({ - test: new RegExp(`${entryPath}.ts|${vendorPath}.ts`), + test: new RegExp(`${entryPath}|${vendorPath}`), use: { loader: "nativescript-dev-webpack/android-app-components-loader", options: { modules: appComponents } @@ -188,8 +203,7 @@ module.exports = env => { if (snapshot) { config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ chunks: [ - "runtime", - "vendors-bundle-vendor", + "common", "vendor", ], projectRoot, @@ -199,17 +213,5 @@ module.exports = env => { })); } - if (uglify) { - config.plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true })); - - // Work around an Android issue by setting compress = false - const compress = platform !== "android"; - config.plugins.push(new UglifyJsPlugin({ - uglifyOptions: { - compress, - } - })); - } - return config; }; From 3d6d16036785d84a8a7cff80ff4ed94d51a78fe4 Mon Sep 17 00:00:00 2001 From: Manol Donev Date: Wed, 4 Apr 2018 14:33:09 +0300 Subject: [PATCH 33/41] fix: restore regular Node.js __dirname behavior --- templates/webpack.angular.js | 7 ++++--- templates/webpack.javascript.js | 1 + templates/webpack.typescript.js | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index 5549be21..c9fb5002 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -92,6 +92,7 @@ module.exports = env => { "timers": false, "setImmediate": false, "fs": "empty", + "__dirname": false, }, devtool: "none", optimization: { @@ -99,7 +100,7 @@ module.exports = env => { splitChunks: { cacheGroups: { common: { - name: "commons", + name: "common", chunks: "all", test: /vendor/, enforce: true, @@ -174,7 +175,7 @@ module.exports = env => { // Generate a bundle starter script and activate it in package.json new nsWebpack.GenerateBundleStarterPlugin([ "./vendor", - "./commons", + "./common", "./bundle", ]), // Support for web workers since v3.2 @@ -226,7 +227,7 @@ module.exports = env => { if (snapshot) { config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ - chunks: [ "vendor", "commons" ], + chunks: [ "vendor", "common" ], projectRoot, webpackConfig: config, targetArchs: ["arm", "arm64", "ia32"], diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index 9d6bae75..ffeacb49 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -88,6 +88,7 @@ module.exports = env => { "timers": false, "setImmediate": false, "fs": "empty", + "__dirname": false, }, devtool: "none", optimization: { diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index 073fae37..889ae0e4 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -88,6 +88,7 @@ module.exports = env => { "timers": false, "setImmediate": false, "fs": "empty", + "__dirname": false, }, devtool: "none", optimization: { From cb24936ca2e0699b71a93cf607b6e6e5669fc891 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Thu, 5 Apr 2018 11:45:59 +0300 Subject: [PATCH 34/41] chore: bump ngtools/webpack and angular-devkit/core versions to latest rc --- dependencyManager.js | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dependencyManager.js b/dependencyManager.js index 21f92ff2..f84e58b5 100644 --- a/dependencyManager.js +++ b/dependencyManager.js @@ -75,8 +75,8 @@ function getRequiredDeps(packageJson) { if (isAngular({packageJson})) { Object.assign(deps, { "@angular/compiler-cli": packageJson.dependencies["@angular/core"], - "@ngtools/webpack": "~6.0.0-beta.8", - "@angular-devkit/core": "~0.4.8", + "@ngtools/webpack": "~6.0.0-rc.1", + "@angular-devkit/core": "~0.5.1", }); } else if (isTypeScript({packageJson})) { Object.assign(deps, { "awesome-typescript-loader": "~5.0.0-1" }); diff --git a/package.json b/package.json index a68ee6e5..33fa65ea 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "tapable": "^1.0.0" }, "devDependencies": { - "@ngtools/webpack": "~6.0.0-beta.5", + "@ngtools/webpack": "~6.0.0-rc.1", "@types/node": "^8.0.0", "source-map-support": "^0.5.0", "typescript": "~2.7.2" From ae60720be6d10874fd03f91211b6069a23248073 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Thu, 5 Apr 2018 11:46:17 +0300 Subject: [PATCH 35/41] fix(PlatformFSPlugin): use Map instead of object for timestamps Webpack 4 uses Map. --- plugins/PlatformFSPlugin.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/PlatformFSPlugin.ts b/plugins/PlatformFSPlugin.ts index 1f11fd2a..d4ce3837 100644 --- a/plugins/PlatformFSPlugin.ts +++ b/plugins/PlatformFSPlugin.ts @@ -149,15 +149,15 @@ export function mapFileSystem(args: MapFileSystemArgs): any { const mappedFilesModified = filterIgnoredFilesAlienFilesAndMap(filesModified); - const mappedTimestamps = {}; + const mappedTimestamps = new Map(); for(const file in fileTimestamps) { const timestamp = fileTimestamps[file]; - mappedTimestamps[file] = timestamp; + mappedTimestamps.set(file, timestamp); const platformSuffixIndex = file.lastIndexOf(platformSuffix); if (platformSuffixIndex != -1) { const mappedFile = file.substr(0, platformSuffixIndex) + file.substr(platformSuffixIndex + platformSuffix.length - 1); if (!(mappedFile in fileTimestamps)) { - mappedTimestamps[mappedFile] = timestamp; + mappedTimestamps.set(mappedFile, timestamp); } } } From 3b885c73dea97777e47c54060ee65f9e6a558a23 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Wed, 11 Apr 2018 15:09:58 +0300 Subject: [PATCH 36/41] chore: bump deps versions --- dependencyManager.js | 10 +++++----- package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dependencyManager.js b/dependencyManager.js index f84e58b5..276ac23c 100644 --- a/dependencyManager.js +++ b/dependencyManager.js @@ -58,8 +58,8 @@ function addDependency(deps, name, version, force) { function getRequiredDeps(packageJson) { const deps = { - "webpack": "~4.3.0", - "webpack-cli": "~2.0.12", + "webpack": "~4.5.0", + "webpack-cli": "~2.0.14", "webpack-bundle-analyzer": "^2.9.1", "webpack-sources": "~1.1.0", "clean-webpack-plugin": "~0.1.19", @@ -75,11 +75,11 @@ function getRequiredDeps(packageJson) { if (isAngular({packageJson})) { Object.assign(deps, { "@angular/compiler-cli": packageJson.dependencies["@angular/core"], - "@ngtools/webpack": "~6.0.0-rc.1", - "@angular-devkit/core": "~0.5.1", + "@ngtools/webpack": "~6.0.0-rc.3", + "@angular-devkit/core": "~0.5.5", }); } else if (isTypeScript({packageJson})) { - Object.assign(deps, { "awesome-typescript-loader": "~5.0.0-1" }); + Object.assign(deps, { "awesome-typescript-loader": "~5.0.0" }); } if (isSass({packageJson})) { diff --git a/package.json b/package.json index 33fa65ea..222774b5 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "tapable": "^1.0.0" }, "devDependencies": { - "@ngtools/webpack": "~6.0.0-rc.1", + "@ngtools/webpack": "~6.0.0-rc.3", "@types/node": "^8.0.0", "source-map-support": "^0.5.0", "typescript": "~2.7.2" From 1dd20009517ddac5ac0233004410e097e96838b2 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Fri, 6 Apr 2018 13:35:06 +0300 Subject: [PATCH 37/41] fix-next: get properly project data from {N} CLI --- nsCliHelpers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nsCliHelpers.js b/nsCliHelpers.js index 66b2f8e6..c9913434 100644 --- a/nsCliHelpers.js +++ b/nsCliHelpers.js @@ -8,7 +8,7 @@ const PROJECT_DATA_GETTERS = { function getProjectData(projectDir) { const cli = getNsCli(); const projectDataService = cli.projectDataService; - const projectData = safeGet(cli, "getProjectData", projectDir); + const projectData = safeGet(projectDataService, "getProjectData", projectDir); return projectData; } @@ -20,7 +20,7 @@ function getNsCli() { return cli; } -function safeGet(object, property, args = []) { +function safeGet(object, property, ...args) { if (!object) { return; } From 39c87426b0d5ab353266db22bf57c4061f9da403 Mon Sep 17 00:00:00 2001 From: sis0k0 Date: Tue, 17 Apr 2018 09:40:39 -0600 Subject: [PATCH 38/41] fix: disable pathinfo to speedup build Disabling pathinfo results in faster builds/rebuilds (~2s). --- templates/webpack.angular.js | 2 +- templates/webpack.javascript.js | 2 +- templates/webpack.typescript.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index b0c7aad5..3b75f837 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -63,7 +63,7 @@ module.exports = env => { vendor: vendorPath, }, output: { - pathinfo: true, + pathinfo: false, path: dist, libraryTarget: "commonjs2", filename: "[name].js", diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index ffeacb49..ec14d231 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -59,7 +59,7 @@ module.exports = env => { vendor: vendorPath, }, output: { - pathinfo: true, + pathinfo: false, path: dist, libraryTarget: "commonjs2", filename: "[name].js", diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index 889ae0e4..9a245131 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -59,7 +59,7 @@ module.exports = env => { vendor: vendorPath, }, output: { - pathinfo: true, + pathinfo: false, path: dist, libraryTarget: "commonjs2", filename: "[name].js", From 546e11c72c3f0df1c498fa775464ca0db1f97a5e Mon Sep 17 00:00:00 2001 From: Manol Donev Date: Wed, 18 Apr 2018 13:49:28 +0300 Subject: [PATCH 39/41] chore(deps): update demo apps' dependencies --- demo/AngularApp/package.json | 27 ++++++++++++++------------- demo/JavaScriptApp/package.json | 14 +++++++------- demo/TypeScriptApp/package.json | 24 ++++++++++++------------ 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/demo/AngularApp/package.json b/demo/AngularApp/package.json index 7df04376..052fc6a0 100644 --- a/demo/AngularApp/package.json +++ b/demo/AngularApp/package.json @@ -6,7 +6,7 @@ "nativescript": { "id": "org.nativescript.AngularApp", "tns-android": { - "version": "4.0.0-2018.3.22.2" + "version": "next" }, "tns-ios": { "version": "next" @@ -29,8 +29,9 @@ "zone.js": "^0.8.4" }, "devDependencies": { - "@angular/compiler-cli": "~5.2.0", - "@ngtools/webpack": "~1.9.4", + "@angular-devkit/core": "~0.5.5", + "@angular/compiler-cli": "~6.0.0-rc.0", + "@ngtools/webpack": "~6.0.0-rc.3", "@types/chai": "^4.0.2", "@types/mocha": "^2.2.41", "@types/node": "^7.0.5", @@ -39,6 +40,10 @@ "babylon": "6.18.0", "chai": "~4.1.1", "chai-as-promised": "~7.1.1", + "clean-webpack-plugin": "~0.1.19", + "copy-webpack-plugin": "~4.5.1", + "css-loader": "~0.28.7", + "extract-text-webpack-plugin": "~3.0.2", "lazy": "1.0.11", "mocha": "~3.5.0", "mocha-junit-reporter": "^1.13.0", @@ -48,19 +53,15 @@ "nativescript-dev-typescript": "next", "nativescript-dev-webpack": "file:../..", "nativescript-worker-loader": "~0.8.1", - "typescript": "~2.7.2", - "webpack": "~4.3.0", - "webpack-cli": "~2.0.12", - "webpack-bundle-analyzer": "^2.9.1", - "webpack-sources": "~1.1.0", - "clean-webpack-plugin": "~0.1.19", - "copy-webpack-plugin": "~4.5.1", "raw-loader": "~0.5.1", - "css-loader": "~0.28.7", "resolve-url-loader": "~2.3.0", - "extract-text-webpack-plugin": "~3.0.2", + "sass-loader": "~6.0.6", + "typescript": "~2.7.2", "uglifyjs-webpack-plugin": "~1.2.4", - "sass-loader": "~6.0.6" + "webpack": "~4.5.0", + "webpack-bundle-analyzer": "^2.9.1", + "webpack-cli": "~2.0.14", + "webpack-sources": "~1.1.0" }, "scripts": { "ns-bundle": "ns-bundle", diff --git a/demo/JavaScriptApp/package.json b/demo/JavaScriptApp/package.json index 8bb5015a..b87cce6e 100644 --- a/demo/JavaScriptApp/package.json +++ b/demo/JavaScriptApp/package.json @@ -9,7 +9,7 @@ "version": "next" }, "tns-android": { - "version": "4.0.0-2018.3.22.2" + "version": "4.1.0-2018.4.17.6-onlyX86" } }, "dependencies": { @@ -17,6 +17,9 @@ "tns-core-modules": "next" }, "devDependencies": { + "@types/chai": "^4.0.2", + "@types/mocha": "^2.2.41", + "@types/node": "^7.0.5", "babel-traverse": "6.26.0", "babel-types": "6.26.0", "babylon": "6.18.0", @@ -37,13 +40,10 @@ "resolve-url-loader": "~2.3.0", "sass-loader": "~6.0.6", "uglifyjs-webpack-plugin": "~1.2.4", - "webpack": "~4.3.0", + "webpack": "~4.5.0", "webpack-bundle-analyzer": "^2.9.1", - "webpack-cli": "~2.0.12", - "webpack-sources": "~1.1.0", - "@types/chai": "^4.0.2", - "@types/mocha": "^2.2.41", - "@types/node": "^7.0.5" + "webpack-cli": "~2.0.14", + "webpack-sources": "~1.1.0" }, "scripts": { "ns-bundle": "ns-bundle", diff --git a/demo/TypeScriptApp/package.json b/demo/TypeScriptApp/package.json index 60cb1a6f..9521e498 100644 --- a/demo/TypeScriptApp/package.json +++ b/demo/TypeScriptApp/package.json @@ -6,7 +6,7 @@ "nativescript": { "id": "org.nativescript.TypeScriptApp", "tns-android": { - "version": "4.0.0-2018.3.22.2" + "version": "next" }, "tns-ios": { "version": "next" @@ -20,9 +20,14 @@ "@types/chai": "^4.0.2", "@types/mocha": "^2.2.41", "@types/node": "^7.0.5", + "awesome-typescript-loader": "~5.0.0-1", "babel-traverse": "6.26.0", "babel-types": "6.26.0", "babylon": "6.18.0", + "clean-webpack-plugin": "~0.1.19", + "copy-webpack-plugin": "~4.5.1", + "css-loader": "~0.28.7", + "extract-text-webpack-plugin": "~3.0.2", "lazy": "1.0.11", "mocha": "~3.5.0", "mocha-junit-reporter": "^1.13.0", @@ -32,20 +37,15 @@ "nativescript-dev-typescript": "next", "nativescript-dev-webpack": "file:../..", "nativescript-worker-loader": "~0.8.1", - "typescript": "~2.7.2", - "webpack": "~4.3.0", - "webpack-cli": "~2.0.12", - "webpack-bundle-analyzer": "^2.9.1", - "webpack-sources": "~1.1.0", - "clean-webpack-plugin": "~0.1.19", - "copy-webpack-plugin": "~4.5.1", "raw-loader": "~0.5.1", - "css-loader": "~0.28.7", "resolve-url-loader": "~2.3.0", - "extract-text-webpack-plugin": "~3.0.2", + "sass-loader": "~6.0.6", + "typescript": "~2.7.2", "uglifyjs-webpack-plugin": "~1.2.4", - "awesome-typescript-loader": "~5.0.0-1", - "sass-loader": "~6.0.6" + "webpack": "~4.5.0", + "webpack-bundle-analyzer": "^2.9.1", + "webpack-cli": "~2.0.14", + "webpack-sources": "~1.1.0" }, "scripts": { "ns-bundle": "ns-bundle", From 782c2410915c46d0f6c05e9fe68ba45e8b3f0cbe Mon Sep 17 00:00:00 2001 From: Manol Donev Date: Wed, 18 Apr 2018 13:55:30 +0300 Subject: [PATCH 40/41] chore(deps): update demo apps' dependencies --- demo/JavaScriptApp/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/JavaScriptApp/package.json b/demo/JavaScriptApp/package.json index b87cce6e..c22d08a2 100644 --- a/demo/JavaScriptApp/package.json +++ b/demo/JavaScriptApp/package.json @@ -9,7 +9,7 @@ "version": "next" }, "tns-android": { - "version": "4.1.0-2018.4.17.6-onlyX86" + "version": "next" } }, "dependencies": { From c0eb96cec19991d25befeae6bf1984d401643cb2 Mon Sep 17 00:00:00 2001 From: Manol Donev Date: Mon, 23 Apr 2018 18:58:26 +0300 Subject: [PATCH 41/41] fix: android app components loader on Windows --- templates/webpack.angular.js | 6 +++--- templates/webpack.javascript.js | 6 +++--- templates/webpack.typescript.js | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index 7c905661..14898285 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -1,4 +1,4 @@ -const { relative, resolve, join } = require("path"); +const { join, relative, resolve, sep } = require("path"); const webpack = require("webpack"); const nsWebpack = require("nativescript-dev-webpack"); @@ -46,8 +46,8 @@ module.exports = env => { const entryModule = aot ? nsWebpack.getAotEntryModule(appFullPath) : `${nsWebpack.getEntryModule(appFullPath)}.ts`; - const entryPath = `./${entryModule}`; - const vendorPath = `./vendor.ts`; + const entryPath = `.${sep}${entryModule}`; + const vendorPath = `.${sep}vendor.ts`; const config = { mode: "development", diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index da9c12cf..75ee94f3 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -1,4 +1,4 @@ -const { relative, resolve, join } = require("path"); +const { join, relative, resolve, sep } = require("path"); const webpack = require("webpack"); const nsWebpack = require("nativescript-dev-webpack"); @@ -42,8 +42,8 @@ module.exports = env => { const appResourcesFullPath = resolve(projectRoot, appResourcesPath); const entryModule = nsWebpack.getEntryModule(appFullPath); - const entryPath = `./${entryModule}.js`; - const vendorPath = `./vendor.js`; + const entryPath = `.${sep}${entryModule}.js`; + const vendorPath = `.${sep}vendor.js`; const config = { mode: "development", diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index 6ec0b403..dfedb7de 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -1,4 +1,4 @@ -const { relative, resolve, join } = require("path"); +const { join, relative, resolve, sep } = require("path"); const webpack = require("webpack"); const nsWebpack = require("nativescript-dev-webpack"); @@ -42,8 +42,8 @@ module.exports = env => { const appResourcesFullPath = resolve(projectRoot, appResourcesPath); const entryModule = nsWebpack.getEntryModule(appFullPath); - const entryPath = `./${entryModule}.ts`; - const vendorPath = `./vendor.ts`; + const entryPath = `.${sep}${entryModule}.ts`; + const vendorPath = `.${sep}vendor.ts`; const config = { mode: "development",