diff --git a/e2e/tests/user-config.test.ts b/e2e/tests/user-config.test.ts index 1a7b590c..491e9ec6 100644 --- a/e2e/tests/user-config.test.ts +++ b/e2e/tests/user-config.test.ts @@ -56,18 +56,23 @@ describe('User Config', () => { `); }); - it('should accept a function for a manifest', async () => { + it('should merge inline and user config based manifests', async () => { const project = new TestProject(); + project.addFile( + 'wxt.config.ts', + `import { defineConfig } from 'wxt'; + export default defineConfig({ + manifest: ({ mode, browser }) => ({ + // @ts-expect-error + example_customization: [mode, browser], + }) + })`, + ); await project.build({ // @ts-expect-error: Specifically setting an invalid field for the test - it should show up in the snapshot - manifest: ({ mode, browser, manifestVersion, command }) => ({ - example_customization: [ - mode, - browser, - String(manifestVersion), - command, - ], + manifest: ({ manifestVersion, command }) => ({ + example_customization: [String(manifestVersion), command], }), }); diff --git a/src/core/utils/getInternalConfig.ts b/src/core/utils/getInternalConfig.ts index 4b30640f..c652a751 100644 --- a/src/core/utils/getInternalConfig.ts +++ b/src/core/utils/getInternalConfig.ts @@ -1,9 +1,11 @@ import { + ConfigEnv, ExtensionRunnerConfig, InlineConfig, InternalConfig, UserConfig, UserManifest, + UserManifestFn, } from '../types'; import path, { resolve } from 'node:path'; import * as vite from 'vite'; @@ -32,15 +34,6 @@ export async function getInternalConfig( const outDir = path.resolve(outBaseDir, `${browser}-mv${manifestVersion}`); const logger = config.logger ?? consola; - const manifest: UserManifest = await (typeof config.manifest === 'function' - ? config.manifest({ - browser, - command, - manifestVersion, - mode, - }) - : config.manifest ?? {}); - const baseConfig: InternalConfigNoUserDirs = { root, outDir, @@ -52,7 +45,6 @@ export async function getInternalConfig( command, logger, vite: config.vite ?? {}, - manifest, imports: config.imports ?? {}, runnerConfig: await loadConfig({ name: 'web-ext', @@ -92,6 +84,12 @@ export async function getInternalConfig( const wxtDir = resolve(srcDir, '.wxt'); const typesDir = resolve(wxtDir, 'types'); + // Merge manifest sources + const env: ConfigEnv = { mode, browser, manifestVersion, command }; + const userManifest = await resolveManifestConfig(env, userConfig.manifest); + const inlineManifest = await resolveManifestConfig(env, config.manifest); + const manifest = vite.mergeConfig(userManifest, inlineManifest); + const finalConfig: InternalConfig = { ...merged, srcDir, @@ -100,6 +98,7 @@ export async function getInternalConfig( wxtDir: wxtDir, typesDir, fsCache: createFsCache(wxtDir), + manifest, }; // Customize the default vite config @@ -137,5 +136,20 @@ export async function getInternalConfig( */ type InternalConfigNoUserDirs = Omit< InternalConfig, - 'srcDir' | 'publicDir' | 'entrypointsDir' | 'wxtDir' | 'typesDir' | 'fsCache' + | 'srcDir' + | 'publicDir' + | 'entrypointsDir' + | 'wxtDir' + | 'typesDir' + | 'fsCache' + | 'manifest' >; + +async function resolveManifestConfig( + env: ConfigEnv, + manifest: UserManifest | Promise | UserManifestFn | undefined, +): Promise { + return await (typeof manifest === 'function' + ? manifest(env) + : manifest ?? {}); +}