feat: Include background script in dev mode if user doesn't define one
This commit is contained in:
@@ -210,10 +210,10 @@ describe('findEntrypoints', () => {
|
||||
},
|
||||
],
|
||||
])(
|
||||
'should find and load content script entrypoint config from %s',
|
||||
'should find and load background entrypoint config from %s',
|
||||
async (path, expected) => {
|
||||
const options: ContentScriptEntrypoint['options'] = {
|
||||
matches: ['<all_urls>'],
|
||||
const options: BackgroundEntrypoint['options'] = {
|
||||
type: 'module',
|
||||
};
|
||||
globMock.mockResolvedValueOnce([path]);
|
||||
importTsFileMock.mockResolvedValue(options);
|
||||
@@ -226,6 +226,24 @@ describe('findEntrypoints', () => {
|
||||
},
|
||||
);
|
||||
|
||||
it("should include a virtual background script so dev reloading works when there isn't a background entrypoint defined by the user", async () => {
|
||||
globMock.mockResolvedValueOnce([]);
|
||||
|
||||
const entrypoints = await findEntrypoints({
|
||||
...config,
|
||||
command: 'serve',
|
||||
});
|
||||
|
||||
expect(entrypoints).toHaveLength(1);
|
||||
expect(entrypoints[0]).toEqual({
|
||||
type: 'background',
|
||||
inputPath: 'virtual:user-background',
|
||||
name: 'background',
|
||||
options: {},
|
||||
outputDir: config.outDir,
|
||||
});
|
||||
});
|
||||
|
||||
it.each<[string, GenericEntrypoint]>([
|
||||
// Sandbox
|
||||
[
|
||||
|
||||
@@ -16,9 +16,10 @@ import JSON5 from 'json5';
|
||||
import { importTsFile } from '../utils/importTsFile';
|
||||
import glob from 'fast-glob';
|
||||
import { getEntrypointName } from '../utils/entrypoints';
|
||||
import { VIRTUAL_NOOP_BACKGROUND_MODULE_ID } from '../vite-plugins/noopBackground';
|
||||
|
||||
/**
|
||||
* Return entrypoints and their configuration by looking through the
|
||||
* Return entrypoints and their configuration by looking through the project's files.
|
||||
*/
|
||||
export async function findEntrypoints(
|
||||
config: InternalConfig,
|
||||
@@ -33,6 +34,7 @@ export async function findEntrypoints(
|
||||
const existingNames: Record<string, Entrypoint | undefined> = {};
|
||||
|
||||
const entrypoints: Entrypoint[] = [];
|
||||
let hasBackground = false;
|
||||
await Promise.all(
|
||||
relativePaths.map(async (relativePath) => {
|
||||
const path = resolve(config.entrypointsDir, relativePath);
|
||||
@@ -63,6 +65,7 @@ export async function findEntrypoints(
|
||||
break;
|
||||
case 'background':
|
||||
entrypoint = await getBackgroundEntrypoint(config, path);
|
||||
hasBackground = true;
|
||||
break;
|
||||
case 'content-script':
|
||||
entrypoint = await getContentScriptEntrypoint(
|
||||
@@ -95,6 +98,11 @@ export async function findEntrypoints(
|
||||
existingNames[entrypoint.name] = entrypoint;
|
||||
}),
|
||||
);
|
||||
if (config.command === 'serve' && !hasBackground) {
|
||||
entrypoints.push(
|
||||
await getBackgroundEntrypoint(config, VIRTUAL_NOOP_BACKGROUND_MODULE_ID),
|
||||
);
|
||||
}
|
||||
return entrypoints;
|
||||
}
|
||||
|
||||
@@ -195,10 +203,17 @@ async function getBackgroundEntrypoint(
|
||||
config: InternalConfig,
|
||||
path: string,
|
||||
): Promise<BackgroundEntrypoint> {
|
||||
const { main: _, ...options } =
|
||||
await importTsFile<BackgroundScriptDefintition>(path, config);
|
||||
if (options == null) {
|
||||
throw Error('Background script does not have a default export');
|
||||
let options: Omit<BackgroundScriptDefintition, 'main'> = {};
|
||||
if (path !== VIRTUAL_NOOP_BACKGROUND_MODULE_ID) {
|
||||
const defaultExport = await importTsFile<BackgroundScriptDefintition>(
|
||||
path,
|
||||
config,
|
||||
);
|
||||
if (defaultExport == null) {
|
||||
throw Error('Background script does not have a default export');
|
||||
}
|
||||
const { main: _, ...moduleOptions } = defaultExport;
|
||||
options = moduleOptions;
|
||||
}
|
||||
return {
|
||||
type: 'background',
|
||||
@@ -257,6 +272,7 @@ const PATH_GLOB_TO_TYPE_MAP: Record<string, Entrypoint['type'] | 'ignored'> = {
|
||||
'devtools/index.html': 'devtools',
|
||||
|
||||
'background.ts': 'background',
|
||||
[VIRTUAL_NOOP_BACKGROUND_MODULE_ID]: 'background',
|
||||
|
||||
'content.ts?(x)': 'content-script',
|
||||
'content/index.ts?(x)': 'content-script',
|
||||
|
||||
@@ -142,6 +142,7 @@ export async function getInternalConfig(
|
||||
);
|
||||
finalConfig.vite.plugins.push(plugins.devServerGlobals(finalConfig));
|
||||
finalConfig.vite.plugins.push(plugins.tsconfigPaths(finalConfig));
|
||||
finalConfig.vite.plugins.push(plugins.noopBackground());
|
||||
|
||||
finalConfig.vite.define ??= {};
|
||||
getGlobals(finalConfig).forEach((global) => {
|
||||
|
||||
@@ -5,3 +5,4 @@ export * from './multipageMove';
|
||||
export * from './unimport';
|
||||
export * from './virtualEntrypoint';
|
||||
export * from './tsconfigPaths';
|
||||
export * from './noopBackground';
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { Plugin } from 'vite';
|
||||
|
||||
/**
|
||||
* In dev mode, if there's not a background script listed, we need to add one.
|
||||
*
|
||||
* This define's a virtual module that is basically just a noop.
|
||||
*/
|
||||
export function noopBackground(): Plugin {
|
||||
const virtualModuleId = VIRTUAL_NOOP_BACKGROUND_MODULE_ID;
|
||||
const resolvedVirtualModuleId = '\0' + virtualModuleId;
|
||||
return {
|
||||
name: 'wxt:noop-background',
|
||||
resolveId(id) {
|
||||
if (id === virtualModuleId) return resolvedVirtualModuleId;
|
||||
},
|
||||
load(id) {
|
||||
if (id === resolvedVirtualModuleId) {
|
||||
return `import { defineBackground } from 'wxt/client';\nexport default defineBackground(() => void 0)`;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const VIRTUAL_NOOP_BACKGROUND_MODULE_ID = 'virtual:user-background';
|
||||
Reference in New Issue
Block a user