Writing your own extension
Je voegt een compiler voor een andere soort bron toe door een extensie te verzenden, op hetzelfde contract dat de ingebouwde extensies gebruiken, zodat een aangepaste extensie precies zoals een verzonden extensie wordt gelezen.
Deze pagina bouwt een Svelte extensie als een compleet voorbeeld. Svelte is een componentframework waarvan de .svelte-bestanden tijdens de bouwtijd naar JavaScript worden gecompileerd. De bundler behandelt die bron niet op zichzelf, dus het consumeren van een Svelte-component vanuit webforJ betekent het leren aan de build om het te compileren, wat precies is wat een extensie doet. Dat maakt het een passend voorbeeld: een nieuw soort bron, geleerd aan de build door de extensie die je schrijft, en vervolgens gebonden aan een klasse op dezelfde manier als elk ander invoerpunt.
De extensie-API is experimenteel en kan tussen versies veranderen terwijl deze zich vestigt. Het mechanisme zelf is hier om te blijven, de ingebouwde extensies zijn gebaseerd op hetzelfde contract, maar de methodesignaturen kunnen verschuiven, dus verwacht aan te passen een aangepaste extensie wanneer je webforJ upgradt.
De afhankelijkheid tijdens de bouwtijd
Om een extensie te schrijven compileer je tegen de bundler-API. Voeg het toe met provided scope, aangezien de build deze levert en je het niet verzendt:
<dependency>
<groupId>com.webforj</groupId>
<artifactId>webforj-bundle-bun</artifactId>
<version>${webforj.version}</version>
<scope>provided</scope>
</dependency>
De pluginwrapper
Een extensie draagt bij aan een Bun-plugin. Houd de plugin in een kleine .mjs bron. Het exporteert standaard een factory die de build aanroept met de opties die je voor deze extensie instelt, en retourneert de Bun-plugin:
import { SveltePlugin } from 'bun-plugin-svelte';
export default (options) => SveltePlugin({ forceSide: 'client', ...options });
De extensie
Implementeer BundleExtension. Het benoemt zichzelf met een id, beslist wanneer het activeert, en in onWillBundle verklaart het zijn pakketten en draagt het de wrapper bij:
public class SvelteExtension implements BundleExtension {
@Override
public String getId() {
return "svelte";
}
@Override
public boolean isEnabledByDefault(BundleContext context) {
return context.getSourceExtensions().contains("svelte");
}
@Override
public void onWillBundle(BundleContext context) {
context.addPackage(new BundlePackageDeclaration()
.setName("bun-plugin-svelte")
.setVersion("^0.0.6")
.setDev(true));
context.addPackage(new BundlePackageDeclaration()
.setName("svelte")
.setVersion("^5.56.2")
.setDev(true));
context.addPlugin(getId(), readWrapper("/frontend-extensions/svelte.mjs"));
}
private String readWrapper(String path) {
try (InputStream in = getClass().getResourceAsStream(path)) {
if (in == null) {
throw new IOException("missing wrapper " + path);
}
return new String(in.readAllBytes(), StandardCharsets.UTF_8);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
In dit voorbeeld:
getId()retourneert de id die wordt gebruikt om de extensie in of uit te schakelen en om zijn opties te koppelen, dezelfde rol diewebforj-scssspeelt voor de SCSS-extensie.isEnabledByDefaultactiveert de extensie wanneer een.svelte-bron aanwezig is, de activeren op bestandstype regel die de gecureerde extensies volgen.onWillBundleverklaart de bouwafhankelijkheden die de compiler nodig heeft en draagt de Bun-plugin bij onder de id van de extensie.
De extensie registreren
De build ontdekt een extensie als een service op het classpath. Voeg een servicebestand toe met de naam BundleExtension, met de volledig gekwalificeerde naam van de klasse:
com.example.SvelteExtension
Met het servicebestand op zijn plaats, compileert een .svelte-bron nu, en de view consumeert het element dat de component registreert.
Opties
De extensie forward de opties die je onder zijn id instelt rechtstreeks naar de Bun-plugin. Stel ze in bun.config.ts in:
export const options = {
'svelte': { /* bun-plugin-svelte options */ }
};