From 38f32a8875568b106727e26b7bb82d66618e15c5 Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Wed, 25 Oct 2023 17:00:42 +0200 Subject: [PATCH 1/3] fix(module): resolve .js extension --- babel.config.js | 7 + scripts/babel/extension-resolver.js | 198 ++++++++++++++++++++++++++++ 2 files changed, 205 insertions(+) create mode 100644 scripts/babel/extension-resolver.js diff --git a/babel.config.js b/babel.config.js index 58f0471a2..d3d5b2957 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,3 +1,4 @@ +const extensionResolver = require('./scripts/babel/extension-resolver'); const wrapWarningWithDevCheck = require('./scripts/babel/wrap-warning-with-dev-check'); module.exports = (api) => { @@ -28,6 +29,12 @@ module.exports = (api) => { ], plugins: clean([ wrapWarningWithDevCheck, + [ + extensionResolver, + { + modulesToResolve: ['@algolia/autocomplete-shared'], + }, + ], [ 'inline-replace-variables', { diff --git a/scripts/babel/extension-resolver.js b/scripts/babel/extension-resolver.js new file mode 100644 index 000000000..1c6b8d4cf --- /dev/null +++ b/scripts/babel/extension-resolver.js @@ -0,0 +1,198 @@ +// original source: https://github.com/shimataro/babel-plugin-module-extension-resolver +// To create proper ES Modules, the paths imported need to be fully-specified, +// and can't be resolved like is possible with CommonJS. To have large compatibility +// without much hassle, we don't use extensions *inside* the source code, but add +// them with this plugin. + +const fs = require('fs'); +const path = require('path'); + +const PLUGIN_NAME = 'babel-plugin-extension-resolver'; + +module.exports = function extensionResolver( + { types }, + { + modulesToResolve = [], + srcExtensions = ['.js', '.ts', '.tsx'], + dstExtension = '.js', + } +) { + return { + name: PLUGIN_NAME, + visitor: { + Program: { + enter: (programPath, state) => { + const fileName = state.filename; + programPath.traverse( + { + ImportDeclaration(declaration) { + const source = declaration.get('source'); + replaceSource({ + types, + source, + fileName, + modulesToResolve, + srcExtensions, + dstExtension, + }); + }, + ExportDeclaration(declaration) { + const source = declaration.get('source'); + if (Array.isArray(source)) { + return; + } + replaceSource({ + types, + source, + fileName, + modulesToResolve, + srcExtensions, + dstExtension, + }); + }, + }, + state + ); + }, + }, + }, + }; +}; + +function replaceSource({ + types, + source, + fileName, + modulesToResolve, + srcExtensions, + dstExtension, +}) { + if (!source.isStringLiteral()) { + return; + } + const sourcePath = source.node.value; + if ( + modulesToResolve.every((prefix) => !sourcePath.startsWith(`${prefix}/`)) && + !isRelativeDependency(sourcePath) + ) { + return; + } + const baseDir = path.dirname(fileName); + + let normalizedPath; + if (isRelativeDependency(sourcePath)) { + const resolvedPath = resolveRelativePath( + baseDir, + sourcePath, + srcExtensions, + dstExtension + ); + normalizedPath = normalizeRelativePath(resolvedPath); + } else { + const resolvedPath = resolveAbsolutePath(sourcePath); + normalizedPath = normalizeAbsolutePath(resolvedPath); + } + + source.replaceWith(types.stringLiteral(normalizedPath)); +} + +function resolveRelativePath(baseDir, sourcePath, srcExtensions, dstExtension) { + let resolvedPath = resolveRelativeExtension( + baseDir, + sourcePath, + srcExtensions, + dstExtension + ); + + if (resolvedPath === null) { + resolvedPath = resolveRelativeExtension( + baseDir, + path.join(sourcePath, 'index'), + srcExtensions, + dstExtension + ); + } + + if (resolvedPath === null) { + throw new Error(`import for "${sourcePath}" could not be resolved`); + } + + return resolvedPath; +} + +/** + * @param {string} sourcePath the path to resolve using require.resolve + * @returns {string} the resolved path + */ +function resolveAbsolutePath(sourcePath) { + // The source path is composed of: 1. the package name, 2. the path inside the package. + const packageNameRegex = sourcePath.startsWith('@') + ? /^(?@[^/]+\/[^/]+)\/(?.+)/ + : /^(?[^/]+)\/(?.+)/; + const { packageName } = sourcePath.match(packageNameRegex).groups; + + // the require.resolve will return the full path of the requested file. + const fullPath = require.resolve(sourcePath); + + // the bare package could resolve to a nested file, but /package.json is always at the root. + // this gives us the path to the root of the package. + const packageJson = '/package.json'; + const packagePath = require + .resolve(packageName + packageJson) + .slice(0, -packageJson.length); + + // We overlap the two parts to get path inside the package. + const [, resolvedPath] = fullPath.split(packagePath); + + // That's then combined with the package name. + return packageName + resolvedPath; +} + +function resolveRelativeExtension( + baseDir, + sourcePath, + srcExtensions, + dstExtension +) { + const absolutePath = path.join(baseDir, sourcePath); + if (isFile(absolutePath)) { + return sourcePath; + } + for (const extension of srcExtensions) { + if (isFile(`${absolutePath}${extension}`)) { + return path.relative(baseDir, `${absolutePath}${dstExtension}`); + } + } + return null; +} + +function normalizeRelativePath(originalPath) { + let normalizedPath = originalPath; + if (path.sep === '\\') { + normalizedPath = normalizedPath.split(path.sep).join('/'); + } + if (normalizedPath[0] !== '.') { + normalizedPath = `./${normalizedPath}`; + } + return normalizedPath; +} + +function normalizeAbsolutePath(originalPath) { + let normalizedPath = originalPath; + if (path.sep === '\\') { + normalizedPath = normalizedPath.split(path.sep).join('/'); + } + return normalizedPath; +} + +function isFile(pathName) { + try { + return fs.statSync(pathName).isFile(); + } catch (err) { + return false; + } +} + +function isRelativeDependency(sourcePath) { + return sourcePath[0] === '.'; +} From 414d384ccfdee311f76b912b1e63c351b6fc662a Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Wed, 25 Oct 2023 17:46:26 +0200 Subject: [PATCH 2/3] package.json#exports --- packages/autocomplete-core/package.json | 13 ++++++++++ packages/autocomplete-js/package.json | 22 ++++++++++++++++ .../package.json | 10 ++++++++ .../package.json | 10 ++++++++ .../package.json | 10 ++++++++ .../package.json | 10 ++++++++ .../autocomplete-plugin-tags/package.json | 14 +++++++++++ .../autocomplete-preset-algolia/package.json | 25 +++++++++++++++++++ packages/autocomplete-shared/package.json | 16 ++++++++++++ .../autocomplete-theme-classic/package.json | 8 ++++++ 10 files changed, 138 insertions(+) diff --git a/packages/autocomplete-core/package.json b/packages/autocomplete-core/package.json index 368824472..f9f116c3a 100644 --- a/packages/autocomplete-core/package.json +++ b/packages/autocomplete-core/package.json @@ -16,6 +16,19 @@ "umd:main": "dist/umd/index.production.js", "unpkg": "dist/umd/index.production.js", "jsdelivr": "dist/umd/index.production.js", + "type": "module", + "exports": { + ".": "./dist/esm/index.js", + "./dist/esm": "./dist/esm/index.js", + "./dist/esm/*": "./dist/esm/*.js", + "./dist/esm/*.js": "./dist/esm/*.js", + "./dist/esm/utils": "./dist/esm/utils/index.js", + "./dist/esm/utils/*": "./dist/esm/utils/*.js", + "./dist/esm/utils/*.js": "./dist/esm/utils/*.js", + "./dist/esm/types": "./dist/esm/types/index.js", + "./dist/esm/types/*": "./dist/esm/types/*.js", + "./dist/esm/types/*.js": "./dist/esm/types/*.js" + }, "sideEffects": false, "files": [ "dist/" diff --git a/packages/autocomplete-js/package.json b/packages/autocomplete-js/package.json index 2f2661025..41b600d23 100644 --- a/packages/autocomplete-js/package.json +++ b/packages/autocomplete-js/package.json @@ -17,6 +17,28 @@ "unpkg": "dist/umd/index.production.js", "jsdelivr": "dist/umd/index.production.js", "sideEffects": false, + "type": "module", + "exports": { + ".": "./dist/esm/index.js", + "./dist/esm": "./dist/esm/index.js", + "./dist/esm/*": "./dist/esm/*.js", + "./dist/esm/*.js": "./dist/esm/*.js", + "./dist/esm/components": "./dist/esm/components/index.js", + "./dist/esm/components/*": "./dist/esm/components/*.js", + "./dist/esm/components/*.js": "./dist/esm/components/*.js", + "./dist/esm/elements": "./dist/esm/elements/index.js", + "./dist/esm/elements/*": "./dist/esm/elements/*.js", + "./dist/esm/elements/*.js": "./dist/esm/elements/*.js", + "./dist/esm/requesters": "./dist/esm/requesters/index.js", + "./dist/esm/requesters/*": "./dist/esm/requesters/*.js", + "./dist/esm/requesters/*.js": "./dist/esm/requesters/*.js", + "./dist/esm/types": "./dist/esm/types/index.js", + "./dist/esm/types/*": "./dist/esm/types/*.js", + "./dist/esm/types/*.js": "./dist/esm/types/*.js", + "./dist/esm/utils": "./dist/esm/utils/index.js", + "./dist/esm/utils/*": "./dist/esm/utils/*.js", + "./dist/esm/utils/*.js": "./dist/esm/utils/*.js" + }, "files": [ "dist/" ], diff --git a/packages/autocomplete-plugin-algolia-insights/package.json b/packages/autocomplete-plugin-algolia-insights/package.json index 3470fa29f..f4b8cde6f 100644 --- a/packages/autocomplete-plugin-algolia-insights/package.json +++ b/packages/autocomplete-plugin-algolia-insights/package.json @@ -17,6 +17,16 @@ "unpkg": "dist/umd/index.production.js", "jsdelivr": "dist/umd/index.production.js", "sideEffects": false, + "type": "module", + "exports": { + ".": "./dist/esm/index.js", + "./dist/esm": "./dist/esm/index.js", + "./dist/esm/*": "./dist/esm/*.js", + "./dist/esm/*.js": "./dist/esm/*.js", + "./dist/esm/types": "./dist/esm/types/index.js", + "./dist/esm/types/*": "./dist/esm/types/*.js", + "./dist/esm/types/*.js": "./dist/esm/types/*.js" + }, "files": [ "dist/" ], diff --git a/packages/autocomplete-plugin-query-suggestions/package.json b/packages/autocomplete-plugin-query-suggestions/package.json index 43b9e6f5b..854725272 100644 --- a/packages/autocomplete-plugin-query-suggestions/package.json +++ b/packages/autocomplete-plugin-query-suggestions/package.json @@ -17,6 +17,16 @@ "unpkg": "dist/umd/index.production.js", "jsdelivr": "dist/umd/index.production.js", "sideEffects": false, + "type": "module", + "exports": { + ".": "./dist/esm/index.js", + "./dist/esm": "./dist/esm/index.js", + "./dist/esm/*": "./dist/esm/*.js", + "./dist/esm/*.js": "./dist/esm/*.js", + "./dist/esm/types": "./dist/esm/types/index.js", + "./dist/esm/types/*": "./dist/esm/types/*.js", + "./dist/esm/types/*.js": "./dist/esm/types/*.js" + }, "files": [ "dist/" ], diff --git a/packages/autocomplete-plugin-recent-searches/package.json b/packages/autocomplete-plugin-recent-searches/package.json index b883bebc4..b5b5c4b90 100644 --- a/packages/autocomplete-plugin-recent-searches/package.json +++ b/packages/autocomplete-plugin-recent-searches/package.json @@ -17,6 +17,16 @@ "unpkg": "dist/umd/index.production.js", "jsdelivr": "dist/umd/index.production.js", "sideEffects": false, + "type": "module", + "exports": { + ".": "./dist/esm/index.js", + "./dist/esm": "./dist/esm/index.js", + "./dist/esm/*": "./dist/esm/*.js", + "./dist/esm/*.js": "./dist/esm/*.js", + "./dist/esm/types": "./dist/esm/types/index.js", + "./dist/esm/types/*": "./dist/esm/types/*.js", + "./dist/esm/types/*.js": "./dist/esm/types/*.js" + }, "files": [ "dist/" ], diff --git a/packages/autocomplete-plugin-redirect-url/package.json b/packages/autocomplete-plugin-redirect-url/package.json index 4887fba6d..dcb6a7f19 100644 --- a/packages/autocomplete-plugin-redirect-url/package.json +++ b/packages/autocomplete-plugin-redirect-url/package.json @@ -17,6 +17,16 @@ "unpkg": "dist/umd/index.production.js", "jsdelivr": "dist/umd/index.production.js", "sideEffects": false, + "type": "module", + "exports": { + ".": "./dist/esm/index.js", + "./dist/esm": "./dist/esm/index.js", + "./dist/esm/*": "./dist/esm/*.js", + "./dist/esm/*.js": "./dist/esm/*.js", + "./dist/esm/types": "./dist/esm/types/index.js", + "./dist/esm/types/*": "./dist/esm/types/*.js", + "./dist/esm/types/*.js": "./dist/esm/types/*.js" + }, "files": [ "dist/" ], diff --git a/packages/autocomplete-plugin-tags/package.json b/packages/autocomplete-plugin-tags/package.json index 86ccb4568..e51388048 100644 --- a/packages/autocomplete-plugin-tags/package.json +++ b/packages/autocomplete-plugin-tags/package.json @@ -19,6 +19,20 @@ "sideEffects": [ "*.css" ], + "type": "module", + "exports": { + ".": "./dist/esm/index.js", + "./dist/esm": "./dist/esm/index.js", + "./dist/esm/*": "./dist/esm/*.js", + "./dist/esm/*.js": "./dist/esm/*.js", + "./dist/esm/types": "./dist/esm/types/index.js", + "./dist/esm/types/*": "./dist/esm/types/*.js", + "./dist/esm/types/*.js": "./dist/esm/types/*.js", + "./theme.css": "./dist/theme.css", + "./theme.min.css": "./dist/theme.min.css", + "./dist/theme.css": "./dist/theme.css", + "./dist/theme.min.css": "./dist/theme.min.css" + }, "files": [ "dist/" ], diff --git a/packages/autocomplete-preset-algolia/package.json b/packages/autocomplete-preset-algolia/package.json index 79df68ff0..22bb06863 100644 --- a/packages/autocomplete-preset-algolia/package.json +++ b/packages/autocomplete-preset-algolia/package.json @@ -10,6 +10,31 @@ "url": "https://www.algolia.com" }, "sideEffects": false, + "type": "module", + "exports": { + ".": "./dist/esm/index.js", + "./dist/esm": "./dist/esm/index.js", + "./dist/esm/*": "./dist/esm/*.js", + "./dist/esm/*.js": "./dist/esm/*.js", + "./dist/esm/constants": "./dist/esm/constants/index.js", + "./dist/esm/constants/*": "./dist/esm/constants/*.js", + "./dist/esm/constants/*.js": "./dist/esm/constants/*.js", + "./dist/esm/highlight": "./dist/esm/highlight/index.js", + "./dist/esm/highlight/*": "./dist/esm/highlight/*.js", + "./dist/esm/highlight/*.js": "./dist/esm/highlight/*.js", + "./dist/esm/requester": "./dist/esm/requester/index.js", + "./dist/esm/requester/*": "./dist/esm/requester/*.js", + "./dist/esm/requester/*.js": "./dist/esm/requester/*.js", + "./dist/esm/search": "./dist/esm/search/index.js", + "./dist/esm/search/*": "./dist/esm/search/*.js", + "./dist/esm/search/*.js": "./dist/esm/search/*.js", + "./dist/esm/types": "./dist/esm/types/index.js", + "./dist/esm/types/*": "./dist/esm/types/*.js", + "./dist/esm/types/*.js": "./dist/esm/types/*.js", + "./dist/esm/utils": "./dist/esm/utils/index.js", + "./dist/esm/utils/*": "./dist/esm/utils/*.js", + "./dist/esm/utils/*.js": "./dist/esm/utils/*.js" + }, "files": [ "dist/" ], diff --git a/packages/autocomplete-shared/package.json b/packages/autocomplete-shared/package.json index 2e0e50a2c..f7a814680 100644 --- a/packages/autocomplete-shared/package.json +++ b/packages/autocomplete-shared/package.json @@ -14,6 +14,22 @@ "module": "dist/esm/index.js", "main": "dist/esm/index.js", "sideEffects": false, + "type": "module", + "exports": { + ".": "./dist/esm/index.js", + "./dist/esm": "./dist/esm/index.js", + "./dist/esm/*": "./dist/esm/*.js", + "./dist/esm/*.js": "./dist/esm/*.js", + "./dist/esm/core": "./dist/esm/core/index.js", + "./dist/esm/core/*": "./dist/esm/core/*.js", + "./dist/esm/core/*.js": "./dist/esm/core/*.js", + "./dist/esm/js": "./dist/esm/js/index.js", + "./dist/esm/js/*": "./dist/esm/js/*.js", + "./dist/esm/js/*.js": "./dist/esm/js/*.js", + "./dist/esm/preset-algolia": "./dist/esm/preset-algolia/index.js", + "./dist/esm/preset-algolia/*": "./dist/esm/preset-algolia/*.js", + "./dist/esm/preset-algolia/*.js": "./dist/esm/preset-algolia/*.js" + }, "files": [ "dist/" ], diff --git a/packages/autocomplete-theme-classic/package.json b/packages/autocomplete-theme-classic/package.json index e420bcb42..a62d21858 100644 --- a/packages/autocomplete-theme-classic/package.json +++ b/packages/autocomplete-theme-classic/package.json @@ -12,6 +12,14 @@ "sideEffects": [ "*.css" ], + "type": "module", + "exports": { + ".": "./dist/theme.min.css", + "./theme.css": "./dist/theme.min.css", + "./theme.min.css": "./dist/theme.min.css", + "./dist/theme.css": "./dist/theme.min.css", + "./dist/theme.min.css": "./dist/theme.min.css" + }, "files": [ "dist/" ], From 397183055e5d9efd7a856b21b583131fbe9d593f Mon Sep 17 00:00:00 2001 From: Haroen Viaene Date: Wed, 25 Oct 2023 17:54:11 +0200 Subject: [PATCH 3/3] add package.json to exports --- packages/autocomplete-core/package.json | 1 + packages/autocomplete-js/package.json | 1 + packages/autocomplete-plugin-algolia-insights/package.json | 1 + packages/autocomplete-plugin-query-suggestions/package.json | 1 + packages/autocomplete-plugin-recent-searches/package.json | 1 + packages/autocomplete-plugin-redirect-url/package.json | 1 + packages/autocomplete-plugin-tags/package.json | 1 + packages/autocomplete-preset-algolia/package.json | 1 + packages/autocomplete-shared/package.json | 1 + packages/autocomplete-theme-classic/package.json | 1 + 10 files changed, 10 insertions(+) diff --git a/packages/autocomplete-core/package.json b/packages/autocomplete-core/package.json index f9f116c3a..af14d8cde 100644 --- a/packages/autocomplete-core/package.json +++ b/packages/autocomplete-core/package.json @@ -19,6 +19,7 @@ "type": "module", "exports": { ".": "./dist/esm/index.js", + "./package.json": "./package.json", "./dist/esm": "./dist/esm/index.js", "./dist/esm/*": "./dist/esm/*.js", "./dist/esm/*.js": "./dist/esm/*.js", diff --git a/packages/autocomplete-js/package.json b/packages/autocomplete-js/package.json index 41b600d23..ef83c306d 100644 --- a/packages/autocomplete-js/package.json +++ b/packages/autocomplete-js/package.json @@ -20,6 +20,7 @@ "type": "module", "exports": { ".": "./dist/esm/index.js", + "./package.json": "./package.json", "./dist/esm": "./dist/esm/index.js", "./dist/esm/*": "./dist/esm/*.js", "./dist/esm/*.js": "./dist/esm/*.js", diff --git a/packages/autocomplete-plugin-algolia-insights/package.json b/packages/autocomplete-plugin-algolia-insights/package.json index f4b8cde6f..d5cb4b70b 100644 --- a/packages/autocomplete-plugin-algolia-insights/package.json +++ b/packages/autocomplete-plugin-algolia-insights/package.json @@ -20,6 +20,7 @@ "type": "module", "exports": { ".": "./dist/esm/index.js", + "./package.json": "./package.json", "./dist/esm": "./dist/esm/index.js", "./dist/esm/*": "./dist/esm/*.js", "./dist/esm/*.js": "./dist/esm/*.js", diff --git a/packages/autocomplete-plugin-query-suggestions/package.json b/packages/autocomplete-plugin-query-suggestions/package.json index 854725272..04e29cd2d 100644 --- a/packages/autocomplete-plugin-query-suggestions/package.json +++ b/packages/autocomplete-plugin-query-suggestions/package.json @@ -20,6 +20,7 @@ "type": "module", "exports": { ".": "./dist/esm/index.js", + "./package.json": "./package.json", "./dist/esm": "./dist/esm/index.js", "./dist/esm/*": "./dist/esm/*.js", "./dist/esm/*.js": "./dist/esm/*.js", diff --git a/packages/autocomplete-plugin-recent-searches/package.json b/packages/autocomplete-plugin-recent-searches/package.json index b5b5c4b90..695b70868 100644 --- a/packages/autocomplete-plugin-recent-searches/package.json +++ b/packages/autocomplete-plugin-recent-searches/package.json @@ -20,6 +20,7 @@ "type": "module", "exports": { ".": "./dist/esm/index.js", + "./package.json": "./package.json", "./dist/esm": "./dist/esm/index.js", "./dist/esm/*": "./dist/esm/*.js", "./dist/esm/*.js": "./dist/esm/*.js", diff --git a/packages/autocomplete-plugin-redirect-url/package.json b/packages/autocomplete-plugin-redirect-url/package.json index dcb6a7f19..0493e19f1 100644 --- a/packages/autocomplete-plugin-redirect-url/package.json +++ b/packages/autocomplete-plugin-redirect-url/package.json @@ -20,6 +20,7 @@ "type": "module", "exports": { ".": "./dist/esm/index.js", + "./package.json": "./package.json", "./dist/esm": "./dist/esm/index.js", "./dist/esm/*": "./dist/esm/*.js", "./dist/esm/*.js": "./dist/esm/*.js", diff --git a/packages/autocomplete-plugin-tags/package.json b/packages/autocomplete-plugin-tags/package.json index e51388048..db85a6528 100644 --- a/packages/autocomplete-plugin-tags/package.json +++ b/packages/autocomplete-plugin-tags/package.json @@ -22,6 +22,7 @@ "type": "module", "exports": { ".": "./dist/esm/index.js", + "./package.json": "./package.json", "./dist/esm": "./dist/esm/index.js", "./dist/esm/*": "./dist/esm/*.js", "./dist/esm/*.js": "./dist/esm/*.js", diff --git a/packages/autocomplete-preset-algolia/package.json b/packages/autocomplete-preset-algolia/package.json index 22bb06863..810e3f897 100644 --- a/packages/autocomplete-preset-algolia/package.json +++ b/packages/autocomplete-preset-algolia/package.json @@ -13,6 +13,7 @@ "type": "module", "exports": { ".": "./dist/esm/index.js", + "./package.json": "./package.json", "./dist/esm": "./dist/esm/index.js", "./dist/esm/*": "./dist/esm/*.js", "./dist/esm/*.js": "./dist/esm/*.js", diff --git a/packages/autocomplete-shared/package.json b/packages/autocomplete-shared/package.json index f7a814680..c98c689b0 100644 --- a/packages/autocomplete-shared/package.json +++ b/packages/autocomplete-shared/package.json @@ -17,6 +17,7 @@ "type": "module", "exports": { ".": "./dist/esm/index.js", + "./package.json": "./package.json", "./dist/esm": "./dist/esm/index.js", "./dist/esm/*": "./dist/esm/*.js", "./dist/esm/*.js": "./dist/esm/*.js", diff --git a/packages/autocomplete-theme-classic/package.json b/packages/autocomplete-theme-classic/package.json index a62d21858..2e92507ba 100644 --- a/packages/autocomplete-theme-classic/package.json +++ b/packages/autocomplete-theme-classic/package.json @@ -15,6 +15,7 @@ "type": "module", "exports": { ".": "./dist/theme.min.css", + "./package.json": "./package.json", "./theme.css": "./dist/theme.min.css", "./theme.min.css": "./dist/theme.min.css", "./dist/theme.css": "./dist/theme.min.css",