Use "external" compilers in Bud

Good news, everyone, SSL is available in 5.5.0.

Here’s how you would handle adding support for .svelte to bud.js. I’m going to do this in a couple parts. Hopefully someone might consider taking the end result and packaging it up as the first official bud community supported extension :roots:?

Dependencies

Install svelte and svelte-loader to your project.

Handling .svelte

First off, we need to add support for .svelte files if Bud doesn’t already support them.

We can scope what Bud knows about with the build.resolve.extensions hook:

app.log(
  app.hooks.filter('build.resolve.extensions')
).close()

Run yarn bud build --log and you’ll see:

[root] ❯ [
  '.wasm',  '.mjs',
  '.js',    '.jsx',
  '.css',   '.json',
  '.json5', '.toml',
  '.xml',   '.csv',
  '.yml',   '.yaml',
  '.xml'
]

So, confirmed that Bud doesn’t know what .svelte is. So, we’ll add the extension using the same hook:

app.hooks.on(
  'build.resolve.extensions', 
  (extensions) => [...extensions, '.svelte']
)

Overriding the configuration

We want to add the svelte loader using the build.module.rules.oneOf hook:

app.hooks.on('build.module.rules.oneOf', (rules) => [
  ...rules,
{
  test: /\.svelte$/,
  use: [
    {
      loader: 'svelte-loader',
      options: {},
    },
  ],
})

Final config

That’s that! Here’s the final config:

/**
 * @typedef {import('@roots/bud').Bud} bud
 * @param {bud} app
 */
module.exports = async (app) => {
  /**
   * Add svelte support
   */
  app.hooks
    .on('build.module.rules.oneOf', (rules) => [
      ...rules,
      {
        test: /\.svelte$/,
        use: [
          {
            loader: 'svelte-loader',
            options: {},
          },
        ],
      },
    ])
    .hooks.on('build.resolve.extensions', (ext) => [...ext, '.svelte'])

    /**
     * Application entrypoints
     *
     * Paths are relative to your resources directory
     */
    .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();
};

Associated docs

4 Likes