esm-loader-svelte

Chainable ESModule Loader for Svelte and SvelteKit

Usage no npm install needed!

<script type="module">
  import esmLoaderSvelte from 'https://cdn.skypack.dev/esm-loader-svelte';
</script>

README

esm-loader-svelte

Node.js ESModule Loader for importing and loading Svelte (.svelte) and SvelteKit files, and transpiling on the fly.

Warning! Using experimental Node.js features and flags, API will likely change. This may be helpful for development and testing, but should not be used in production.

Usage

npm install --save-dev esm-loader-svelte

We want to import a .svelte file with Node.js:

<!-- Component.svelte -->
<script>
  const words = 'Hello'
</script>

<h1>{words} World!</h1>

<style>
  h1 {
    color: blue;
  }
</style>
// index.js
import Component from './Component.svelte'

// render(Component) to DOM, etc.

Standalone

NODE_OPTIONS="--experimental-loader esm-loader-svelte" node index.js

Chainable

This loader can be configured, and chained with other loaders, using node-esm-loader.

npm install --save-dev node-esm-loader
// .loaderrc.js
export default {
  loaders: ['esm-loader-svelte'],
}
NODE_OPTIONS="--experimental-loader node-esm-loader" node index.js

Option: Debug

// .loaderrc.js
export default {
  loaders: [
    {
      loader: 'esm-loader-svelte',
      options: {
        debug: true,
      },
    },
  ],
}

Option: Preprocess

Preprocessing options can be supplied, for usage with something like SvelteKit's svelte-preprocess.

Supply preprocessing options via node-esm-loader config file .loaderrc.js:

// .loaderrc.js
import preprocess from 'svelte-preprocess'
import { resolve } from 'path'

export default {
  loaders: [
    {
      loader: 'esm-loader-svelte',
      options: {
        preprocess: preprocess({
          postcss: true,
          typescript: {
            tsconfigDirectory: resolve('./'),
            tsconfigFile: 'tsconfig.json',
          },
        }),
      },
    },
  ],
}

SvelteKit

If options.preprocess is NOT found in .loaderrc.js, then we will try to load a SvelteKit svelte.config.js file, and use the preprocess settings found therein:

// svelte.config.js
import preprocess from 'svelte-preprocess'
import { resolve } from 'path'

export default {
  kit: ...,
  preprocess: preprocess({
    postcss: true,
    typescript: {
      tsconfigDirectory: resolve('./'),
      tsconfigFile: 'tsconfig.json',
    }
  })
}

To complete your support of SvelteKit, you may want to add these additional loaders to your chain:

Caveats

Lifecycle Events

By current Svelte design, some lifecycle events do not run on the server: onMount, beforeUpdate, afterUpdate. More context is here: https://github.com/sveltejs/svelte/issues/7267.

You can still test these lifecycle events by using a slightly verbose workaround:

<!-- Component.svelte -->
<script>
  import { onMount } from 'svelte'

  let name = 'Alice'

  export const onMountHandle = () => {
    name = 'Bob'
  }

  onMount(onMountHandle)
</script>

<div>
  <h1>{name}</h1>
</div>
// Component.test.js
test('onMount', async () => {
  const { component, findByText, getByText } = render(Component)
  assert.ok(getByText('Alice'))

  component.onMountHandle()
  assert.ok(await findByText('Bob'))
})

License

MIT