From c6571ade63ba5571205c13983632926cbc0d2445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Brauer?= Date: Mon, 31 Jan 2022 17:02:17 +0000 Subject: [PATCH] refactor: use babel in importComponent webpack loader In case the `--experimental-esbuild` mode is used, we have a small webpack loader to handle the `importComponent` transformation. This had been introduced in #1632 to be a quick & dirty regex based replacer. With this commit we now have a webpack loader that has a fast-exit path in case `importComponent` is not used. Otherwise it will transpile the source code using the proper babel plugin. Co-authored-by: Markus Wolf Co-authored-by: Philipp Hinrichsen Co-authored-by: Robert Kowalski --- packages/jest-preset/package.json | 1 + packages/jest-preset/transforms/esbuild.js | 20 +++++++++--- .../import-component-loader.js | 31 ++++++++++++++++--- packages/react/import-component/mixin.core.js | 5 ++- packages/react/package.json | 1 + yarn.lock | 2 +- 6 files changed, 48 insertions(+), 12 deletions(-) diff --git a/packages/jest-preset/package.json b/packages/jest-preset/package.json index 1f6e7820b8..452ef0edab 100644 --- a/packages/jest-preset/package.json +++ b/packages/jest-preset/package.json @@ -24,6 +24,7 @@ "dependencies": { "@babel/core": "^7.9.0", "@babel/plugin-proposal-class-properties": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3", "@babel/plugin-transform-flow-strip-types": "^7.9.0", "@babel/preset-env": "^7.9.5", "@babel/preset-react": "^7.9.4", diff --git a/packages/jest-preset/transforms/esbuild.js b/packages/jest-preset/transforms/esbuild.js index a0c4d8e61d..cbf7e41401 100644 --- a/packages/jest-preset/transforms/esbuild.js +++ b/packages/jest-preset/transforms/esbuild.js @@ -1,17 +1,27 @@ // eslint-disable-next-line node/no-extraneous-require const { createTransformer } = require('esbuild-jest'); +const { transformSync } = require('@babel/core'); const transformer = createTransformer({ sourcemap: true, }); +const regex = /importComponent/g; + module.exports = { process(content, filename, config, opts) { - content = content.replace( - /importComponent\s*\(\s*\(\)\s+=>\s+import\(\s*'([^']+)'\s*\)\s*\)/g, - "importComponent({ component: require('$1') })" - ); + if (!regex.test(content)) { + return transformer.process(content, filename, config, opts); + } + + const result = transformSync(content, { + plugins: [ + require.resolve('../helpers/babel-plugin-import-component'), + require.resolve('@babel/plugin-syntax-jsx'), + ], + filename, + }); - return transformer.process(content, filename, config, opts); + return transformer.process(result.code, filename, config, opts); }, }; diff --git a/packages/react/import-component/import-component-loader.js b/packages/react/import-component/import-component-loader.js index 7c6b84d175..ab24e67b9d 100644 --- a/packages/react/import-component/import-component-loader.js +++ b/packages/react/import-component/import-component-loader.js @@ -1,10 +1,31 @@ -const regex = - /importComponent\s*\(\s*\(\)\s+=>\s+import\(\s*'([^']+)'\s*\)\s*\)/g; +const { transform } = require('@babel/core'); +const regex = /importComponent/g; function importComponentLoader(source) { - return source.replace( - regex, - "importComponent({ load: () => import('$1'), moduleId: require.resolveWeak('$1') })" + const callback = this.async(); + + if (!regex.test(source)) { + return callback(null, source); + } + + const options = this.getOptions(); + + transform( + source, + { + plugins: [ + [require.resolve('./babel'), options], + require.resolve('@babel/plugin-syntax-jsx'), + ], + filename: this.resourcePath, + }, + (err, result) => { + if (err) { + return callback(err); + } + + callback(null, result.code, result.map); + } ); } diff --git a/packages/react/import-component/mixin.core.js b/packages/react/import-component/mixin.core.js index f420c8d18c..30f8e06663 100644 --- a/packages/react/import-component/mixin.core.js +++ b/packages/react/import-component/mixin.core.js @@ -5,7 +5,10 @@ class ImportComponentCoreMixin extends Mixin { const { experimentalEsbuild } = this.options; if (experimentalEsbuild) { - jsLoaderConfig.use.push(require.resolve('./import-component-loader.js')); + jsLoaderConfig.use.push({ + loader: require.resolve('./import-component-loader.js'), + options: { module: 'hops', rootDir: this.config.rootDir }, + }); } else { jsLoaderConfig.options.plugins.push([ require.resolve('../lib/babel'), diff --git a/packages/react/package.json b/packages/react/package.json index acceb56826..6afea8ec41 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -23,6 +23,7 @@ "dependencies": { "@babel/core": "^7.9.0", "@babel/plugin-proposal-class-properties": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3", "@babel/plugin-transform-flow-strip-types": "^7.9.0", "@babel/preset-react": "^7.9.4", "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3", diff --git a/yarn.lock b/yarn.lock index 2e04e242d0..d117615bdc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -576,7 +576,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.16.7": +"@babel/plugin-syntax-jsx@^7.16.7", "@babel/plugin-syntax-jsx@^7.8.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz#50b6571d13f764266a113d77c82b4a6508bbe665" integrity sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==