Overslaan naar hoofdinhoud

Writing your own extension

Openen in ChatGPT
26.01 Experimenteel

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.

Experimentele API

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:

pom.xml
<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:

src/main/resources/frontend-extensions/svelte.mjs
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:

SvelteExtension.java
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 die webforj-scss speelt voor de SCSS-extensie.
  • isEnabledByDefault activeert de extensie wanneer een .svelte-bron aanwezig is, de activeren op bestandstype regel die de gecureerde extensies volgen.
  • onWillBundle verklaart 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:

META-INF/services/com.webforj.bundle.bun.BundleExtension
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:

src/main/frontend/bun.config.ts
export const options = {
'svelte': { /* bun-plugin-svelte options */ }
};