feat: Virtualized content script entrypoint

Generalized the background logic so it can be reused with mulitple entrypoint types
This commit is contained in:
Aaron Klinker
2023-06-23 21:17:41 -05:00
parent ec57e8cbca
commit ca29537bbc
8 changed files with 80 additions and 2 deletions
+2 -1
View File
@@ -14,7 +14,8 @@
"author": "Aaron Klinker",
"license": "MIT",
"files": [
"dist"
"dist",
"templates"
],
"bin": "dist/cli/index.cjs",
"main": "./dist/index.cjs",
+7 -1
View File
@@ -32,10 +32,16 @@ async function buildSingleEntrypoint(
entrypoint: Entrypoint,
config: InternalConfig,
): Promise<BuildOutput> {
// Should this entrypoint be wrapped by the vite-plugins/virtualEntrypoint plugin?
const isVirtual = ['background', 'content-script'].includes(entrypoint.type);
const entry = isVirtual
? `virtual:exvite-${entrypoint.type}?${entrypoint.inputPath}`
: entrypoint.inputPath;
const libMode: vite.InlineConfig = {
build: {
lib: {
entry: entrypoint.inputPath,
entry,
formats: ['iife'],
name: entrypoint.name,
fileName: entrypoint.name,
+2
View File
@@ -79,6 +79,8 @@ export async function getInternalConfig(
merged.vite.plugins.push(plugins.download(merged));
merged.vite.plugins.push(plugins.devHtmlPrerender(merged));
merged.vite.plugins.push(plugins.unimport(merged));
merged.vite.plugins.push(plugins.virtualEntrypoin('background'));
merged.vite.plugins.push(plugins.virtualEntrypoin('content-script'));
return merged;
}
+1
View File
@@ -2,3 +2,4 @@ export * from './download';
export * from './unimport';
export * from './multipageMove';
export * from './devHtmlPrerender';
export * from './virtualEntrypoint';
+35
View File
@@ -0,0 +1,35 @@
import { Plugin } from 'vite';
import { Entrypoint } from '../types';
import fs from 'fs-extra';
import { resolve } from 'path';
/**
* Wraps a user's entrypoint with a vitual version with additional logic.
*/
export function virtualEntrypoin(type: Entrypoint['type']): Plugin {
const virtualId = `virtual:exvite-${type}?`;
const resolvedVirtualId = `\0${virtualId}`;
return {
name: `exvite:virtual-entrypoint`,
resolveId(id) {
// Id doesn't start with prefix, it looks like this:
// /path/to/project/virtual:background?/path/to/project/entrypoints/background.ts
const index = id.indexOf(virtualId);
if (index === -1) return;
const inputPath = id.substring(index + virtualId.length);
return resolvedVirtualId + inputPath;
},
async load(id) {
if (!id.startsWith(resolvedVirtualId)) return;
const inputPath = id.replace(resolvedVirtualId, '');
const template = await fs.readFile(
resolve(`node_modules/exvite/templates/virtual-${type}.ts`),
'utf-8',
);
return template.replaceAll('{{moduleId}}', inputPath);
},
};
}
+11
View File
@@ -0,0 +1,11 @@
// Types required to make templates happy.
declare module '*?raw' {
const content: any;
export default content;
}
declare module '{{moduleId}}' {
const variable: any;
export default variable;
}
+13
View File
@@ -0,0 +1,13 @@
import definition from '{{moduleId}}';
try {
const res = definition.main();
if (res instanceof Promise) {
console.warn(
"The background's main() function return a promise, but it must be synchonous",
);
}
} catch (err) {
console.error('The background script crashed on startup!\n\n', err);
throw err;
}
+9
View File
@@ -0,0 +1,9 @@
import definition from '{{moduleId}}';
(async () => {
try {
await definition.main();
} catch (err) {
console.error('The content script crashed on startup!\n\n', err);
}
})();