Skip to content

Commit 342057b

Browse files
authored
fix: resolve wxt modules from the root (#1417)
1 parent 151b139 commit 342057b

File tree

3 files changed

+35
-16
lines changed

3 files changed

+35
-16
lines changed

packages/wxt/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
"get-port-please": "^3.1.2",
105105
"giget": "^1.2.3",
106106
"hookable": "^5.5.3",
107+
"import-meta-resolve": "^4.1.0",
107108
"is-wsl": "^3.1.0",
108109
"jiti": "^1.21.6",
109110
"json5": "^2.2.3",

packages/wxt/src/core/resolve-config.ts

+26-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { loadConfig } from 'c12';
2+
import { resolve as esmResolve } from 'import-meta-resolve';
23
import {
34
InlineConfig,
45
ResolvedConfig,
@@ -28,6 +29,7 @@ import { getEslintVersion } from './utils/eslint';
2829
import { safeStringToNumber } from './utils/number';
2930
import { loadEnv } from './utils/env';
3031
import { getPort } from 'get-port-please';
32+
import { fileURLToPath, pathToFileURL } from 'node:url';
3133

3234
/**
3335
* Given an inline config, discover the config file if necessary, merge the results, resolve any
@@ -84,7 +86,7 @@ export async function resolveConfig(
8486
inlineConfig.root ?? userConfig.root ?? process.cwd(),
8587
);
8688
const wxtDir = path.resolve(root, '.wxt');
87-
const wxtModuleDir = await resolveWxtModuleDir();
89+
const wxtModuleDir = resolveWxtModuleDir();
8890
const srcDir = path.resolve(root, mergedConfig.srcDir ?? root);
8991
const entrypointsDir = path.resolve(
9092
srcDir,
@@ -156,6 +158,7 @@ export async function resolveConfig(
156158
}
157159

158160
const userModules = await resolveWxtUserModules(
161+
root,
159162
modulesDir,
160163
mergedConfig.modules,
161164
);
@@ -420,21 +423,22 @@ async function getUnimportEslintOptions(
420423
/**
421424
* Returns the path to `node_modules/wxt`.
422425
*/
423-
async function resolveWxtModuleDir() {
424-
// TODO: Use this once we're fully running in ESM, see https://github.com/wxt-dev/wxt/issues/277
425-
// const url = import.meta.resolve('wxt', import.meta.url);
426-
// resolve() returns the "wxt/dist/index.mjs" file, not the package's root
427-
// directory, which we want to return from this function.
428-
// return path.resolve(fileURLToPath(url), '../..');
429-
430-
const requireResolve =
431-
globalThis.require?.resolve ??
432-
(await import('node:module')).default.createRequire(import.meta.url)
433-
.resolve;
434-
435-
// resolve() returns the "wxt/dist/index.mjs" file, not the package's root
426+
function resolveWxtModuleDir() {
427+
// TODO: Drop the __filename expression once we're fully running in ESM
428+
// (see https://github.com/wxt-dev/wxt/issues/277)
429+
const importer =
430+
typeof __filename === 'string'
431+
? pathToFileURL(__filename).href
432+
: import.meta.url;
433+
434+
// TODO: Switch to import.meta.resolve() once the parent argument is unflagged
435+
// (e.g. --experimental-import-meta-resolve) and all Node.js versions we support
436+
// have it.
437+
const url = esmResolve('wxt', importer);
438+
439+
// esmResolve() returns the "wxt/dist/index.mjs" file, not the package's root
436440
// directory, which we want to return from this function.
437-
return path.resolve(requireResolve('wxt'), '../..');
441+
return path.resolve(fileURLToPath(url), '../..');
438442
}
439443

440444
async function isDirMissing(dir: string) {
@@ -479,14 +483,20 @@ export async function mergeBuilderConfig(
479483
}
480484

481485
export async function resolveWxtUserModules(
486+
root: string,
482487
modulesDir: string,
483488
modules: string[] = [],
484489
): Promise<WxtModuleWithMetadata<any>[]> {
490+
const importer = pathToFileURL(path.join(root, 'index.js')).href;
491+
485492
// Resolve node_modules modules
486493
const npmModules = await Promise.all<WxtModuleWithMetadata<any>>(
487494
modules.map(async (moduleId) => {
495+
// Resolve before importing to allow for a local WXT clone to be
496+
// symlinked into a project.
497+
const resolvedModulePath = esmResolve(moduleId, importer);
488498
const mod: { default: WxtModule<any> } = await import(
489-
/* @vite-ignore */ moduleId
499+
/* @vite-ignore */ resolvedModulePath
490500
);
491501
if (mod.default == null) {
492502
throw Error('Module missing default export: ' + moduleId);

pnpm-lock.yaml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)