96 lines
2.8 KiB
TypeScript
96 lines
2.8 KiB
TypeScript
import { mkdir, writeFile } from 'node:fs/promises';
|
|
import path from 'node:path';
|
|
import { createRequire } from 'node:module';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const require = createRequire(import.meta.url);
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
const OUTPUT_DIR = path.resolve(__dirname, '../public/vendor');
|
|
|
|
interface LibraryDefinition {
|
|
packageName: string;
|
|
globalName: string;
|
|
outputFile: string;
|
|
}
|
|
|
|
interface WriteShimOptions {
|
|
outputDir: string;
|
|
silent: boolean;
|
|
}
|
|
|
|
type ShimSource = Pick<LibraryDefinition, 'packageName' | 'globalName'>;
|
|
|
|
const libraries: LibraryDefinition[] = [
|
|
{ packageName: 'vue', globalName: 'Vue', outputFile: 'vue.mjs' },
|
|
{ packageName: 'vue-router', globalName: 'VueRouter', outputFile: 'vue-router.mjs' },
|
|
{ packageName: 'pinia', globalName: 'Pinia', outputFile: 'pinia.mjs' },
|
|
];
|
|
|
|
const formatLines = (globalName: string, exports: readonly string[]): string => {
|
|
const lines: string[] = [];
|
|
lines.push(`const ${globalName} = window.${globalName};`);
|
|
lines.push(`if (!${globalName}) {`);
|
|
lines.push(` throw new Error('${globalName} runtime is not available on window.');`);
|
|
lines.push('}');
|
|
lines.push(`export default ${globalName};`);
|
|
|
|
for (const name of exports) {
|
|
lines.push(`export const ${name} = ${globalName}.${name};`);
|
|
}
|
|
|
|
lines.push('');
|
|
return lines.join('\n');
|
|
};
|
|
|
|
const generateShim = ({ packageName, globalName }: ShimSource): string => {
|
|
const mod = require(packageName) as Record<string, unknown>;
|
|
const exportNames = Object.keys(mod)
|
|
.filter((key) => key !== 'default')
|
|
.sort();
|
|
|
|
return formatLines(globalName, exportNames);
|
|
};
|
|
|
|
const writeShim = async (
|
|
{ packageName, globalName, outputFile }: LibraryDefinition,
|
|
{ outputDir, silent }: WriteShimOptions,
|
|
): Promise<void> => {
|
|
const content = generateShim({ packageName, globalName });
|
|
await writeFile(path.join(outputDir, outputFile), content, 'utf8');
|
|
|
|
if (!silent) {
|
|
console.log(`Generated ${outputFile}`);
|
|
}
|
|
};
|
|
|
|
export interface GenerateVendorShimsOptions {
|
|
outputDir?: string;
|
|
silent?: boolean;
|
|
}
|
|
|
|
export type GenerateVendorShims = (options?: GenerateVendorShimsOptions) => Promise<void>;
|
|
|
|
export const generateVendorShims: GenerateVendorShims = async (options = {}) => {
|
|
const { outputDir = OUTPUT_DIR, silent = false } = options;
|
|
|
|
await mkdir(outputDir, { recursive: true });
|
|
|
|
await Promise.all(libraries.map((library) => writeShim(library, { outputDir, silent })));
|
|
|
|
if (!silent) {
|
|
console.log(`[generate-vendor-shims] Vendor shims updated in ${outputDir}`);
|
|
}
|
|
};
|
|
|
|
const isCliExecution = Boolean(process.argv[1] && path.resolve(process.argv[1]) === __filename);
|
|
|
|
if (isCliExecution) {
|
|
void generateVendorShims().catch((error) => {
|
|
console.error('[generate-vendor-shims] Failed to generate shims', error);
|
|
process.exitCode = 1;
|
|
});
|
|
}
|