imba
Version:
89 lines (73 loc) • 2.79 kB
text/typescript
import { promises as fs } from 'fs';
// import { compile } from 'imba/compiler';
// import {compile} from '../../../imba/dist/compiler.mjs'
import {compile} from 'imba/compiler'
import { DepOptimizationOptions } from 'vite';
import { Compiled } from './compile';
import { log } from './log';
import { CompileOptions, ResolvedOptions } from './options';
import { toESBuildError } from './error';
type EsbuildOptions = NonNullable<DepOptimizationOptions['esbuildOptions']>;
type EsbuildPlugin = NonNullable<EsbuildOptions['plugins']>[number];
export const facadeEsbuildImbaPluginName = 'vite-plugin-imba:facade';
export function esbuildImbaPlugin(options: ResolvedOptions): EsbuildPlugin {
return {
name: 'vite-plugin-imba:optimize-imba',
setup(build) {
// Skip in scanning phase as Vite already handles scanning Imba files.
// Otherwise this would heavily slow down the scanning phase.
// if (build.initialOptions.plugins?.some((v) => v.name === 'vite:dep-scan')) return;
const imbaExtensions = (options.extensions ?? ['.imba', '.imba1']).map((ext) => ext.slice(1));
const imbaFilter = new RegExp(`\\.(` + imbaExtensions.join('|') + `)(\\?.*)?$`);
build.onLoad({ filter: imbaFilter }, async ({ path: filename }) => {
const code = await fs.readFile(filename, 'utf8');
try {
const contents = await compileImba(options, { filename, code });
return { contents };
} catch (e) {
return { errors: [toESBuildError(e, options)] };
}
});
}
};
}
async function compileImba(
options: ResolvedOptions,
{ filename, code }: { filename: string; code: string }
): Promise<string> {
const compileOptions: CompileOptions = {
...options.compilerOptions,
css: true,
filename,
format: 'esm',
generate: 'dom',
sourcePath: filename,
};
let preprocessed;
// if (options.preprocess) {
// try {
// preprocessed = await preprocess(code, options.preprocess, { filename });
// } catch (e) {
// e.message = `Error while preprocessing ${filename}${e.message ? ` - ${e.message}` : ''}`;
// throw e;
// }
// if (preprocessed.map) compileOptions.sourcemap = preprocessed.map;
// }
const finalCode = preprocessed ? preprocessed.code : code;
const dynamicCompileOptions = await options.experimental?.dynamicCompileOptions?.({
filename,
code: finalCode,
compileOptions
});
if (dynamicCompileOptions && log.debug.enabled) {
log.debug(`dynamic compile options for ${filename}: ${JSON.stringify(dynamicCompileOptions)}`);
}
const finalCompileOptions = dynamicCompileOptions
? {
...compileOptions,
...dynamicCompileOptions
}
: compileOptions;
const compiled = compile(finalCode, finalCompileOptions) as Compiled;
return compiled.js.code + '//# sourceMappingURL=' + compiled.js.map.toUrl();
}