From 816c6cbcbff3d8de5ed080cb29efa00b40317393 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Tue, 9 Jul 2019 17:37:58 +0300 Subject: [PATCH] fix: handle the `bundle-config-loader` require.context change without breaking-changes for the end-users --- bundle-config-loader.ts | 16 ++++++++++--- demo/AngularApp/webpack.config.js | 2 ++ demo/JavaScriptApp/webpack.config.js | 3 ++- demo/TypeScriptApp/webpack.config.js | 3 ++- index.js | 35 ++++++++++++++++++++++++++++ templates/webpack.angular.js | 2 ++ templates/webpack.javascript.js | 3 +++ templates/webpack.typescript.js | 2 ++ templates/webpack.vue.js | 2 ++ 9 files changed, 63 insertions(+), 5 deletions(-) diff --git a/bundle-config-loader.ts b/bundle-config-loader.ts index cd4c981b..7557874c 100644 --- a/bundle-config-loader.ts +++ b/bundle-config-loader.ts @@ -1,20 +1,30 @@ import * as unitTestingConfigLoader from "./unit-testing-config-loader"; import { loader } from "webpack"; import { getOptions } from "loader-utils"; +import * as escapeRegExp from "escape-string-regexp"; // Matches all source, markup and style files that are not in App_Resources -const defaultMatch = /(? { itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); } + nsWebpack.processAppComponents(appComponents, platform); const config = { mode: production ? "production" : "development", context: appFullPath, @@ -213,6 +214,7 @@ module.exports = env => { unitTesting, appFullPath, projectRoot, + ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform) } }, ].filter(loader => !!loader) diff --git a/demo/JavaScriptApp/webpack.config.js b/demo/JavaScriptApp/webpack.config.js index 27bfc2db..ddcf17ea 100644 --- a/demo/JavaScriptApp/webpack.config.js +++ b/demo/JavaScriptApp/webpack.config.js @@ -69,6 +69,7 @@ module.exports = env => { itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); } + nsWebpack.processAppComponents(appComponents, platform); const config = { mode: production ? "production" : "development", context: appFullPath, @@ -173,7 +174,7 @@ module.exports = env => { unitTesting, appFullPath, projectRoot, - registerModules: /(? !!loader) diff --git a/demo/TypeScriptApp/webpack.config.js b/demo/TypeScriptApp/webpack.config.js index 88f3585f..9bc21ca6 100644 --- a/demo/TypeScriptApp/webpack.config.js +++ b/demo/TypeScriptApp/webpack.config.js @@ -73,6 +73,7 @@ module.exports = env => { itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); } + nsWebpack.processAppComponents(appComponents, platform); const config = { mode: production ? "production" : "development", context: appFullPath, @@ -179,7 +180,7 @@ module.exports = env => { unitTesting, appFullPath, projectRoot, - registerModules: /(? !!loader) diff --git a/index.js b/index.js index e76ce2cb..2ed399dc 100644 --- a/index.js +++ b/index.js @@ -98,6 +98,41 @@ exports.getConvertedExternals = (externals) => { return modifiedExternals; }; + +/** + * The `require.context` call in `bundle-config-loader` will ask the FS for files and + * the PlatformFSPlugin will return files without `.${platform}`. The SplitChunksPlugin will + * compare the `appComponents` with the files returned from the `PlatformFSPlugin` and when they + * do not match because of the platform extension, it will duplicate the custom components + * in `bundle` (activity.js - included by the `require.context` call in `bundle-config-loader`) + * and `vendor` (activity.android.js - included by `android-app-components-loader` and `SplitChunksPlugin`). + * We are post-processing the `appComponents` in order to unify the file names and avoid getting + * a build-time SBG exception for duplicate native class definition. + */ +exports.processAppComponents = (appComponents, platform) => { + for (const key in appComponents) { + appComponents[key] = appComponents[key].replace(`.${platform}`, ""); + } +}; + +/** + * The `bundle-config-loader` needs this in order to skip the custom entries in its `require.context` call. + * If we don't skip them, custom entries like custom Android application will be included in both `application.js` + * (because its defined as an entry) and `bundle.js` (included by the `require.context` call in `bundle-config-loader`) + * causing a build-time SBG exception for duplicate native class definition. + * We are removing the extension in order to unify the file names with the `PlatformFSPlugin`. + */ +exports.getUserDefinedEntries = (entries, platform) => { + const userDefinedEntries = []; + for (const entry in entries) { + if (entry !== "bundle" && entry !== "tns_modules/tns-core-modules/inspector_modules") { + userDefinedEntries.push(entries[entry].replace(`.${platform}`, "")); + } + } + + return userDefinedEntries; +}; + const sanitize = name => name .split("") .filter(char => /[a-zA-Z0-9]/.test(char)) diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index f2933c5f..d7cd1e78 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -108,6 +108,7 @@ module.exports = env => { itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); } + nsWebpack.processAppComponents(appComponents, platform); const config = { mode: production ? "production" : "development", context: appFullPath, @@ -212,6 +213,7 @@ module.exports = env => { unitTesting, appFullPath, projectRoot, + ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform) } }, ].filter(loader => !!loader) diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index e6515456..2d004846 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -68,6 +68,8 @@ module.exports = env => { itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); } + + nsWebpack.processAppComponents(appComponents, platform); const config = { mode: production ? "production" : "development", context: appFullPath, @@ -172,6 +174,7 @@ module.exports = env => { unitTesting, appFullPath, projectRoot, + ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform) } }, ].filter(loader => !!loader) diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index 8c7627bf..a6bda652 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -72,6 +72,7 @@ module.exports = env => { itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); } + nsWebpack.processAppComponents(appComponents, platform); const config = { mode: production ? "production" : "development", context: appFullPath, @@ -178,6 +179,7 @@ module.exports = env => { unitTesting, appFullPath, projectRoot, + ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform) } }, ].filter(loader => !!loader) diff --git a/templates/webpack.vue.js b/templates/webpack.vue.js index df96d8e1..b0539c0e 100644 --- a/templates/webpack.vue.js +++ b/templates/webpack.vue.js @@ -75,6 +75,7 @@ module.exports = env => { itemsToClean.push(`${join(projectRoot, "platforms", "android", "app", "build", "configurations", "nativescript-android-snapshot")}`); } + nsWebpack.processAppComponents(appComponents, platform); const config = { mode: mode, context: appFullPath, @@ -185,6 +186,7 @@ module.exports = env => { unitTesting, appFullPath, projectRoot, + ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform) }, }, ].filter(loader => Boolean(loader)),