Development server integration providing file watching, processing, and build coordination for Chrome extension assets with HMR support. Manages the complete lifecycle of extension files from source to output during development and production builds.
Functions to coordinate build completion and file availability for Chrome extension development.
/**
* Wait for all extension files to be processed and written
* @returns Promise that resolves when all files are ready
*/
function allFilesReady(): Promise<void>;
/**
* Wait for a specific file and its dependencies to be written
* @param script - File identifier string for the target script
* @returns Promise that resolves when the specified file is ready
*/
function filesReady(script: string): Promise<void>;
// Alias - the actual export is fileReady, aliased as filesReady
const fileReady = filesReady;
type FileWriterId = string;Usage Examples:
import { allFilesReady, filesReady } from "@crxjs/vite-plugin";
// Wait for all files in development
async function initializeExtension() {
await allFilesReady();
console.log("All extension files are ready");
// Safe to load extension or perform operations
}
// Wait for specific content script
async function loadContentScript() {
await filesReady("src/content.ts");
console.log("Content script is ready");
// Content script and its dependencies are available
}
// In a Vite plugin or build script
export default defineConfig({
plugins: [
crx({ manifest }),
{
name: "post-build",
closeBundle: async () => {
await allFilesReady();
console.log("Extension build complete");
},
},
],
});The file writer system manages different types of extension assets and coordinates their processing.
interface OutputFile {
fileName: string;
source: string | Uint8Array;
type: 'asset' | 'chunk';
}
interface ManifestFiles {
contentScripts: string[];
contentStyles: string[];
html: string[];
icons: string[];
locales: string[];
rulesets: string[];
background: string[];
webAccessibleResources: string[];
}
interface WebAccessibleFiles {
webScripts: string[];
webResources: string[];
}File Types Managed:
The file writer integrates with Vite's development server to provide HMR and file watching.
interface FileWriterStartOptions {
server: ViteDevServer;
}
// Internal file writer functions (not directly exported)
interface FileWriterSystem {
start(options: FileWriterStartOptions): Promise<void>;
write(files: OutputFile[]): Promise<void>;
close(): Promise<void>;
}Development Features:
The file writer processes different types of files through specialized pipelines.
Content Script Processing:
Extension Page Processing:
Asset Processing:
The file writer coordinates between development and production builds.
type BuildMode = 'development' | 'production';
interface BuildContext {
mode: BuildMode;
outDir: string;
publicDir: string;
isProduction: boolean;
}Development Mode:
Production Mode:
The file writer includes comprehensive error handling and validation.
File Validation:
Error Recovery:
Usage Example:
import { defineConfig } from "vite";
import { crx, defineManifest, allFilesReady } from "@crxjs/vite-plugin";
export default defineConfig({
plugins: [
crx({ manifest }),
{
name: "extension-validator",
buildStart: async () => {
console.log("Starting extension build...");
},
generateBundle: async () => {
try {
await allFilesReady();
console.log("All extension files validated and ready");
} catch (error) {
console.error("Extension build failed:", error);
throw error;
}
},
},
],
build: {
rollupOptions: {
onwarn(warning, warn) {
// Handle build warnings
if (warning.code === 'UNRESOLVED_IMPORT') {
console.warn(`Unresolved import: ${warning.message}`);
}
warn(warning);
},
},
},
});Custom File Processors:
import { CrxPlugin } from "@crxjs/vite-plugin";
const customFileProcessor: CrxPlugin = {
name: "custom-file-processor",
renderCrxDevScript(code, script) {
if (script.type === 'module') {
// Add custom processing for module scripts
return `// Custom header\n${code}\n// Custom footer`;
}
return code;
},
generateBundle(options, bundle) {
// Process output bundle
Object.keys(bundle).forEach(fileName => {
const file = bundle[fileName];
if (file.type === 'chunk' && fileName.includes('content')) {
// Custom processing for content script chunks
file.code = `/* Processed */ ${file.code}`;
}
});
},
};File System Utilities:
The file writer provides utilities for working with extension file structures, though these are primarily internal APIs used by the plugin system.