From aa0daba6a5aae5aca8c426bf7957a6d9d2f80333 Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Fri, 5 Mar 2021 15:34:16 +0100 Subject: [PATCH] feat: ips helper, ts config, cleanups --- .../__snapshots__/angular.spec.ts.snap | 2 + .../__snapshots__/base.spec.ts.snap | 2 + .../__snapshots__/javascript.spec.ts.snap | 20 +- .../__snapshots__/react.spec.ts.snap | 4 + .../__snapshots__/svelte.spec.ts.snap | 2 + .../__snapshots__/typescript.spec.ts.snap | 556 ++++++++++++++++++ .../__snapshots__/vue.spec.ts.snap | 2 + .../configuration/typescript.spec.ts | 16 + packages/webpack5/__tests__/index.spec.ts | 8 +- packages/webpack5/package.json | 3 +- packages/webpack5/scripts/injectGlobals.ts | 30 + packages/webpack5/src/configuration/base.ts | 4 + .../webpack5/src/configuration/javascript.ts | 36 +- packages/webpack5/src/configuration/react.ts | 2 +- .../webpack5/src/configuration/typescript.ts | 30 +- packages/webpack5/src/configuration/vue.ts | 2 +- .../webpack5/src/helpers/externalConfigs.ts | 2 +- packages/webpack5/src/helpers/host.ts | 19 + .../webpack5/src/helpers/virtualModules.ts | 46 ++ .../src/plugins/PlatformSuffixPlugin.ts | 1 + 20 files changed, 743 insertions(+), 44 deletions(-) create mode 100644 packages/webpack5/__tests__/configuration/__snapshots__/typescript.spec.ts.snap create mode 100644 packages/webpack5/__tests__/configuration/typescript.spec.ts create mode 100644 packages/webpack5/scripts/injectGlobals.ts create mode 100644 packages/webpack5/src/helpers/host.ts create mode 100644 packages/webpack5/src/helpers/virtualModules.ts diff --git a/packages/webpack5/__tests__/configuration/__snapshots__/angular.spec.ts.snap b/packages/webpack5/__tests__/configuration/__snapshots__/angular.spec.ts.snap index ecd72ecc0..f2bceba52 100644 --- a/packages/webpack5/__tests__/configuration/__snapshots__/angular.spec.ts.snap +++ b/packages/webpack5/__tests__/configuration/__snapshots__/angular.spec.ts.snap @@ -201,6 +201,7 @@ exports[`angular configuration for android 1`] = ` { __DEV__: true, __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]', __CSS_PARSER__: '\\"css-tree\\"', __ANDROID__: true, __IOS__: false, @@ -468,6 +469,7 @@ exports[`angular configuration for ios 1`] = ` { __DEV__: true, __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]', __CSS_PARSER__: '\\"css-tree\\"', __ANDROID__: false, __IOS__: true, diff --git a/packages/webpack5/__tests__/configuration/__snapshots__/base.spec.ts.snap b/packages/webpack5/__tests__/configuration/__snapshots__/base.spec.ts.snap index d2e230d9d..cfa2a799c 100644 --- a/packages/webpack5/__tests__/configuration/__snapshots__/base.spec.ts.snap +++ b/packages/webpack5/__tests__/configuration/__snapshots__/base.spec.ts.snap @@ -199,6 +199,7 @@ exports[`base configuration for android 1`] = ` { __DEV__: true, __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]', __CSS_PARSER__: '\\"css-tree\\"', __ANDROID__: true, __IOS__: false, @@ -454,6 +455,7 @@ exports[`base configuration for ios 1`] = ` { __DEV__: true, __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]', __CSS_PARSER__: '\\"css-tree\\"', __ANDROID__: false, __IOS__: true, diff --git a/packages/webpack5/__tests__/configuration/__snapshots__/javascript.spec.ts.snap b/packages/webpack5/__tests__/configuration/__snapshots__/javascript.spec.ts.snap index 63a3ba91d..06922eb76 100644 --- a/packages/webpack5/__tests__/configuration/__snapshots__/javascript.spec.ts.snap +++ b/packages/webpack5/__tests__/configuration/__snapshots__/javascript.spec.ts.snap @@ -32,8 +32,7 @@ exports[`javascript configuration for android 1`] = ` '.android.scss', '.scss', '.android.json', - '.json', - '.xml' + '.json' ] }, resolveLoader: { @@ -210,6 +209,7 @@ exports[`javascript configuration for android 1`] = ` { __DEV__: true, __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]', __CSS_PARSER__: '\\"css-tree\\"', __ANDROID__: true, __IOS__: false, @@ -256,12 +256,12 @@ exports[`javascript configuration for android 1`] = ` new WatchStatePlugin(), /* config.plugin('ContextExclusionPluginPlugin') */ new ContextExclusionPlugin( - /__virtual_entry__\\\\.js$/ + /__@nativescript_webpack_virtual_entry_javascript__.js$/ ), /* config.plugin('VirtualModulesPlugin') */ new VirtualModulesPlugin( { - '__jest__/src/__virtual_entry__.js': 'require(\\\\'@nativescript/core/bundle-entry-points\\\\')\\\\nconst context = require.context(\\"~/\\", /* deep: */ true, /* filter: */ /.(xml|js|s?css)$/);\\\\nglobal.registerWebpackModules(context);' + '__jest__/src/__@nativescript_webpack_virtual_entry_javascript__': '// VIRTUAL ENTRY START\\\\nrequire(\\\\'@nativescript/core/bundle-entry-points\\\\')\\\\nconst context = require.context(\\"~/\\", /* deep: */ true, /* filter: */ /.(xml|js|s?css)$/);\\\\nglobal.registerWebpackModules(context);\\\\n// VIRTUAL ENTRY END' } ) ], @@ -271,7 +271,7 @@ exports[`javascript configuration for android 1`] = ` '__jest__/src/app.js', '@nativescript/core/ui/frame', '@nativescript/core/ui/frame/activity', - '__jest__/src/__virtual_entry__.js' + '__jest__/src/__@nativescript_webpack_virtual_entry_javascript__' ] } }" @@ -309,8 +309,7 @@ exports[`javascript configuration for ios 1`] = ` '.ios.scss', '.scss', '.ios.json', - '.json', - '.xml' + '.json' ] }, resolveLoader: { @@ -487,6 +486,7 @@ exports[`javascript configuration for ios 1`] = ` { __DEV__: true, __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]', __CSS_PARSER__: '\\"css-tree\\"', __ANDROID__: false, __IOS__: true, @@ -533,12 +533,12 @@ exports[`javascript configuration for ios 1`] = ` new WatchStatePlugin(), /* config.plugin('ContextExclusionPluginPlugin') */ new ContextExclusionPlugin( - /__virtual_entry__\\\\.js$/ + /__@nativescript_webpack_virtual_entry_javascript__.js$/ ), /* config.plugin('VirtualModulesPlugin') */ new VirtualModulesPlugin( { - '__jest__/src/__virtual_entry__.js': 'require(\\\\'@nativescript/core/bundle-entry-points\\\\')\\\\nconst context = require.context(\\"~/\\", /* deep: */ true, /* filter: */ /.(xml|js|s?css)$/);\\\\nglobal.registerWebpackModules(context);' + '__jest__/src/__@nativescript_webpack_virtual_entry_javascript__': '// VIRTUAL ENTRY START\\\\nrequire(\\\\'@nativescript/core/bundle-entry-points\\\\')\\\\nconst context = require.context(\\"~/\\", /* deep: */ true, /* filter: */ /.(xml|js|s?css)$/);\\\\nglobal.registerWebpackModules(context);\\\\n// VIRTUAL ENTRY END' } ) ], @@ -546,7 +546,7 @@ exports[`javascript configuration for ios 1`] = ` bundle: [ '@nativescript/core/globals/index.js', '__jest__/src/app.js', - '__jest__/src/__virtual_entry__.js' + '__jest__/src/__@nativescript_webpack_virtual_entry_javascript__' ], 'tns_modules/inspector_modules': [ '@nativescript/core/inspector_modules' diff --git a/packages/webpack5/__tests__/configuration/__snapshots__/react.spec.ts.snap b/packages/webpack5/__tests__/configuration/__snapshots__/react.spec.ts.snap index a80530515..397073200 100644 --- a/packages/webpack5/__tests__/configuration/__snapshots__/react.spec.ts.snap +++ b/packages/webpack5/__tests__/configuration/__snapshots__/react.spec.ts.snap @@ -214,6 +214,7 @@ exports[`react configuration > android > adds ReactRefreshWebpackPlugin when HMR { __DEV__: true, __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]', __CSS_PARSER__: '\\"css-tree\\"', __ANDROID__: true, __IOS__: false, @@ -486,6 +487,7 @@ exports[`react configuration > android > base config 1`] = ` { __DEV__: true, __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]', __CSS_PARSER__: '\\"css-tree\\"', __ANDROID__: true, __IOS__: false, @@ -758,6 +760,7 @@ exports[`react configuration > ios > adds ReactRefreshWebpackPlugin when HMR ena { __DEV__: true, __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]', __CSS_PARSER__: '\\"css-tree\\"', __ANDROID__: false, __IOS__: true, @@ -1031,6 +1034,7 @@ exports[`react configuration > ios > base config 1`] = ` { __DEV__: true, __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]', __CSS_PARSER__: '\\"css-tree\\"', __ANDROID__: false, __IOS__: true, diff --git a/packages/webpack5/__tests__/configuration/__snapshots__/svelte.spec.ts.snap b/packages/webpack5/__tests__/configuration/__snapshots__/svelte.spec.ts.snap index 67fb95c7e..7c6b05ef0 100644 --- a/packages/webpack5/__tests__/configuration/__snapshots__/svelte.spec.ts.snap +++ b/packages/webpack5/__tests__/configuration/__snapshots__/svelte.spec.ts.snap @@ -224,6 +224,7 @@ exports[`svelte configuration for android 1`] = ` { __DEV__: true, __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]', __CSS_PARSER__: '\\"css-tree\\"', __ANDROID__: true, __IOS__: false, @@ -504,6 +505,7 @@ exports[`svelte configuration for ios 1`] = ` { __DEV__: true, __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]', __CSS_PARSER__: '\\"css-tree\\"', __ANDROID__: false, __IOS__: true, diff --git a/packages/webpack5/__tests__/configuration/__snapshots__/typescript.spec.ts.snap b/packages/webpack5/__tests__/configuration/__snapshots__/typescript.spec.ts.snap new file mode 100644 index 000000000..92be731de --- /dev/null +++ b/packages/webpack5/__tests__/configuration/__snapshots__/typescript.spec.ts.snap @@ -0,0 +1,556 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`typescript configuration for android 1`] = ` +"{ + mode: 'development', + externals: [ + 'package.json', + '~/package.json' + ], + devtool: 'inline-source-map', + target: 'node', + output: { + path: '__jest__/platforms/android/app/src/main/assets/app', + pathinfo: false, + publicPath: '', + libraryTarget: 'commonjs', + globalObject: 'global' + }, + resolve: { + symlinks: true, + alias: { + '~': '__jest__/src', + '@': '__jest__/src' + }, + extensions: [ + '.android.ts', + '.ts', + '.android.js', + '.js', + '.android.css', + '.css', + '.android.scss', + '.scss', + '.android.json', + '.json' + ] + }, + resolveLoader: { + modules: [ + 'node_modules/@nativescript/webpack/dist/loaders', + 'node_modules' + ] + }, + module: { + rules: [ + /* config.module.rule('ts') */ + { + test: [ + /\\\\.ts$/ + ], + use: [ + /* config.module.rule('ts').use('ts-loader') */ + { + loader: 'ts-loader', + options: { + transpileOnly: true, + allowTsInNodeModules: true, + compilerOptions: { + sourceMap: true, + declaration: false + }, + getCustomTransformers: function () { /* omitted long function */ } + } + } + ] + }, + /* config.module.rule('js') */ + { + test: /\\\\.js$/, + exclude: [ + /node_modules/ + ], + use: [ + /* config.module.rule('js').use('babel-loader') */ + { + loader: 'babel-loader', + options: { + generatorOpts: { + compact: false + } + } + } + ] + }, + /* config.module.rule('css') */ + { + test: /\\\\.css$/, + use: [ + /* config.module.rule('css').use('apply-css-loader') */ + { + loader: 'apply-css-loader' + }, + /* config.module.rule('css').use('css2json-loader') */ + { + loader: 'css2json-loader' + }, + /* config.module.rule('css').use('postcss-loader') */ + { + loader: 'postcss-loader', + options: { + postcssOptions: { + plugins: [ + 'postcss-import' + ] + } + } + } + ] + }, + /* config.module.rule('scss') */ + { + test: /\\\\.scss$/, + use: [ + /* config.module.rule('scss').use('apply-css-loader') */ + { + loader: 'apply-css-loader' + }, + /* config.module.rule('scss').use('css2json-loader') */ + { + loader: 'css2json-loader' + }, + /* config.module.rule('scss').use('postcss-loader') */ + { + loader: 'postcss-loader', + options: { + postcssOptions: { + plugins: [ + 'postcss-import' + ] + } + } + }, + /* config.module.rule('scss').use('sass-loader') */ + { + loader: 'sass-loader' + } + ] + }, + /* config.module.rule('xml') */ + { + test: /\\\\.xml$/, + use: [ + /* config.module.rule('xml').use('xml-namespace-loader') */ + { + loader: 'xml-namespace-loader' + } + ] + } + ] + }, + optimization: { + splitChunks: { + cacheGroups: { + defaultVendor: { + test: /[\\\\\\\\/]node_modules[\\\\\\\\/]/, + priority: -10, + name: 'vendor', + chunks: 'all' + } + } + }, + minimizer: [ + /* config.optimization.minimizer('TerserPlugin') */ + new TerserPlugin( + { + terserOptions: { + compress: { + collapse_vars: false, + sequences: false + }, + keep_fnames: true + } + } + ) + ] + }, + plugins: [ + /* config.plugin('ForkTsCheckerWebpackPlugin') */ + new ForkTsCheckerWebpackPlugin( + { + typescript: { + memoryLimit: 4096 + } + } + ), + /* config.plugin('CleanWebpackPlugin') */ + new CleanWebpackPlugin( + { + cleanOnceBeforeBuildPatterns: [ + '__jest__/platforms/android/app/src/main/assets/app/**/*' + ], + verbose: false + } + ), + /* config.plugin('PlatformSuffixPlugin') */ + new PlatformSuffixPlugin( + { + platform: 'android' + } + ), + /* config.plugin('FilterWarningsPlugin') */ + new FilterWarningsPlugin( + { + exclude: /System.import\\\\(\\\\) is deprecated/ + } + ), + /* config.plugin('DefinePlugin') */ + new DefinePlugin( + { + __DEV__: true, + __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]', + __CSS_PARSER__: '\\"css-tree\\"', + __ANDROID__: true, + __IOS__: false, + 'global.isAndroid': true, + 'global.isIOS': false, + process: 'global.process' + } + ), + /* config.plugin('CopyWebpackPlugin') */ + new CopyPlugin( + { + patterns: [ + { + from: 'assets/**', + context: '__jest__/src', + noErrorOnMissing: true, + globOptions: { + dot: false, + ignore: [] + } + }, + { + from: 'fonts/**', + context: '__jest__/src', + noErrorOnMissing: true, + globOptions: { + dot: false, + ignore: [] + } + }, + { + from: '**/*.+(jpg|png)', + context: '__jest__/src', + noErrorOnMissing: true, + globOptions: { + dot: false, + ignore: [] + } + } + ] + } + ), + /* config.plugin('WatchStatePlugin') */ + new WatchStatePlugin(), + /* config.plugin('ContextExclusionPluginPlugin') */ + new ContextExclusionPlugin( + /__@nativescript_webpack_virtual_entry_typescript__.js$/ + ), + /* config.plugin('VirtualModulesPlugin') */ + new VirtualModulesPlugin( + { + '__jest__/src/__@nativescript_webpack_virtual_entry_typescript__': '// VIRTUAL ENTRY START\\\\nrequire(\\\\'@nativescript/core/bundle-entry-points\\\\')\\\\nconst context = require.context(\\"~/\\", /* deep: */ true, /* filter: */ /.(xml|js|ts|s?css)$/);\\\\nglobal.registerWebpackModules(context);\\\\n// VIRTUAL ENTRY END' + } + ) + ], + entry: { + bundle: [ + '@nativescript/core/globals/index.js', + '__jest__/src/app.js', + '@nativescript/core/ui/frame', + '@nativescript/core/ui/frame/activity', + '__jest__/src/__@nativescript_webpack_virtual_entry_typescript__' + ] + } +}" +`; + +exports[`typescript configuration for ios 1`] = ` +"{ + mode: 'development', + externals: [ + 'package.json', + '~/package.json' + ], + devtool: 'inline-source-map', + target: 'node', + output: { + path: '__jest__/platforms/ios/jest/app', + pathinfo: false, + publicPath: '', + libraryTarget: 'commonjs', + globalObject: 'global' + }, + resolve: { + symlinks: true, + alias: { + '~': '__jest__/src', + '@': '__jest__/src' + }, + extensions: [ + '.ios.ts', + '.ts', + '.ios.js', + '.js', + '.ios.css', + '.css', + '.ios.scss', + '.scss', + '.ios.json', + '.json' + ] + }, + resolveLoader: { + modules: [ + 'node_modules/@nativescript/webpack/dist/loaders', + 'node_modules' + ] + }, + module: { + rules: [ + /* config.module.rule('ts') */ + { + test: [ + /\\\\.ts$/ + ], + use: [ + /* config.module.rule('ts').use('ts-loader') */ + { + loader: 'ts-loader', + options: { + transpileOnly: true, + allowTsInNodeModules: true, + compilerOptions: { + sourceMap: true, + declaration: false + }, + getCustomTransformers: function () { /* omitted long function */ } + } + } + ] + }, + /* config.module.rule('js') */ + { + test: /\\\\.js$/, + exclude: [ + /node_modules/ + ], + use: [ + /* config.module.rule('js').use('babel-loader') */ + { + loader: 'babel-loader', + options: { + generatorOpts: { + compact: false + } + } + } + ] + }, + /* config.module.rule('css') */ + { + test: /\\\\.css$/, + use: [ + /* config.module.rule('css').use('apply-css-loader') */ + { + loader: 'apply-css-loader' + }, + /* config.module.rule('css').use('css2json-loader') */ + { + loader: 'css2json-loader' + }, + /* config.module.rule('css').use('postcss-loader') */ + { + loader: 'postcss-loader', + options: { + postcssOptions: { + plugins: [ + 'postcss-import' + ] + } + } + } + ] + }, + /* config.module.rule('scss') */ + { + test: /\\\\.scss$/, + use: [ + /* config.module.rule('scss').use('apply-css-loader') */ + { + loader: 'apply-css-loader' + }, + /* config.module.rule('scss').use('css2json-loader') */ + { + loader: 'css2json-loader' + }, + /* config.module.rule('scss').use('postcss-loader') */ + { + loader: 'postcss-loader', + options: { + postcssOptions: { + plugins: [ + 'postcss-import' + ] + } + } + }, + /* config.module.rule('scss').use('sass-loader') */ + { + loader: 'sass-loader' + } + ] + }, + /* config.module.rule('xml') */ + { + test: /\\\\.xml$/, + use: [ + /* config.module.rule('xml').use('xml-namespace-loader') */ + { + loader: 'xml-namespace-loader' + } + ] + } + ] + }, + optimization: { + splitChunks: { + cacheGroups: { + defaultVendor: { + test: /[\\\\\\\\/]node_modules[\\\\\\\\/]/, + priority: -10, + name: 'vendor', + chunks: 'all' + } + } + }, + minimizer: [ + /* config.optimization.minimizer('TerserPlugin') */ + new TerserPlugin( + { + terserOptions: { + compress: { + collapse_vars: true, + sequences: true + }, + keep_fnames: true + } + } + ) + ] + }, + plugins: [ + /* config.plugin('ForkTsCheckerWebpackPlugin') */ + new ForkTsCheckerWebpackPlugin( + { + typescript: { + memoryLimit: 4096 + } + } + ), + /* config.plugin('CleanWebpackPlugin') */ + new CleanWebpackPlugin( + { + cleanOnceBeforeBuildPatterns: [ + '__jest__/platforms/ios/jest/app/**/*' + ], + verbose: false + } + ), + /* config.plugin('PlatformSuffixPlugin') */ + new PlatformSuffixPlugin( + { + platform: 'ios' + } + ), + /* config.plugin('FilterWarningsPlugin') */ + new FilterWarningsPlugin( + { + exclude: /System.import\\\\(\\\\) is deprecated/ + } + ), + /* config.plugin('DefinePlugin') */ + new DefinePlugin( + { + __DEV__: true, + __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]', + __CSS_PARSER__: '\\"css-tree\\"', + __ANDROID__: false, + __IOS__: true, + 'global.isAndroid': false, + 'global.isIOS': true, + process: 'global.process' + } + ), + /* config.plugin('CopyWebpackPlugin') */ + new CopyPlugin( + { + patterns: [ + { + from: 'assets/**', + context: '__jest__/src', + noErrorOnMissing: true, + globOptions: { + dot: false, + ignore: [] + } + }, + { + from: 'fonts/**', + context: '__jest__/src', + noErrorOnMissing: true, + globOptions: { + dot: false, + ignore: [] + } + }, + { + from: '**/*.+(jpg|png)', + context: '__jest__/src', + noErrorOnMissing: true, + globOptions: { + dot: false, + ignore: [] + } + } + ] + } + ), + /* config.plugin('WatchStatePlugin') */ + new WatchStatePlugin(), + /* config.plugin('ContextExclusionPluginPlugin') */ + new ContextExclusionPlugin( + /__@nativescript_webpack_virtual_entry_typescript__.js$/ + ), + /* config.plugin('VirtualModulesPlugin') */ + new VirtualModulesPlugin( + { + '__jest__/src/__@nativescript_webpack_virtual_entry_typescript__': '// VIRTUAL ENTRY START\\\\nrequire(\\\\'@nativescript/core/bundle-entry-points\\\\')\\\\nconst context = require.context(\\"~/\\", /* deep: */ true, /* filter: */ /.(xml|js|ts|s?css)$/);\\\\nglobal.registerWebpackModules(context);\\\\n// VIRTUAL ENTRY END' + } + ) + ], + entry: { + bundle: [ + '@nativescript/core/globals/index.js', + '__jest__/src/app.js', + '__jest__/src/__@nativescript_webpack_virtual_entry_typescript__' + ], + 'tns_modules/inspector_modules': [ + '@nativescript/core/inspector_modules' + ] + } +}" +`; diff --git a/packages/webpack5/__tests__/configuration/__snapshots__/vue.spec.ts.snap b/packages/webpack5/__tests__/configuration/__snapshots__/vue.spec.ts.snap index d84f2b0a6..8664501e6 100644 --- a/packages/webpack5/__tests__/configuration/__snapshots__/vue.spec.ts.snap +++ b/packages/webpack5/__tests__/configuration/__snapshots__/vue.spec.ts.snap @@ -231,6 +231,7 @@ exports[`vue configuration for android 1`] = ` { __DEV__: true, __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]', __CSS_PARSER__: '\\"css-tree\\"', __ANDROID__: true, __IOS__: false, @@ -518,6 +519,7 @@ exports[`vue configuration for ios 1`] = ` { __DEV__: true, __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]', __CSS_PARSER__: '\\"css-tree\\"', __ANDROID__: false, __IOS__: true, diff --git a/packages/webpack5/__tests__/configuration/typescript.spec.ts b/packages/webpack5/__tests__/configuration/typescript.spec.ts new file mode 100644 index 000000000..39b12876c --- /dev/null +++ b/packages/webpack5/__tests__/configuration/typescript.spec.ts @@ -0,0 +1,16 @@ +import Config from 'webpack-chain'; +import typescript from '../../src/configuration/typescript'; +import { init } from '../../src'; + +describe('typescript configuration', () => { + const platforms = ['ios', 'android']; + + for (let platform of platforms) { + it(`for ${platform}`, () => { + init({ + [platform]: true, + }); + expect(typescript(new Config()).toString()).toMatchSnapshot(); + }); + } +}); diff --git a/packages/webpack5/__tests__/index.spec.ts b/packages/webpack5/__tests__/index.spec.ts index 53814ce17..40931b186 100644 --- a/packages/webpack5/__tests__/index.spec.ts +++ b/packages/webpack5/__tests__/index.spec.ts @@ -72,7 +72,7 @@ describe('@nativescript/webpack', () => { }); it('applies merge configs', () => { - const dummyEnv = { env: true }; + const dummyEnv = { foo: true }; webpack.init(dummyEnv); webpack.useConfig(false); @@ -96,7 +96,7 @@ describe('@nativescript/webpack', () => { }); it('merges mutate config', () => { - const dummyEnv = { env: true }; + const dummyEnv = { foo: true }; webpack.init(dummyEnv); webpack.useConfig(false); @@ -110,7 +110,7 @@ describe('@nativescript/webpack', () => { }); it('merges returned config', () => { - const dummyEnv = { env: true }; + const dummyEnv = { foo: true }; webpack.init(dummyEnv); webpack.useConfig(false); @@ -126,7 +126,7 @@ describe('@nativescript/webpack', () => { }); it('merges objects', () => { - const dummyEnv = { env: true }; + const dummyEnv = { foo: true }; webpack.init(dummyEnv); webpack.useConfig(false); diff --git a/packages/webpack5/package.json b/packages/webpack5/package.json index 1c211d8cb..6f26433c5 100644 --- a/packages/webpack5/package.json +++ b/packages/webpack5/package.json @@ -11,7 +11,7 @@ }, "license": "Apache-2.0", "scripts": { - "build": "tsc --project tsconfig.build.json", + "build": "tsc --project tsconfig.build.json && ts-node ./scripts/injectGlobals.ts dist/index.js __TEST__=false", "test": "jest", "prepack": "npm run build && cp -R src/stubs dist/stubs && chmod +x dist/bin/index.js" }, @@ -65,6 +65,7 @@ "memfs": "^3.2.0", "nativescript-vue-template-compiler": "^2.8.2", "ts-jest": "^26.5.2", + "ts-node": "^9.1.1", "typescript": "^4.2.2", "unionfs": "^4.4.0" }, diff --git a/packages/webpack5/scripts/injectGlobals.ts b/packages/webpack5/scripts/injectGlobals.ts new file mode 100644 index 000000000..22c90f341 --- /dev/null +++ b/packages/webpack5/scripts/injectGlobals.ts @@ -0,0 +1,30 @@ +import { readFileSync, writeFileSync, existsSync } from 'fs'; +import { program } from 'commander'; +import { resolve } from 'path'; + +program + .description('Inject globals into a dist file') + .arguments(' ') + .parse(process.argv); + +const target = resolve(program.args[0]); + +if (!existsSync(target)) { + console.log(`Invalid target: ${program.args[0]}. ${target} does not exist.`); + + process.exit(1); +} + +const globals = program.args.slice(1); +const toInject = globals.map((global) => { + const [name, value] = global.split('='); + return `global.${name} = ${value};`; +}); + +console.log(`Injecting to ${target}:`); +console.log(toInject.join('\n')); + +let fileContents = readFileSync(target).toString(); +fileContents = `${fileContents}\n${toInject.join('\n')}`; + +writeFileSync(target, fileContents); diff --git a/packages/webpack5/src/configuration/base.ts b/packages/webpack5/src/configuration/base.ts index 7504e2dfd..702af021b 100644 --- a/packages/webpack5/src/configuration/base.ts +++ b/packages/webpack5/src/configuration/base.ts @@ -16,12 +16,14 @@ import { getProjectRootPath } from '../helpers/project'; import { hasDependency } from '../helpers/dependencies'; import { applyDotEnvPlugin } from '../helpers/dotEnv'; import { env as _env, IWebpackEnv } from '../index'; +import { getIPS } from '../helpers/host'; import { getPlatformName, getAbsoluteDistPath, getEntryDirPath, getEntryPath, } from '../helpers/platform'; +import os from 'os'; export default function (config: Config, env: IWebpackEnv = _env): Config { const entryPath = getEntryPath(); @@ -267,6 +269,8 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { { __DEV__: mode === 'development', __NS_WEBPACK__: true, + __NS_DEV_HOST_IPS__: + mode === 'development' ? JSON.stringify(getIPS()) : `[]`, __CSS_PARSER__: JSON.stringify('css-tree'), // todo: replace from config value __ANDROID__: platform === 'android', __IOS__: platform === 'ios', diff --git a/packages/webpack5/src/configuration/javascript.ts b/packages/webpack5/src/configuration/javascript.ts index e42d0b5d2..2ded22963 100644 --- a/packages/webpack5/src/configuration/javascript.ts +++ b/packages/webpack5/src/configuration/javascript.ts @@ -1,38 +1,28 @@ -import VirtualModulesPlugin from 'webpack-virtual-modules'; -import { ContextExclusionPlugin } from 'webpack'; import Config from 'webpack-chain'; -import dedent from 'ts-dedent'; -import { join } from 'path'; -import { getEntryDirPath } from '../helpers/platform'; +import { addVirtualEntry } from '../helpers/virtualModules'; import { env as _env, IWebpackEnv } from '../index'; import base from './base'; export default function (config: Config, env: IWebpackEnv = _env): Config { base(config, env); - const virtualEntryPath = join(getEntryDirPath(), '__virtual_entry__.js'); const filterRE = '/.(xml|js|s?css)$/'; + const virtualEntryPath = addVirtualEntry( + config, + 'javascript', + ` + // VIRTUAL ENTRY START + require('@nativescript/core/bundle-entry-points') + const context = require.context("~/", /* deep: */ true, /* filter: */ ${filterRE}); + global.registerWebpackModules(context); + // VIRTUAL ENTRY END + ` + ); config.entry('bundle').add(virtualEntryPath); - config - .plugin('ContextExclusionPluginPlugin') - .use(ContextExclusionPlugin, [/__virtual_entry__\.js$/]); - - // Add a virtual entry module that will register all modules into - // the nativescript module loader/handler - config.plugin('VirtualModulesPlugin').use(VirtualModulesPlugin, [ - { - [virtualEntryPath]: dedent` - require('@nativescript/core/bundle-entry-points') - const context = require.context("~/", /* deep: */ true, /* filter: */ ${filterRE}); - global.registerWebpackModules(context); - `, - }, - ]); - - config.resolve.extensions.add('.xml'); + // config.resolve.extensions.add('.xml'); // set up xml config.module diff --git a/packages/webpack5/src/configuration/react.ts b/packages/webpack5/src/configuration/react.ts index d0da8cd54..be0a552dd 100644 --- a/packages/webpack5/src/configuration/react.ts +++ b/packages/webpack5/src/configuration/react.ts @@ -1,8 +1,8 @@ import { merge } from 'webpack-merge'; import Config from 'webpack-chain'; -import { env as _env, IWebpackEnv } from '../index'; import { getPlatformName } from '../helpers/platform'; +import { env as _env, IWebpackEnv } from '../index'; import base from './base'; export default function (config: Config, env: IWebpackEnv = _env): Config { diff --git a/packages/webpack5/src/configuration/typescript.ts b/packages/webpack5/src/configuration/typescript.ts index d3f7b73eb..7cfb974b4 100644 --- a/packages/webpack5/src/configuration/typescript.ts +++ b/packages/webpack5/src/configuration/typescript.ts @@ -1,11 +1,35 @@ import Config from 'webpack-chain'; -import { IWebpackEnv } from '../index'; +import { addVirtualEntry } from '../helpers/virtualModules'; +import { env as _env, IWebpackEnv } from '../index'; import base from './base'; -// todo: add base configuration for core -export default function (config: Config, env: IWebpackEnv): Config { +export default function (config: Config, env: IWebpackEnv = _env): Config { base(config, env); + const filterRE = '/.(xml|js|ts|s?css)$/'; + const virtualEntryPath = addVirtualEntry( + config, + 'typescript', + ` + // VIRTUAL ENTRY START + require('@nativescript/core/bundle-entry-points') + const context = require.context("~/", /* deep: */ true, /* filter: */ ${filterRE}); + global.registerWebpackModules(context); + // VIRTUAL ENTRY END + ` + ); + + config.entry('bundle').add(virtualEntryPath); + + // config.resolve.extensions.add('.xml'); + + // set up xml + config.module + .rule('xml') + .test(/\.xml$/) + .use('xml-namespace-loader') + .loader('xml-namespace-loader'); + return config; } diff --git a/packages/webpack5/src/configuration/vue.ts b/packages/webpack5/src/configuration/vue.ts index b9f8a62b9..a8a82098c 100644 --- a/packages/webpack5/src/configuration/vue.ts +++ b/packages/webpack5/src/configuration/vue.ts @@ -2,8 +2,8 @@ import { VueLoaderPlugin } from 'vue-loader'; import { merge } from 'webpack-merge'; import Config from 'webpack-chain'; -import { env as _env, IWebpackEnv } from '../index'; import { getPlatformName } from '../helpers/platform'; +import { env as _env, IWebpackEnv } from '../index'; import base from './base'; export default function (config: Config, env: IWebpackEnv = _env): Config { diff --git a/packages/webpack5/src/helpers/externalConfigs.ts b/packages/webpack5/src/helpers/externalConfigs.ts index 518f8b97a..3dc2a5d83 100644 --- a/packages/webpack5/src/helpers/externalConfigs.ts +++ b/packages/webpack5/src/helpers/externalConfigs.ts @@ -2,9 +2,9 @@ import path from 'path'; import fs from 'fs'; import { getAllDependencies, getDependencyPath } from './dependencies'; +import { clearCurrentPlugin, setCurrentPlugin } from '../index'; import { info, warn } from './log'; import * as lib from '../index'; -import { clearCurrentPlugin, setCurrentPlugin } from '../index'; /** * @internal diff --git a/packages/webpack5/src/helpers/host.ts b/packages/webpack5/src/helpers/host.ts new file mode 100644 index 000000000..aaf55ffee --- /dev/null +++ b/packages/webpack5/src/helpers/host.ts @@ -0,0 +1,19 @@ +import os from 'os'; + +export function getIPS() { + // todo: perhaps mock networkInterfaces instead? + if (__TEST__) { + // in tests we don't need the real ips + return ['127.0.0.1', '192.168.0.10']; + } + + const interfaces = os.networkInterfaces(); + return Object.keys(interfaces) + .map((name) => { + return interfaces[name].filter( + (binding: any) => binding.family === 'IPv4' + )[0]; + }) + .filter(Boolean) + .map((binding) => binding.address); +} diff --git a/packages/webpack5/src/helpers/virtualModules.ts b/packages/webpack5/src/helpers/virtualModules.ts new file mode 100644 index 000000000..ef6c478ac --- /dev/null +++ b/packages/webpack5/src/helpers/virtualModules.ts @@ -0,0 +1,46 @@ +import { ContextExclusionPlugin } from 'webpack'; +import Config from 'webpack-chain'; +import { join } from 'path'; + +import VirtualModulesPlugin from 'webpack-virtual-modules'; +import { getEntryDirPath } from './platform'; +import dedent from 'ts-dedent'; + +export function addVirtualEntry( + config: Config, + name: string, + contents: string +): string { + return addVirtualModule( + config, + `__@nativescript_webpack_virtual_entry_${name}__`, + contents + ); +} + +export function addVirtualModule( + config: Config, + name: string, + contents: string +): string { + const virtualEntryPath = join(getEntryDirPath(), `${name}`); + + config + .plugin('ContextExclusionPluginPlugin') + .use(ContextExclusionPlugin, [new RegExp(`${name}\.js$`)]); + + const options = { + [virtualEntryPath]: dedent(contents), + }; + + if (config.plugins.has('VirtualModulesPlugin')) { + config.plugin('VirtualModulesPlugin').tap((args) => { + Object.assign(args[0], options); + return args; + }); + } else { + config.plugin('VirtualModulesPlugin').use(VirtualModulesPlugin, [options]); + } + + return virtualEntryPath; +} diff --git a/packages/webpack5/src/plugins/PlatformSuffixPlugin.ts b/packages/webpack5/src/plugins/PlatformSuffixPlugin.ts index b9e437ed4..6b4137cce 100644 --- a/packages/webpack5/src/plugins/PlatformSuffixPlugin.ts +++ b/packages/webpack5/src/plugins/PlatformSuffixPlugin.ts @@ -42,6 +42,7 @@ export class PlatformSuffixPlugin { // require.context compiler.hooks.contextModuleFactory.tap(id, (cmf) => { + // @ts-ignore cmf.hooks.alternativeRequests.tap(id, (modules, options) => { const additionalModules = []; // we are looking for modules that are platform specific (something..ext)