Simply precompiles Svelte components before importing them into Jest tests.
This version requires Jest >= 27 and defaults to ESM, which is required with Svelte 4+. If you're using Svelte 3 and want to use CJS, you need to specify the full path for the jest transformer in your jest config.
Seems like other libraries won't be working with preprocessors, won't be maintained actively or didn't have proper licensing.
If you're using SvelteKit, you can set it up and install it with svelte-add-jest by running:
npx apply rossyman/svelte-add-jest
This library has peerDependencies
listings for svelte >= 3
and jest >= 27
.
npm install svelte-jester -D
Add the following to your Jest config:
{
"transform": {
"^.+\\.svelte$": "svelte-jester"
},
"moduleFileExtensions": ["js", "svelte"],
"extensionsToTreatAsEsm": [".svelte"]
}
Run your tests with NODE_OPTIONS=--experimental-vm-modules
. For Windows you need to add cross-env
as well.
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest src",
Add the following to your Jest config:
{
"transform": {
"^.+\\.svelte$": "./node_modules/svelte-jester/dist/transformer.cjs"
},
"moduleFileExtensions": ["js", "svelte"]
}
npm install @babel/core @babel/preset-env babel-jest -D
Add the following to your Jest config
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.svelte$": "svelte-jester"
}
Create a .babelrc
and add the following
{
"presets": [["@babel/preset-env", { "targets": { "node": "current" } }]]
}
To enable TypeScript support you'll need to setup svelte-preprocess
and ts-jest
.
Install typescript
, svelte-preprocess
, and ts-jest
:
npm install typescript svelte-preprocess ts-jest -D
Create a svelte.config.js
at the root of your project:
import preprocess from 'svelte-preprocess'
/** @type {import('@sveltejs/kit').Config} */
export default config = {
preprocess: preprocess(),
// ...
};
To learn what options you can pass to sveltePreprocess
, please refer to the documentation.
In your Jest config, enable preprocessing for svelte-jester
, and add ts-jest
as a transform:
"transform": {
"^.+\\.svelte$": [
"svelte-jester",
{
"preprocess": true
}
],
"^.+\\.ts$": [
"ts-jest",
{
"useESM": true
// optional: seperate tsconfig for tests
//"tsconfig": "tsconfig.spec.json",
}
],
},
"moduleFileExtensions": [
"js",
"ts",
"svelte"
],
"extensionsToTreatAsEsm": [
".svelte",
".ts"
],
However if you do not want to create a svelte.config.js
at the root of your
project or you wish to use a custom config just for tests, you may pass the
path to the config file to the preprocess
option thus:
"transform": {
"^.+\\.svelte$": [
"svelte-jester",
{
"preprocess": "/some/path/to/svelte.config.js"
}
],
"^.+\\.ts$": [
"ts-jest",
{
"useESM": true
// optional: seperate tsconfig for tests
//"tsconfig": "tsconfig.spec.json",
}
],
},
"moduleFileExtensions": [
"js",
"ts",
"svelte"
],
"extensionsToTreatAsEsm": [
".svelte",
".ts"
],
Create a svelte.config.js
at the root of your project:
const sveltePreprocess = require("svelte-preprocess");
module.exports = {
preprocess: sveltePreprocess({
// ...
}),
};
To learn what options you can pass to sveltePreprocess
, please refer to the documentation.
In your Jest config, enable preprocessing for svelte-jester
, and add ts-jest
as a transform:
"transform": {
"^.+\\.svelte$": [
"./node_modules/svelte-jester/dist/transformer.cjs",
{
"preprocess": true
}
],
"^.+\\.ts$": "ts-jest"
},
"moduleFileExtensions": [
"js",
"ts",
"svelte"
]
However if you do not want to create a svelte.config.js
at the root of your
project or you wish to use a custom config just for tests, you may pass the
path to the config file to the preprocess
option thus:
"transform": {
"^.+\\.svelte$": [
"./node_modules/svelte-jester/dist/transformer.cjs",
{
"preprocess": "/some/path/to/svelte.config.js"
}
],
"^.+\\.ts$": "ts-jest"
},
"moduleFileExtensions": [
"js",
"ts",
"svelte"
]
Note that TypeScript supports ES modules, so if you were previously using babel-jest just for ES module transpilation, you can remove babel-jest, babel, and any associated presets and config.
By default, ts-jest will only transpile .ts files though, so if you want to continue using ES modules in .js files, you'll need to configure ts-jest to process .js files as well. To do this, update the file glob above, and follow the instructions in the ts-jest docs.
Preprocessors are loaded from svelte.config.js
or svelte.config.cjs
.
Add the following to your Jest config:
"transform": {
"^.+\\.svelte$": ["svelte-jester", { "preprocess": true }]
}
For CJS, replace "svelte-jester"
with "./node_modules/svelte-jester/dist/transformer.cjs"
.
Create a svelte.config.js
file and configure it, see
svelte-preprocess for more information.
In CJS mode, svelte-jester
must start a new a process for each file needing to be preprocessed, which adds a performance overhead.
In ESM mode, this isn't necessary. You can set NODE_OPTIONS=--experimental-vm-modules
and "extensionsToTreatAsEsm": [".svelte"]
to run in ESM mode. However, be aware that ESM support in Jest is still experimental as according to their docs. Follow the development along at https://github.com/facebook/jest/issues/9430.
preprocess
(default: false): Pass in true
if you are using Svelte preprocessors.
They are loaded from svelte.config.js
or svelte.config.cjs
.
debug
(default: false): If you'd like to see the output of the compiled code then pass in true
.
svelteVersion
(default: actual Version from Svelte package): If you'd like to override the svelteVersion for some reason.
compilerOptions
(default: {}): Use this to pass in
Svelte compiler options.
rootMode
(default: ""): Pass in upward
to walk up from the transforming file's directory and use the first svelte.config.js
or svelte.config.cjs
found, or throw an error if no config file is discovered. This is particularly useful in a monorepo as it allows you to:
svelte.config.js
in workspace folders, and not in the root.svelte.config.js
configurations for individual workspaces.svelte.config.js
in your worktree root (or any directory above the file being transformed) without needing individual svelte.config.js
files in each workspace. Note - this root config file can be overriden if necessary by putting another config file into a workspace folderThe default mode is to load svelte.config.js
or svelte.config.cjs
from the current project root to avoid the risk of accidentally loading a config file from outside the current project folder.
When upward
is set it will stop at the first config file it finds above the file being transformed, but will walk up the directory structure all the way to the filesystem root if it cannot find any config file. This means that if there is no svelte.config.js
or svelte.config.cjs
file in the project above the file being transformed, it is always possible that someone will have a forgotten config file in their home directory which could cause unexpected errors in your builds.
showConsoleLog
(default: false): If you'd like to see console.logs of the preprocessors then pass in true
. Otherwise these will be surpressed, because the compiler could complain about unexpected tokens.
maxBuffer
(default: 10485760): Sets limit for buffer when preprocess
is true. It defines the largest amount of data in bytes allowed on stdout or stderr for child_process.spawnSync. If exceeded, the child process is terminated and any output is truncated. The default value of 10Mb overrides Node's default value of 1Mb.
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.svelte$": ["./node_modules/svelte-jester/dist/transformer.cjs", {
"preprocess": false,
"debug": false,
"compilerOptions": {},
"rootMode": "",
"maxBuffer": 15000000
}]
}
This package is required when using Svelte with the Testing Library. If you'd like to avoid including implementation details in your tests, and making them more maintainble in the long run, then consider checking out @testing-library/svelte.
Thanks to all contributors, inspired by: