132 lines
3.3 KiB
TypeScript
132 lines
3.3 KiB
TypeScript
import {
|
|
BuildStepOutput,
|
|
EntrypointGroup,
|
|
InternalConfig,
|
|
WxtDevServer,
|
|
} from './types';
|
|
import * as vite from 'vite';
|
|
import { findOpenPort } from './utils/findOpenPort';
|
|
import { Manifest } from 'webextension-polyfill';
|
|
import { getEntrypointBundlePath } from './utils/entrypoints';
|
|
import { getContentScriptCssFiles } from './utils/manifest';
|
|
import { createWebExtRunner } from './runners/createWebExtRunner';
|
|
import { buildInternal } from './build';
|
|
|
|
export async function getServerInfo(): Promise<ServerInfo> {
|
|
const port = await findOpenPort(3000, 3010);
|
|
const hostname = 'localhost';
|
|
const origin = `http://${hostname}:${port}`;
|
|
const serverConfig: vite.InlineConfig = {
|
|
server: {
|
|
origin,
|
|
},
|
|
};
|
|
|
|
return {
|
|
port,
|
|
hostname,
|
|
origin,
|
|
viteServerConfig: serverConfig,
|
|
};
|
|
}
|
|
|
|
export async function setupServer(
|
|
serverInfo: ServerInfo,
|
|
config: InternalConfig,
|
|
): Promise<WxtDevServer> {
|
|
const runner = createWebExtRunner();
|
|
|
|
const viteServer = await vite.createServer(
|
|
vite.mergeConfig(serverInfo, config.vite),
|
|
);
|
|
|
|
const start = async () => {
|
|
await viteServer.listen(server.port);
|
|
config.logger.success(`Started dev server @ ${serverInfo.origin}`);
|
|
|
|
server.currentOutput = await buildInternal(config);
|
|
config.logger.info('Opening browser...');
|
|
await runner.openBrowser(config);
|
|
config.logger.success('Opened!');
|
|
};
|
|
|
|
const reloadExtension = () => {
|
|
viteServer.ws.send('wxt:reload-extension');
|
|
};
|
|
const reloadPage = (path: string) => {
|
|
// Can't use Vite's built-in "full-reload" event because it doesn't like our paths, it expects
|
|
// paths ending in "/index.html"
|
|
viteServer.ws.send('wxt:reload-page', path);
|
|
};
|
|
const reloadContentScript = (contentScript: Manifest.ContentScript) => {
|
|
viteServer.ws.send('wxt:reload-content-script', contentScript);
|
|
};
|
|
|
|
const server: WxtDevServer = {
|
|
...viteServer,
|
|
start,
|
|
currentOutput: {
|
|
manifest: {
|
|
manifest_version: 3,
|
|
name: '',
|
|
version: '',
|
|
},
|
|
publicAssets: [],
|
|
steps: [],
|
|
},
|
|
port: serverInfo.port,
|
|
hostname: serverInfo.hostname,
|
|
origin: serverInfo.origin,
|
|
reloadExtension,
|
|
reloadPage,
|
|
reloadContentScript,
|
|
};
|
|
|
|
return server;
|
|
}
|
|
|
|
/**
|
|
* From the server, tell the client to reload content scripts from the provided build step outputs.
|
|
*/
|
|
export function reloadContentScripts(
|
|
steps: BuildStepOutput[],
|
|
config: InternalConfig,
|
|
server: WxtDevServer,
|
|
) {
|
|
if (config.manifestVersion === 3) {
|
|
steps.forEach((step) => {
|
|
const entry = step.entrypoints;
|
|
if (Array.isArray(entry) || entry.type !== 'content-script') return;
|
|
|
|
const js = [getEntrypointBundlePath(entry, config.outDir, '.js')];
|
|
const css = getContentScriptCssFiles([entry], server.currentOutput);
|
|
|
|
server.reloadContentScript({
|
|
js,
|
|
css,
|
|
...entry.options,
|
|
});
|
|
});
|
|
} else {
|
|
server.reloadExtension();
|
|
}
|
|
}
|
|
|
|
export function reloadHtmlPages(
|
|
groups: EntrypointGroup[],
|
|
server: WxtDevServer,
|
|
config: InternalConfig,
|
|
) {
|
|
groups.flat().forEach((entry) => {
|
|
const path = getEntrypointBundlePath(entry, config.outDir, '.html');
|
|
server.reloadPage(path);
|
|
});
|
|
}
|
|
|
|
interface ServerInfo {
|
|
port: number;
|
|
hostname: string;
|
|
origin: string;
|
|
viteServerConfig: vite.InlineConfig;
|
|
}
|