From 9ede6adb6cd66f5216f78570e848828bdf9b3823 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 25 Jan 2019 18:30:46 +0200 Subject: [PATCH 1/3] fix: some packages are treated as externals when they shouldn't In case `externals` are passed to webpack.config.js, they are converted to regular expression. The idea is to detect all imports for this module, for example if it is `nativescript-vue`, we would like to make externals imports like `nativescript-vue/somesubdir/file1`. However, the regular expression we construct also matches packages like `nativescript-vue-template`. Fix the regular expressions in all template webpack.config.js files and add unit tests for them. Add devDependency to `proxyquire` as the webpack configs that are tested, require some packages that are not available in node_modules of `nativescript-dev-webpack` (including the `nativescript-dev-webpack` itself). This is expected for the `webpack.config.js` files, as they should be placed in the NativeScript applications, so mocking the requires shouldn't be a problem in this case. --- package.json | 4 +- templates/webpack.angular.js | 2 +- templates/webpack.config.spec.ts | 123 +++++++++++++++++++++++++++++++ templates/webpack.javascript.js | 2 +- templates/webpack.typescript.js | 2 +- templates/webpack.vue.js | 2 +- 6 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 templates/webpack.config.spec.ts diff --git a/package.json b/package.json index 1c767915..d0cb1d4b 100644 --- a/package.json +++ b/package.json @@ -100,11 +100,13 @@ }, "devDependencies": { "@ngtools/webpack": "~7.1.0", - "@types/jasmine": "^3.3.1", + "@types/jasmine": "^3.3.7", "@types/node": "^10.12.12", + "@types/proxyquire": "1.3.28", "conventional-changelog-cli": "^1.3.22", "jasmine": "^3.2.0", "jasmine-spec-reporter": "^4.2.1", + "proxyquire": "2.1.0", "typescript": "~3.1.1" } } diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index ee8250f5..22e62aaa 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -48,7 +48,7 @@ module.exports = env => { } = env; env.externals = env.externals || []; const externals = (env.externals).map((e) => { // --env.externals - return new RegExp(e + ".*"); + return new RegExp(`^${e}((/.*)|$)`); }); const appFullPath = resolve(projectRoot, appPath); diff --git a/templates/webpack.config.spec.ts b/templates/webpack.config.spec.ts new file mode 100644 index 00000000..669b48fe --- /dev/null +++ b/templates/webpack.config.spec.ts @@ -0,0 +1,123 @@ +import * as proxyquire from 'proxyquire'; +// With noCallThru enabled, `proxyquire` will not fallback to requiring real module to populate properties that are not mocked. +// This allows us to mock packages that are not available in node_modules. +// In case you want to enable fallback for a specific object, just add `'@noCallThru': false`. +proxyquire.noCallThru(); + +class EmptyClass { }; + +const nativeScriptDevWebpack = { + GenerateBundleStarterPlugin: EmptyClass, + WatchStateLoggerPlugin: EmptyClass, + PlatformFSPlugin: EmptyClass, + getAppPath: () => 'app', + getEntryModule: () => 'EntryModule', + getResolver: () => null +}; + +const emptyObject = {}; + +const webpackConfigAngular = proxyquire('./webpack.angular', { + 'nativescript-dev-webpack': nativeScriptDevWebpack, + 'nativescript-dev-webpack/nativescript-target': emptyObject, + 'nativescript-dev-webpack/transformers/ns-replace-bootstrap': emptyObject, + 'nativescript-dev-webpack/transformers/ns-replace-lazy-loader': emptyObject, + 'nativescript-dev-webpack/utils/ast-utils': emptyObject, + '@ngtools/webpack': { + AngularCompilerPlugin: EmptyClass + } +}); + +const webpackConfigTypeScript = proxyquire('./webpack.typescript', { + 'nativescript-dev-webpack': nativeScriptDevWebpack, + 'nativescript-dev-webpack/nativescript-target': emptyObject, +}); + +const webpackConfigJavaScript = proxyquire('./webpack.javascript', { + 'nativescript-dev-webpack': nativeScriptDevWebpack, + 'nativescript-dev-webpack/nativescript-target': emptyObject, +}); + +const webpackConfigVue = proxyquire('./webpack.vue', { + 'nativescript-dev-webpack': nativeScriptDevWebpack, + 'nativescript-dev-webpack/nativescript-target': emptyObject, + 'vue-loader/lib/plugin': EmptyClass, + 'nativescript-vue-template-compiler': emptyObject +}); + +describe('webpack.config.js', () => { + [ + { type: 'javascript', webpackConfig: webpackConfigJavaScript }, + { type: 'typescript', webpackConfig: webpackConfigTypeScript }, + { type: 'angular', webpackConfig: webpackConfigAngular }, + { type: 'vue', webpackConfig: webpackConfigVue } + ].forEach(element => { + const { type, webpackConfig } = element; + + describe(`verify externals for webpack.${type}.js`, () => { + const getInput = (platform: string, externals: string[]) => { + const input: any = { externals }; + input[platform] = true; + return input; + }; + + [ + 'android', + 'ios' + ].forEach(platform => { + describe(`for ${platform}`, () => { + it('returns empty array when externals are not passed', () => { + const config = webpackConfig(getInput(platform, null)); + expect(config.externals).toEqual([]); + }); + + [ + { + input: ['nativescript-vue'], + expectedOutput: [/^nativescript-vue((\/.*)|$)/] + }, + { + input: ['nativescript-vue', 'nativescript-angular'], + expectedOutput: [/^nativescript-vue((\/.*)|$)/, /^nativescript-angular((\/.*)|$)/] + }, + ].forEach(testCase => { + const input = getInput(platform, testCase.input); + + it(`are correct regular expressions, for input ${testCase.input}`, () => { + const config = webpackConfig(input); + expect(config.externals).toEqual(testCase.expectedOutput); + }); + + it(`returns regular expressions which match expected modules and their subdirs, for input ${testCase.input}`, () => { + const config = webpackConfig(input); + + [ + 'nativescript-vue', + 'nativescript-vue/subdir', + 'nativescript-vue/subdir/subdir-2' + ].forEach(testString => { + const result = config.externals.some((regExp: RegExp) => !!regExp.exec(testString)); + expect(result).toBe(true, `String ${testString} does not match any of the regular expressions: ${config.externals.join(', ')}`); + }); + }); + + it(`returns regular expressions which does not match expected modules and their subdirs, for input ${testCase.input}`, () => { + const config = webpackConfig(input); + + [ + 'nativescript-facebook', + 'nativescript-facebook/nativescript-vue', + 'main-plugin/subdir/nativescript-vue', + 'nativescript-vue-template-compiler', + 'nativescript-vue-template-compiler/subdir' + ].forEach(testString => { + const result = config.externals.some((regExp: RegExp) => !!regExp.exec(testString)); + expect(result).toBe(false, `String ${testString} matches some of the regular expressions: ${config.externals.join(', ')}`); + }); + }); + }); + }); + }); + }); + }); +}); diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index 96fa1e62..13a9dcd2 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -43,7 +43,7 @@ module.exports = env => { hmr, // --env.hmr, } = env; const externals = (env.externals || []).map((e) => { // --env.externals - return new RegExp(e + ".*"); + return new RegExp(`^${e}((/.*)|$)`); }); const appFullPath = resolve(projectRoot, appPath); diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index fd3bdb28..e9e86180 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -43,7 +43,7 @@ module.exports = env => { hmr, // --env.hmr, } = env; const externals = (env.externals || []).map((e) => { // --env.externals - return new RegExp(e + ".*"); + return new RegExp(`^${e}((/.*)|$)`); }); const appFullPath = resolve(projectRoot, appPath); diff --git a/templates/webpack.vue.js b/templates/webpack.vue.js index 043d0a9f..2c412296 100644 --- a/templates/webpack.vue.js +++ b/templates/webpack.vue.js @@ -47,7 +47,7 @@ module.exports = env => { } = env; const externals = (env.externals || []).map((e) => { // --env.externals - return new RegExp(e + ".*"); + return new RegExp(`^${e}((/.*)|$)`); }); const mode = production ? "production" : "development" From 34c36ba79049e825bc807f7d99ed5a5a69a613fc Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 29 Jan 2019 19:30:36 +0200 Subject: [PATCH 2/3] chore: move externals generation to a common place Move the conversion of regular expressions from `string[]` to `RegExp[]` to index.js file, so it can be reused in all webpack.config.js files. Move most of the tests to the `index.spec.js` due to this change. --- index.js | 18 +++ index.spec.ts | 54 +++++++++ templates/webpack.angular.js | 7 +- templates/webpack.config.spec.ts | 182 +++++++++++++++---------------- templates/webpack.javascript.js | 4 +- templates/webpack.typescript.js | 4 +- templates/webpack.vue.js | 4 +- 7 files changed, 163 insertions(+), 110 deletions(-) create mode 100644 index.spec.ts diff --git a/index.js b/index.js index 1b3a317c..25d974db 100644 --- a/index.js +++ b/index.js @@ -53,6 +53,24 @@ exports.getAppPath = (platform, projectDir) => { } }; +/** + * Converts array of strings externals to array of regular expressions. + * Input is array of string, which we need to convert to regular expressions, so all imports for this module will be treated as exteranls. + * For example, in case we want nativescript-vue to be external, we will pass `["nativescript-vue"]`. + * If we pass it to webpack in this way, it will treat all `require("nativescript-vue")` as externals. + * However, you may import some file/subdir of the module, for example `require("nativescript-vue/somedir/file1")`. + * To treat this as external, we convert the strings to regular expressions, which makes webpack exclude all imports of the module. + * @param {string[]} externals Array of strings. + * @returns {RegExp[]} Array of regular expressions constructed from the input strings. In case the input is nullable, empty array is returned. + */ +exports.getConvertedExternals = (externals) => { + const modifiedExternals = (externals || []).map((e) => { + return new RegExp(`^${e}((/.*)|$)`); + }); + + return modifiedExternals; +}; + const sanitize = name => name .split("") .filter(char => /[a-zA-Z0-9]/.test(char)) diff --git a/index.spec.ts b/index.spec.ts new file mode 100644 index 00000000..4e5471bb --- /dev/null +++ b/index.spec.ts @@ -0,0 +1,54 @@ +import { getConvertedExternals } from './index'; + +describe('index', () => { + describe('getConvertedExternals', () => { + it('returns empty array when nullable is passed', () => { + const actualResult = getConvertedExternals(null); + expect(actualResult).toEqual([]); + }); + + const testCases = [ + { + input: ['nativescript-vue'], + expectedOutput: [/^nativescript-vue((\/.*)|$)/] + }, + { + input: ['nativescript-vue', 'nativescript-angular'], + expectedOutput: [/^nativescript-vue((\/.*)|$)/, /^nativescript-angular((\/.*)|$)/] + } + ]; + + testCases.forEach(testCase => { + it('converts passed strings to regular expressions', () => { + const actualResult = getConvertedExternals(testCase.input); + expect(actualResult).toEqual(testCase.expectedOutput); + }); + + it(`returns regular expressions which match expected modules and their subdirs, for input ${testCase.input}`, () => { + [ + 'nativescript-vue', + 'nativescript-vue/subdir', + 'nativescript-vue/subdir/subdir-2' + ].forEach(testString => { + const regExpsExternals = getConvertedExternals(testCase.input); + const result = regExpsExternals.some((regExp: RegExp) => !!regExp.exec(testString)); + expect(result).toBe(true, `String ${testString} does not match any of the regular expressions: ${regExpsExternals.join(', ')}`); + }); + }); + + it(`returns regular expressions which does not match expected modules and their subdirs, for input ${testCase.input}`, () => { + [ + 'nativescript-facebook', + 'nativescript-facebook/nativescript-vue', + 'main-plugin/subdir/nativescript-vue', + 'nativescript-vue-template-compiler', + 'nativescript-vue-template-compiler/subdir' + ].forEach(testString => { + const regExpsExternals = getConvertedExternals(testCase.input); + const result = regExpsExternals.some((regExp: RegExp) => !!regExp.exec(testString)); + expect(result).toBe(false, `String ${testString} matches some of the regular expressions: ${regExpsExternals.join(', ')}`); + }); + }); + }); + }); +}); diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index 22e62aaa..2d57bada 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -46,11 +46,8 @@ module.exports = env => { sourceMap, // --env.sourceMap hmr, // --env.hmr, } = env; - env.externals = env.externals || []; - const externals = (env.externals).map((e) => { // --env.externals - return new RegExp(`^${e}((/.*)|$)`); - }); + const externals = nsWebpack.getConvertedExternals(env.externals); const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); @@ -65,7 +62,7 @@ module.exports = env => { // when "@angular/core" is external, it's not included in the bundles. In this way, it will be used // directly from node_modules and the Angular modules loader won't be able to resolve the lazy routes // fixes https://github.com/NativeScript/nativescript-cli/issues/4024 - if (env.externals.indexOf("@angular/core") > -1) { + if (externals.indexOf("@angular/core") > -1) { const appModuleRelativePath = getMainModulePath(resolve(appFullPath, entryModule)); if (appModuleRelativePath) { const appModuleFolderPath = dirname(resolve(appFullPath, appModuleRelativePath)); diff --git a/templates/webpack.config.spec.ts b/templates/webpack.config.spec.ts index 669b48fe..6356558d 100644 --- a/templates/webpack.config.spec.ts +++ b/templates/webpack.config.spec.ts @@ -1,4 +1,5 @@ import * as proxyquire from 'proxyquire'; +import * as nsWebpackIndex from '../index'; // With noCallThru enabled, `proxyquire` will not fallback to requiring real module to populate properties that are not mocked. // This allows us to mock packages that are not available in node_modules. // In case you want to enable fallback for a specific object, just add `'@noCallThru': false`. @@ -7,117 +8,106 @@ proxyquire.noCallThru(); class EmptyClass { }; const nativeScriptDevWebpack = { - GenerateBundleStarterPlugin: EmptyClass, - WatchStateLoggerPlugin: EmptyClass, - PlatformFSPlugin: EmptyClass, - getAppPath: () => 'app', - getEntryModule: () => 'EntryModule', - getResolver: () => null + GenerateBundleStarterPlugin: EmptyClass, + WatchStateLoggerPlugin: EmptyClass, + PlatformFSPlugin: EmptyClass, + getAppPath: () => 'app', + getEntryModule: () => 'EntryModule', + getResolver: () => null, + getConvertedExternals: nsWebpackIndex.getConvertedExternals }; const emptyObject = {}; const webpackConfigAngular = proxyquire('./webpack.angular', { - 'nativescript-dev-webpack': nativeScriptDevWebpack, - 'nativescript-dev-webpack/nativescript-target': emptyObject, - 'nativescript-dev-webpack/transformers/ns-replace-bootstrap': emptyObject, - 'nativescript-dev-webpack/transformers/ns-replace-lazy-loader': emptyObject, - 'nativescript-dev-webpack/utils/ast-utils': emptyObject, - '@ngtools/webpack': { - AngularCompilerPlugin: EmptyClass - } + 'nativescript-dev-webpack': nativeScriptDevWebpack, + 'nativescript-dev-webpack/nativescript-target': emptyObject, + 'nativescript-dev-webpack/transformers/ns-replace-bootstrap': emptyObject, + 'nativescript-dev-webpack/transformers/ns-replace-lazy-loader': emptyObject, + 'nativescript-dev-webpack/utils/ast-utils': emptyObject, + '@ngtools/webpack': { + AngularCompilerPlugin: EmptyClass + } }); const webpackConfigTypeScript = proxyquire('./webpack.typescript', { - 'nativescript-dev-webpack': nativeScriptDevWebpack, - 'nativescript-dev-webpack/nativescript-target': emptyObject, + 'nativescript-dev-webpack': nativeScriptDevWebpack, + 'nativescript-dev-webpack/nativescript-target': emptyObject, }); const webpackConfigJavaScript = proxyquire('./webpack.javascript', { - 'nativescript-dev-webpack': nativeScriptDevWebpack, - 'nativescript-dev-webpack/nativescript-target': emptyObject, + 'nativescript-dev-webpack': nativeScriptDevWebpack, + 'nativescript-dev-webpack/nativescript-target': emptyObject, }); const webpackConfigVue = proxyquire('./webpack.vue', { - 'nativescript-dev-webpack': nativeScriptDevWebpack, - 'nativescript-dev-webpack/nativescript-target': emptyObject, - 'vue-loader/lib/plugin': EmptyClass, - 'nativescript-vue-template-compiler': emptyObject + 'nativescript-dev-webpack': nativeScriptDevWebpack, + 'nativescript-dev-webpack/nativescript-target': emptyObject, + 'vue-loader/lib/plugin': EmptyClass, + 'nativescript-vue-template-compiler': emptyObject }); describe('webpack.config.js', () => { - [ - { type: 'javascript', webpackConfig: webpackConfigJavaScript }, - { type: 'typescript', webpackConfig: webpackConfigTypeScript }, - { type: 'angular', webpackConfig: webpackConfigAngular }, - { type: 'vue', webpackConfig: webpackConfigVue } - ].forEach(element => { - const { type, webpackConfig } = element; - - describe(`verify externals for webpack.${type}.js`, () => { - const getInput = (platform: string, externals: string[]) => { - const input: any = { externals }; - input[platform] = true; - return input; - }; - - [ - 'android', - 'ios' - ].forEach(platform => { - describe(`for ${platform}`, () => { - it('returns empty array when externals are not passed', () => { - const config = webpackConfig(getInput(platform, null)); - expect(config.externals).toEqual([]); - }); - - [ - { - input: ['nativescript-vue'], - expectedOutput: [/^nativescript-vue((\/.*)|$)/] - }, - { - input: ['nativescript-vue', 'nativescript-angular'], - expectedOutput: [/^nativescript-vue((\/.*)|$)/, /^nativescript-angular((\/.*)|$)/] - }, - ].forEach(testCase => { - const input = getInput(platform, testCase.input); - - it(`are correct regular expressions, for input ${testCase.input}`, () => { - const config = webpackConfig(input); - expect(config.externals).toEqual(testCase.expectedOutput); - }); - - it(`returns regular expressions which match expected modules and their subdirs, for input ${testCase.input}`, () => { - const config = webpackConfig(input); - - [ - 'nativescript-vue', - 'nativescript-vue/subdir', - 'nativescript-vue/subdir/subdir-2' - ].forEach(testString => { - const result = config.externals.some((regExp: RegExp) => !!regExp.exec(testString)); - expect(result).toBe(true, `String ${testString} does not match any of the regular expressions: ${config.externals.join(', ')}`); - }); - }); - - it(`returns regular expressions which does not match expected modules and their subdirs, for input ${testCase.input}`, () => { - const config = webpackConfig(input); - - [ - 'nativescript-facebook', - 'nativescript-facebook/nativescript-vue', - 'main-plugin/subdir/nativescript-vue', - 'nativescript-vue-template-compiler', - 'nativescript-vue-template-compiler/subdir' - ].forEach(testString => { - const result = config.externals.some((regExp: RegExp) => !!regExp.exec(testString)); - expect(result).toBe(false, `String ${testString} matches some of the regular expressions: ${config.externals.join(', ')}`); - }); - }); - }); - }); - }); - }); - }); + [ + { type: 'javascript', webpackConfig: webpackConfigJavaScript }, + { type: 'typescript', webpackConfig: webpackConfigTypeScript }, + { type: 'angular', webpackConfig: webpackConfigAngular }, + { type: 'vue', webpackConfig: webpackConfigVue } + ].forEach(element => { + const { type, webpackConfig } = element; + + describe(`verify externals for webpack.${type}.js`, () => { + const getInput = (platform: string, externals: string[]) => { + const input: any = { externals }; + input[platform] = true; + return input; + }; + + [ + 'android', + 'ios' + ].forEach(platform => { + describe(`for ${platform}`, () => { + afterEach(() => { + nativeScriptDevWebpack.getConvertedExternals = nsWebpackIndex.getConvertedExternals; + }); + + it('returns empty array when externals are not passed', () => { + const config = webpackConfig(getInput(platform, null)); + expect(config.externals).toEqual([]); + }); + + it('calls getConvertedExternals to convert externals', () => { + let isCalled = false; + nativeScriptDevWebpack.getConvertedExternals = () => { + isCalled = true; + return []; + }; + + const input = getInput(platform, ['nativescript-vue']); + webpackConfig(input); + expect(isCalled).toBe(true, 'Webpack.config.js must use the getConvertedExternals method'); + }); + + [ + { + input: ['nativescript-vue'], + expectedOutput: [/^nativescript-vue((\/.*)|$)/] + }, + { + input: ['nativescript-vue', 'nativescript-angular'], + expectedOutput: [/^nativescript-vue((\/.*)|$)/, /^nativescript-angular((\/.*)|$)/] + }, + ].forEach(testCase => { + const input = getInput(platform, testCase.input); + + it(`are correct regular expressions, for input ${testCase.input}`, () => { + const config = webpackConfig(input); + expect(config.externals).toEqual(testCase.expectedOutput); + }); + }); + }); + }); + }); + }); }); diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index 13a9dcd2..780e9ecd 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -42,9 +42,7 @@ module.exports = env => { sourceMap, // --env.sourceMap hmr, // --env.hmr, } = env; - const externals = (env.externals || []).map((e) => { // --env.externals - return new RegExp(`^${e}((/.*)|$)`); - }); + const externals = nsWebpack.getConvertedExternals(env.externals); const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index e9e86180..913977c9 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -42,9 +42,7 @@ module.exports = env => { sourceMap, // --env.sourceMap hmr, // --env.hmr, } = env; - const externals = (env.externals || []).map((e) => { // --env.externals - return new RegExp(`^${e}((/.*)|$)`); - }); + const externals = nsWebpack.getConvertedExternals(env.externals); const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); diff --git a/templates/webpack.vue.js b/templates/webpack.vue.js index 2c412296..18a09ff3 100644 --- a/templates/webpack.vue.js +++ b/templates/webpack.vue.js @@ -46,9 +46,7 @@ module.exports = env => { hmr, // --env.hmr } = env; - const externals = (env.externals || []).map((e) => { // --env.externals - return new RegExp(`^${e}((/.*)|$)`); - }); + const externals = nsWebpack.getConvertedExternals(env.externals); const mode = production ? "production" : "development" From 95fac4638dd43eb742ff72a833d11c8ae2bf7ffd Mon Sep 17 00:00:00 2001 From: Stanimira Vlaeva Date: Fri, 1 Feb 2019 11:04:26 +0200 Subject: [PATCH 3/3] chore: fix grammar errors Co-Authored-By: rosen-vladimirov --- index.js | 7 ++++--- templates/webpack.config.spec.ts | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 25d974db..8e86cb9b 100644 --- a/index.js +++ b/index.js @@ -54,14 +54,15 @@ exports.getAppPath = (platform, projectDir) => { }; /** - * Converts array of strings externals to array of regular expressions. - * Input is array of string, which we need to convert to regular expressions, so all imports for this module will be treated as exteranls. + * Converts an array of strings externals to an array of regular expressions. + * Input is an array of string, which we need to convert to regular expressions, so all imports for this module will be treated as externals. + * For example, in case we want nativescript-vue to be external, we will pass `["nativescript-vue"]`. * If we pass it to webpack in this way, it will treat all `require("nativescript-vue")` as externals. * However, you may import some file/subdir of the module, for example `require("nativescript-vue/somedir/file1")`. * To treat this as external, we convert the strings to regular expressions, which makes webpack exclude all imports of the module. * @param {string[]} externals Array of strings. - * @returns {RegExp[]} Array of regular expressions constructed from the input strings. In case the input is nullable, empty array is returned. + * @returns {RegExp[]} Array of regular expressions constructed from the input strings. In case the input is nullable, an empty array is returned. */ exports.getConvertedExternals = (externals) => { const modifiedExternals = (externals || []).map((e) => { diff --git a/templates/webpack.config.spec.ts b/templates/webpack.config.spec.ts index 6356558d..4fd15434 100644 --- a/templates/webpack.config.spec.ts +++ b/templates/webpack.config.spec.ts @@ -1,6 +1,6 @@ import * as proxyquire from 'proxyquire'; import * as nsWebpackIndex from '../index'; -// With noCallThru enabled, `proxyquire` will not fallback to requiring real module to populate properties that are not mocked. +// With noCallThru enabled, `proxyquire` will not fall back to requiring the real module to populate properties that are not mocked. // This allows us to mock packages that are not available in node_modules. // In case you want to enable fallback for a specific object, just add `'@noCallThru': false`. proxyquire.noCallThru();