Adding support for svelte through Bud’s APIs
The above instruction work great for quickly adding to a single project but if you want to share it it’s less than ideal. There is no way to pass options in, or any simple way to modify the rule once it has been set.
Adding support for svelte with the @roots/bud-build
API is not a big deal and solves almost all of those problems.
Handling .svelte
We still need to do this and the hook is still the best way to get it done.
app.hooks.on(
'build.resolve.extensions',
(extensions) => [...extensions, '.svelte'],
)
Registering the svelte-loader
Import the Loader
class at the top of the config:
const {Loader} = require('@roots/bud')
And now register the loader:
app.build.loaders.svelte = new Loader('svelte-loader');
Creating a “use” for the svelte-loader
Import the Item
class at the top of the config:
const {Item} = require('@roots/bud')
And register the loader item:
app.build.items.svelte = new Item({
loader: app.build.loaders.svelte,
options: {},
});
There are plenty of options you can use to configure svelte-loader
. Check out the svelte-loader README. You can place options
in the options
property.
Creating a Rule to “use” the loader
Rule
is kind of fancy and has a helper to make it easy to add, so you don’t need to require Rule
from @roots/bud-build
. One day Item
and Loader
will get the same treatment.
app.build.setRule('svelte', {
test: /\.svelte$/,
use: [app.build.items.svelte],
});
Final config
const {Loader, Item} = require('@roots/bud-build');
/**
* @typedef {import('@roots/bud').Bud} bud
* @param {bud} app
*/
module.exports = async (app) => {
/* Add `.svelte` extension */
app.hooks.on('build.resolve.extensions', (ext) => [...ext, '.svelte']);
/* Add svelte loader */
app.build.loaders.svlete = new Loader('svelte-loader');
/* Add svelte item */
app.build.items.svelte = new Item({
loader: app.build.loaders.svlete,
options: {},
});
/* Add svelte rule */
app.build.setRule('svelte', {
test: /\.svelte$/,
use: [app.build.items.svelte],
});
/**
* Application entrypoints
*
* Paths are relative to your resources directory
*/
app
.entry({
app: ['@scripts/app', '@styles/app'],
editor: ['@scripts/editor', '@styles/editor'],
})
/**
* These files should be processed as part of the build
* even if they are not explicitly imported in application assets.
*/
.assets('images')
/**
* These files will trigger a full page reload
* when modified.
*/
.watch('resources/views/**/*', 'app/**/*')
/**
* Target URL to be proxied by the dev server.
*
* This is your local dev server.
*/
.proxy('http://example.test')
/**
* Development URL
*/
.serve('http://example.test:3000')
/**
* Generate WordPress `theme.json`
*
* @note This overwrites `theme.json` on every build.
*/
.themeJson()
/**
* Set `theme.json` colors from `tailwind.config.js` values
*/
.useTailwindColors();
};
What makes it better
It’s arguably easier to read and maintain, but other than that you have retained the ability to modify all of the above. It’s no longer a one way ticket.
For instance, now you can set different options after the fact:
app.build.items.svelte.setOptions({
emitCss: true,
})
Or add additional directories to look for modules in:
app.build.rules.svelte.setInclude(['node_modules', 'src'])
It’s this extensibility that makes it ideal for sharing and what makes it possible for others to use it in their own extensions.
Associated documentation