Add a Svelte Project
The code for this example is available on GitHub:
Example repository/nrwl/nx-recipes/tree/main/svelte
Supported Features
Because we are not using a Nx plugin for Svelte, there are a few items we'll have to configure manually. We'll have to configure our own build system. There are no pre-created Svelte-specific code generators. And we'll have to take care of updating any framework dependencies as needed.
✅ Run Tasks✅ Cache Task Results✅ Share Your Cache✅ Explore the Graph✅ Distribute Task Execution✅ Integrate with Editors✅ Automate Updating Nx✅ Enforce Module Boundaries🚫 Use Code Generators🚫 Automate Updating Framework Dependencies
Setup workspace
Create a new Nx workspace
❯
npx create-nx-workspace@latest acme --preset=ts-standalone --nx-cloud=yes
Add @nx/vite, svelte, and other dependencies to your workspace
Make sure to install the@nx/vite
and@nx/js
versions that matches the version ofnx
in your repository. If the version numbers get out of sync, you can encounter some difficult to debug errors. You canfix Nx version mismatches with this recipe.
❯
npm add -D vitest vite svelte svelte-check @sveltejs/vite-plugin-svelte
❯
nx add @nx/vite @nx/js
Create the application
Create yourindex.html
at the root with the following:
1<!DOCTYPEhtml>2<htmllang="en">3<head>4<metacharset="UTF-8" />5<metaname="viewport"content="width=device-width, initial-scale=1.0" />6<title>Acme</title>7</head>8<body>9<divid="app"></div>10<scripttype="module"src="./src/main.ts"></script>11</body>12</html>13
Navigate tosrc/index.ts
and change it tosrc/main.ts
and add the following content:
1import Appfrom'./App.svelte';23const app =new App({4target:document.getElementById('app'),5});67exportdefault app;8
Create a new filesrc/App.svelte
and add the following content:
1<script lang="ts">2let count:number =0;3const increment =() => {4 count +=1;5 };6</script>78<buttonon:click={increment}>9 count is {count}10</button>11
Since we have a.svelte
file, we'll need to tell typescript how to handle it. Create a new filesrc/svelte-shims.d.ts
and add the following content:
1declaremodule'*.svelte' {2importtype { ComponentType }from'svelte';3const component: ComponentType;4exportdefault component;5}6
Alternatively, you could also extend thetsconfig.json
file to use tsconfig/svelte.
1{2"extends":"@tsconfig/svelte/tsconfig.json"3//... other configs4}5
See more here:Svelte TypeScript
Configure Nx to build and serve the application
Navigate tovite.config.ts
addsvelte
to your plugins.
1// Add this to your imports2import { svelte }from'@sveltejs/vite-plugin-svelte';34exportdefault defineConfig({5plugins: [6//... other plugins7 svelte(),// Add this line8 ],9//...10server: {11port:4200,12host:'localhost',13 },14});15
Change yourtsconfig.lib.json
totsconfig.app.json
. It should look like this:
1{2"extends":"./tsconfig.json",3"compilerOptions": {4"outDir":"./dist/out-tsc",5"declaration":true,6"types": ["node"]7 },8"include": ["src/**/*.ts","src/**/*.svelte"],9"exclude": ["jest.config.ts","src/**/*.spec.ts","src/**/*.test.ts"]10}11
Navigate tonx.json
it should contain the following:
1{2// ... other config3"plugins": [4 {5"plugin":"@nx/eslint/plugin",6"options": {7"targetName":"lint"8 }9 },10 {11"plugin":"@nx/vite/plugin",12"options": {13"buildTargetName":"build",14"previewTargetName":"preview",15"testTargetName":"test",16"serveTargetName":"serve",17"serveStaticTargetName":"serve-static"18 }19 }20 ]21}22
We also need to add asvelte.config.js
file to the project root with the following content:
1import { vitePreprocess }from'@sveltejs/vite-plugin-svelte';23exportdefault {4// Consult https://svelte.dev/docs#compile-time-svelte-preprocess5// for more information about preprocessors6preprocess: vitePreprocess(),7};8
Update yourpackage.json
to include:
1{2"type":"module"3}4
We need to add"type": "module"
to ourpackage.json
file because we are using ESM only packages. See more here:ESM Package
Test it out
Build the application
❯
nx build acme
Your build artifacts should be indist/acme
Serve the application
❯
nx serve acme
Navigate tohttp://localhost:4200
and you should see your application.
Create a library
Instead of having our Counter directly defined inApp.svelte
file, let's create a library that we can import into our application.
❯
nx generate @nx/js:library libs/counter --unitTestRunner=vitest --bundler=vite --importPath=@acme/counter
Create the Counter component atlibs/counter/src/lib/Counter.svelte
and copy the contents of yoursrc/App.svelte
file into it.
Update yourlibs/counter/src/lib/index.ts
to export your Counter component.
1export {defaultas Counter }from'./Counter.svelte';2
Thedefault
is import here as due to the aliasing we'll be doing later, we'll need to import the Counter component asimport { Counter } from '@acme/counter'
.
Update your project'svite.config.ts
to include the following:
1exportdefault defineConfig({2//... other config3resolve: {4alias: {5'@acme/counter': fileURLToPath(6new URL('/libs/counter/src/index.ts',import.meta.url)7 ),8 },9 },10});11
This allows the runtime to resolve the@acme/counter
import to the correct location.
Finally update yoursrc/App.svelte
to use the counter component.
1<script lang="ts">2import { Counter }from'@acme/counter';3</script>45<Counter />6
Now we can build and serve our application again.
❯
nx build acme
To generate the build artifact atdist/acme
.
❯
nx serve acme
To serve the application athttp://localhost:4200
.
More Documentation
A larger example including libraries, test and more is available atNx Svelte Example on GitHub.