From 6c24c149ed773f742802696c150f9a96eb0a192c Mon Sep 17 00:00:00 2001 From: Bruno Silva Date: Thu, 15 Dec 2022 14:49:57 -0300 Subject: [PATCH 01/13] feat: add new moduleFederation option --- packages/babel-plugin/src/index.js | 6 ++- .../babel-plugin/src/properties/resolve.js | 41 ++++++++++++++----- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/packages/babel-plugin/src/index.js b/packages/babel-plugin/src/index.js index 24081f419..c5b5829c6 100644 --- a/packages/babel-plugin/src/index.js +++ b/packages/babel-plugin/src/index.js @@ -20,7 +20,9 @@ const properties = [ const LOADABLE_COMMENT = '#__LOADABLE__' -const loadablePlugin = declare((api, { defaultImportSpecifier = 'loadable' }) => { +const loadablePlugin = declare((api, babelOptions) => { + const { defaultImportSpecifier = 'loadable' } = babelOptions + const { types: t } = api function collectImportCallPaths(startPath) { @@ -33,7 +35,7 @@ const loadablePlugin = declare((api, { defaultImportSpecifier = 'loadable' }) => return imports } - const propertyFactories = properties.map(init => init(api)) + const propertyFactories = properties.map(init => init(api, babelOptions)) function isValidIdentifier(path, loadableImportSpecifier, lazyImportSpecifier) { // `loadable()` diff --git a/packages/babel-plugin/src/properties/resolve.js b/packages/babel-plugin/src/properties/resolve.js index 8c952d0df..5eca5d6c0 100644 --- a/packages/babel-plugin/src/properties/resolve.js +++ b/packages/babel-plugin/src/properties/resolve.js @@ -1,13 +1,27 @@ import { getImportArg } from '../util' -export default function resolveProperty({ types: t, template }) { - const buildStatements = template` - if (require.resolveWeak) { - return require.resolveWeak(ID) - } - - return eval('require.resolve')(ID) - ` +export default function resolveProperty( + { types: t, template }, + { moduleFederation }, +) { + const templates = { + federated: template` + require(ID) + + if (require.resolveWeak) { + return require.resolveWeak(ID) + } + + return eval('require.resolve')(ID) + `, + standard: template` + if (require.resolveWeak) { + return require.resolveWeak(ID) + } + + return eval('require.resolve')(ID) + `, + } function getCallValue(callPath) { const importArg = getImportArg(callPath) @@ -27,11 +41,16 @@ export default function resolveProperty({ types: t, template }) { return t.stringLiteral(importArg.node.value) } - return ({ callPath, funcPath }) => - t.objectMethod( + return ({ callPath, funcPath }) => { + const targetTemplate = moduleFederation ? 'federated' : 'standard' + + return t.objectMethod( 'method', t.identifier('resolve'), funcPath.node.params, - t.blockStatement(buildStatements({ ID: getCallValue(callPath) })), + t.blockStatement( + templates[targetTemplate]({ ID: getCallValue(callPath) }), + ), ) + } } From bf7dda7bd122038d5aab476bfaaefe034c5b86f6 Mon Sep 17 00:00:00 2001 From: Bruno Silva Date: Tue, 20 Dec 2022 10:40:49 -0300 Subject: [PATCH 02/13] feat: add check to verify if process.isBrowser is defined as false --- packages/babel-plugin/src/properties/resolve.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/babel-plugin/src/properties/resolve.js b/packages/babel-plugin/src/properties/resolve.js index 5eca5d6c0..499a14087 100644 --- a/packages/babel-plugin/src/properties/resolve.js +++ b/packages/babel-plugin/src/properties/resolve.js @@ -42,7 +42,8 @@ export default function resolveProperty( } return ({ callPath, funcPath }) => { - const targetTemplate = moduleFederation ? 'federated' : 'standard' + const targetTemplate = + moduleFederation && process.isBrowser === false ? 'federated' : 'standard' return t.objectMethod( 'method', From f1b058cb9e51b30b08f886e7ab9ca4f7ea8cb81c Mon Sep 17 00:00:00 2001 From: Bruno Silva Date: Tue, 20 Dec 2022 14:17:39 -0300 Subject: [PATCH 03/13] feat: add warnings to avoid misconfiguration --- .../babel-plugin/src/properties/resolve.js | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/babel-plugin/src/properties/resolve.js b/packages/babel-plugin/src/properties/resolve.js index 499a14087..be7e1a5aa 100644 --- a/packages/babel-plugin/src/properties/resolve.js +++ b/packages/babel-plugin/src/properties/resolve.js @@ -42,8 +42,27 @@ export default function resolveProperty( } return ({ callPath, funcPath }) => { + const { isBrowser } = process + + if (moduleFederation) { + if ('isBrowser' in process) { + if (isBrowser === true) { + // eslint-disable-next-line no-console + console.warn( + 'The "moduleFederation: true" option will disable code splitting on the client-side', + ) + } + } else { + // eslint-disable-next-line no-console + console.warn( + 'It\'s recommended to use "isBrowser" global variable to detect the environment\n' + + 'Try to add "webpack.DefinePlugin({ \'process.isBrowser\': true })" to your webpack config', + ) + } + } + const targetTemplate = - moduleFederation && process.isBrowser === false ? 'federated' : 'standard' + moduleFederation && isBrowser === false ? 'federated' : 'standard' return t.objectMethod( 'method', From c6939b8a7bcbc9c0a9d39acfd80218ea4dcd4d85 Mon Sep 17 00:00:00 2001 From: Bruno Silva Date: Tue, 20 Dec 2022 14:47:51 -0300 Subject: [PATCH 04/13] feat: update warning messages --- packages/babel-plugin/src/properties/resolve.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/babel-plugin/src/properties/resolve.js b/packages/babel-plugin/src/properties/resolve.js index be7e1a5aa..91e7f072a 100644 --- a/packages/babel-plugin/src/properties/resolve.js +++ b/packages/babel-plugin/src/properties/resolve.js @@ -49,14 +49,15 @@ export default function resolveProperty( if (isBrowser === true) { // eslint-disable-next-line no-console console.warn( - 'The "moduleFederation: true" option will disable code splitting on the client-side', + 'The "moduleFederation: true" option only works in Node.js environment\n' + + 'Try to add "webpack.DefinePlugin({ \'process.isBrowser\': false })" to your webpack config', ) } } else { // eslint-disable-next-line no-console console.warn( 'It\'s recommended to use "isBrowser" global variable to detect the environment\n' + - 'Try to add "webpack.DefinePlugin({ \'process.isBrowser\': true })" to your webpack config', + 'Try to add "webpack.DefinePlugin({ \'process.isBrowser\': false })" to your webpack config', ) } } From ae04c1001024d8361a0f14a8706e250a133871e3 Mon Sep 17 00:00:00 2001 From: Bruno Silva Date: Thu, 22 Dec 2022 14:58:39 -0300 Subject: [PATCH 05/13] feat: use DefinePlugin to declare isBrowser at process --- packages/webpack-plugin/src/index.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/webpack-plugin/src/index.js b/packages/webpack-plugin/src/index.js index a8dbcbdde..f056b5e65 100644 --- a/packages/webpack-plugin/src/index.js +++ b/packages/webpack-plugin/src/index.js @@ -101,6 +101,19 @@ class LoadablePlugin { apply(compiler) { this.compiler = compiler + const { webpack } = compiler + + const defs = { + 'process.isBrowser': + compiler.options.target === 'web' || + compiler.options.target === undefined, + } + + // eslint-disable-next-line global-require + new ((webpack && webpack.DefinePlugin) || require('webpack').DefinePlugin)( + defs, + ).apply(compiler) + const version = 'jsonpFunction' in compiler.options.output ? 4 : 5 // Add a custom chunk loading callback From be7f129e309d7cca02fe4209bcf57f724055b00c Mon Sep 17 00:00:00 2001 From: Bruno Silva Date: Thu, 22 Dec 2022 14:58:49 -0300 Subject: [PATCH 06/13] feat: update warning messages --- packages/babel-plugin/src/properties/resolve.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/babel-plugin/src/properties/resolve.js b/packages/babel-plugin/src/properties/resolve.js index 91e7f072a..78c3f4c5a 100644 --- a/packages/babel-plugin/src/properties/resolve.js +++ b/packages/babel-plugin/src/properties/resolve.js @@ -49,15 +49,13 @@ export default function resolveProperty( if (isBrowser === true) { // eslint-disable-next-line no-console console.warn( - 'The "moduleFederation: true" option only works in Node.js environment\n' + - 'Try to add "webpack.DefinePlugin({ \'process.isBrowser\': false })" to your webpack config', + 'You are using Module Federation with target browser in webpack config. This is not recommended, cause it will disable code-splitting on client-side. Please use target "node" or false.', ) } } else { // eslint-disable-next-line no-console console.warn( - 'It\'s recommended to use "isBrowser" global variable to detect the environment\n' + - 'Try to add "webpack.DefinePlugin({ \'process.isBrowser\': false })" to your webpack config', + 'process.isBrowser not found. Please use LoadablePlugin in webpack config.', ) } } From 14cd316dad96fce80be5e49c1e84c72ff9b79b73 Mon Sep 17 00:00:00 2001 From: Bruno Silva Date: Thu, 22 Dec 2022 15:24:56 -0300 Subject: [PATCH 07/13] feat: remove unecessary warning --- .../babel-plugin/src/properties/resolve.js | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/packages/babel-plugin/src/properties/resolve.js b/packages/babel-plugin/src/properties/resolve.js index 78c3f4c5a..ca14e9ae9 100644 --- a/packages/babel-plugin/src/properties/resolve.js +++ b/packages/babel-plugin/src/properties/resolve.js @@ -44,20 +44,11 @@ export default function resolveProperty( return ({ callPath, funcPath }) => { const { isBrowser } = process - if (moduleFederation) { - if ('isBrowser' in process) { - if (isBrowser === true) { - // eslint-disable-next-line no-console - console.warn( - 'You are using Module Federation with target browser in webpack config. This is not recommended, cause it will disable code-splitting on client-side. Please use target "node" or false.', - ) - } - } else { - // eslint-disable-next-line no-console - console.warn( - 'process.isBrowser not found. Please use LoadablePlugin in webpack config.', - ) - } + if (moduleFederation && !('isBrowser' in process)) { + // eslint-disable-next-line no-console + console.warn( + 'process.isBrowser not found. Please use LoadablePlugin in webpack config.', + ) } const targetTemplate = From 50d84064305ce47eb0cf75529730ab6c555303b4 Mon Sep 17 00:00:00 2001 From: Bruno Silva Date: Thu, 22 Dec 2022 16:54:31 -0300 Subject: [PATCH 08/13] feat: use unified option structure --- .../babel-plugin/src/properties/resolve.js | 19 +++-------- packages/webpack-plugin/src/index.js | 33 ++++++++++++++----- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/packages/babel-plugin/src/properties/resolve.js b/packages/babel-plugin/src/properties/resolve.js index ca14e9ae9..27f015dcc 100644 --- a/packages/babel-plugin/src/properties/resolve.js +++ b/packages/babel-plugin/src/properties/resolve.js @@ -1,9 +1,6 @@ import { getImportArg } from '../util' -export default function resolveProperty( - { types: t, template }, - { moduleFederation }, -) { +export default function resolveProperty({ types: t, template }) { const templates = { federated: template` require(ID) @@ -42,17 +39,9 @@ export default function resolveProperty( } return ({ callPath, funcPath }) => { - const { isBrowser } = process - - if (moduleFederation && !('isBrowser' in process)) { - // eslint-disable-next-line no-console - console.warn( - 'process.isBrowser not found. Please use LoadablePlugin in webpack config.', - ) - } - - const targetTemplate = - moduleFederation && isBrowser === false ? 'federated' : 'standard' + const targetTemplate = process.env.serverSideModuleFederation + ? 'federated' + : 'standard' return t.objectMethod( 'method', diff --git a/packages/webpack-plugin/src/index.js b/packages/webpack-plugin/src/index.js index f056b5e65..da1901ce3 100644 --- a/packages/webpack-plugin/src/index.js +++ b/packages/webpack-plugin/src/index.js @@ -11,8 +11,16 @@ class LoadablePlugin { writeToDisk, outputAsset = true, chunkLoadingGlobal = '__LOADABLE_LOADED_CHUNKS__', + serverSideModuleFederation = false, } = {}) { - this.opts = { filename, writeToDisk, outputAsset, path, chunkLoadingGlobal } + this.opts = { + filename, + writeToDisk, + outputAsset, + path, + chunkLoadingGlobal, + serverSideModuleFederation, + } // The Webpack compiler instance this.compiler = null @@ -103,16 +111,23 @@ class LoadablePlugin { const { webpack } = compiler - const defs = { - 'process.isBrowser': - compiler.options.target === 'web' || - compiler.options.target === undefined, + if ( + (this.opts.serverSideModuleFederation === true && + compiler.options.target === 'web') || + compiler.options.target === undefined + ) { + throw new Error( + `Enabling server-side module federation support for a client-side Webpack target (${compiler.options.target}) is unnecessary and will effectively disable all code-splitting.`, + ) } - // eslint-disable-next-line global-require - new ((webpack && webpack.DefinePlugin) || require('webpack').DefinePlugin)( - defs, - ).apply(compiler) + if (this.opts.serverSideModuleFederation) { + new ((webpack && webpack.DefinePlugin) || + // eslint-disable-next-line global-require + require('webpack').DefinePlugin)({ + serverSideModuleFederation: true, + }).apply(compiler) + } const version = 'jsonpFunction' in compiler.options.output ? 4 : 5 From 66e6786ca4e7eebecafd87e0e0f954986b6b20bb Mon Sep 17 00:00:00 2001 From: Bruno Silva Date: Thu, 22 Dec 2022 17:17:35 -0300 Subject: [PATCH 09/13] fix: solve boolean logic error --- packages/webpack-plugin/src/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/webpack-plugin/src/index.js b/packages/webpack-plugin/src/index.js index da1901ce3..8a864a29b 100644 --- a/packages/webpack-plugin/src/index.js +++ b/packages/webpack-plugin/src/index.js @@ -112,9 +112,9 @@ class LoadablePlugin { const { webpack } = compiler if ( - (this.opts.serverSideModuleFederation === true && - compiler.options.target === 'web') || - compiler.options.target === undefined + this.opts.serverSideModuleFederation === true && + (compiler.options.target === 'web' || + compiler.options.target === undefined) ) { throw new Error( `Enabling server-side module federation support for a client-side Webpack target (${compiler.options.target}) is unnecessary and will effectively disable all code-splitting.`, From 90ced6f715a88579e3a794b565e5f4b5faba8771 Mon Sep 17 00:00:00 2001 From: Bruno Silva Date: Fri, 23 Dec 2022 16:58:42 -0300 Subject: [PATCH 10/13] fix: force injection of serverSideModuleFederation option --- .../babel-plugin/src/properties/resolve.js | 2 +- packages/webpack-plugin/src/index.js | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/packages/babel-plugin/src/properties/resolve.js b/packages/babel-plugin/src/properties/resolve.js index 27f015dcc..614e95fa8 100644 --- a/packages/babel-plugin/src/properties/resolve.js +++ b/packages/babel-plugin/src/properties/resolve.js @@ -39,7 +39,7 @@ export default function resolveProperty({ types: t, template }) { } return ({ callPath, funcPath }) => { - const targetTemplate = process.env.serverSideModuleFederation + const targetTemplate = process.serverSideModuleFederation ? 'federated' : 'standard' diff --git a/packages/webpack-plugin/src/index.js b/packages/webpack-plugin/src/index.js index 8a864a29b..8869f6586 100644 --- a/packages/webpack-plugin/src/index.js +++ b/packages/webpack-plugin/src/index.js @@ -111,6 +111,16 @@ class LoadablePlugin { const { webpack } = compiler + if ( + (this.opts.serverSideModuleFederation === true && + compiler.options.target === 'web') || + compiler.options.target === undefined + ) { + throw new Error( + `Enabling server-side module federation support for a client-side Webpack target (${compiler.options.target}) is unnecessary and will effectively disable all code-splitting.`, + ) + } + if ( this.opts.serverSideModuleFederation === true && (compiler.options.target === 'web' || @@ -122,11 +132,10 @@ class LoadablePlugin { } if (this.opts.serverSideModuleFederation) { - new ((webpack && webpack.DefinePlugin) || - // eslint-disable-next-line global-require - require('webpack').DefinePlugin)({ - serverSideModuleFederation: true, - }).apply(compiler) + Object.defineProperty(process, 'serverSideModuleFederation', { + value: true, + writable: false, + }) } const version = 'jsonpFunction' in compiler.options.output ? 4 : 5 From 36158cc878192a3ddbd50c5a4608c74f65d85b64 Mon Sep 17 00:00:00 2001 From: Bruno Silva Date: Fri, 23 Dec 2022 17:16:58 -0300 Subject: [PATCH 11/13] fix: remove unused variable --- packages/webpack-plugin/src/index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/webpack-plugin/src/index.js b/packages/webpack-plugin/src/index.js index 8869f6586..0171190c5 100644 --- a/packages/webpack-plugin/src/index.js +++ b/packages/webpack-plugin/src/index.js @@ -109,8 +109,6 @@ class LoadablePlugin { apply(compiler) { this.compiler = compiler - const { webpack } = compiler - if ( (this.opts.serverSideModuleFederation === true && compiler.options.target === 'web') || From 3f582c9b7aa726f98c6747e642ff5c50eb632a5a Mon Sep 17 00:00:00 2001 From: Bruno Silva Date: Wed, 28 Dec 2022 19:11:18 -0300 Subject: [PATCH 12/13] fix: remove wrong condition and error --- packages/webpack-plugin/src/index.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/packages/webpack-plugin/src/index.js b/packages/webpack-plugin/src/index.js index 0171190c5..ae67fae20 100644 --- a/packages/webpack-plugin/src/index.js +++ b/packages/webpack-plugin/src/index.js @@ -109,16 +109,6 @@ class LoadablePlugin { apply(compiler) { this.compiler = compiler - if ( - (this.opts.serverSideModuleFederation === true && - compiler.options.target === 'web') || - compiler.options.target === undefined - ) { - throw new Error( - `Enabling server-side module federation support for a client-side Webpack target (${compiler.options.target}) is unnecessary and will effectively disable all code-splitting.`, - ) - } - if ( this.opts.serverSideModuleFederation === true && (compiler.options.target === 'web' || From 3b2c37d918dcf9e07a361384941afc31bebf8f70 Mon Sep 17 00:00:00 2001 From: Bruno Silva Date: Fri, 30 Dec 2022 15:30:54 -0300 Subject: [PATCH 13/13] feat: move serverSideFederation option to process.env --- packages/babel-plugin/src/properties/resolve.js | 2 +- packages/webpack-plugin/src/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/babel-plugin/src/properties/resolve.js b/packages/babel-plugin/src/properties/resolve.js index 614e95fa8..19aa5c0a8 100644 --- a/packages/babel-plugin/src/properties/resolve.js +++ b/packages/babel-plugin/src/properties/resolve.js @@ -39,7 +39,7 @@ export default function resolveProperty({ types: t, template }) { } return ({ callPath, funcPath }) => { - const targetTemplate = process.serverSideModuleFederation + const targetTemplate = process.env.SERVER_SIDE_MODULE_FEDERATION ? 'federated' : 'standard' diff --git a/packages/webpack-plugin/src/index.js b/packages/webpack-plugin/src/index.js index ae67fae20..3d417944e 100644 --- a/packages/webpack-plugin/src/index.js +++ b/packages/webpack-plugin/src/index.js @@ -120,7 +120,7 @@ class LoadablePlugin { } if (this.opts.serverSideModuleFederation) { - Object.defineProperty(process, 'serverSideModuleFederation', { + Object.defineProperty(process.env, 'SERVER_SIDE_MODULE_FEDERATION', { value: true, writable: false, })