Skip to content

Commit

Permalink
docs(misc): Update Svelte recipe to use ts-standalone preset
Browse files Browse the repository at this point in the history
  • Loading branch information
ndcunningham authored and juristr committed Nov 28, 2023
1 parent 448e915 commit 02ee93f
Showing 1 changed file with 53 additions and 57 deletions.
110 changes: 53 additions & 57 deletions docs/shared/recipes/add-stack/add-svelte.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,21 @@ Because we are not using a Nx plugin for Svelte, there are a few items we'll hav
{%tab label="npm"%}

```shell
npx create-nx-workspace@latest workspace --preset=react-monorepo --style=css --bundler=vite --nx-cloud=true --appName=acme
npx create-nx-workspace@latest acme --preset=ts-standalone --nx-cloud=true
```

{% /tab %}
{%tab label="yarn"%}

```shell
npx create-nx-workspace@latest workspace --preset=react-monorepo --style=css --bundler=vite --nx-cloud=true --appName=acme --pm yarn
npx create-nx-workspace@latest acme --preset=ts-standalone --nx-cloud=true --pm yarn
```

{% /tab %}
{%tab label="pnpm"%}

```shell
npx create-nx-workspace@latest workspace --preset=react-monorepo --style=css --bundler=vite --nx-cloud=true --appName=acme --pm pnpm
npx create-nx-workspace@latest acme --preset=ts-standalone --nx-cloud=true --pm pnpm
```

{% /tab %}
Expand Down Expand Up @@ -80,13 +80,7 @@ pnpm add --save-dev @nx/vite @nx/js vitest vite svelte svelte-check @sveltejs/vi

## Create the application

Before we start to create our application, let's remove the React application that was created for us.

```shell
rm -rf apps/acme/src/app/*
```

Update your `apps/acme/src/index.html` to the following:
Create your `index.html` at the root with the following:

```html
<!DOCTYPE html>
Expand All @@ -103,10 +97,10 @@ Update your `apps/acme/src/index.html` to the following:
</html>
```

Navigate to `apps/acme/src/main.tsx` and change it to `apps/acme/src/main.ts` and add the following content:
Navigate to `src/index.ts` and change it to `src/main.ts` and add the following content:

```ts
import App from './app/App.svelte';
import App from './App.svelte';

const app = new App({
target: document.getElementById('app'),
Expand All @@ -115,87 +109,89 @@ const app = new App({
export default app;
```

Create a new file `apps/acme/src/app/App.svelte` and add the following content:
Create a new file `src/App.svelte` and add the following content:

```ts
```ts {% fileName="src/App.svelte" %}
<script lang="ts">
let count: number = 0
const increment = () => {
count += 1
}
</script>
let count: number = 0;
const increment = () => {
count += 1;
};
</script>

<button on:click={increment}>
count is {count}
</button>
```

Since we have a `.svelte` file, we'll need to tell typescript how to handle it. Create a new file `src/svelte-shims.d.ts` and add the following content:

<button on:click={increment}>
count is {count}
</button>
```ts {% fileName="src/svelte-shims.d.ts" %}
declare module '*.svelte' {
import type { ComponentType } from 'svelte';
const component: ComponentType;
export default component;
}
```

Alternatively, you could also extend the `tsconfig.json` file to use tsconfig/svelte.

```json {% fileName="tsconfig.json" %}
{
"extends": "@tsconfig/svelte/tsconfig.json"
//... other configs
}
```

See more here: [Svelte TypeScript](https://www.npmjs.com/package/@tsconfig/svelte)

## Configure Nx to build and serve the application

Navigate to `vite.config.ts` update the file name to `vite.config.mts` and add the following content:
Navigate to `vite.config.ts` add `svelte` to your plugins.

```ts
// Add this to your imports
import { svelte } from '@sveltejs/vite-plugin-svelte';

export default defineConfig({
plugins: [
//...
svelte(),
//... other plugins
svelte(), // Add this line
],

//...
server: {
port: 4200,
host: 'localhost',
},
});
```

{%callout type="Note" title="Why use the .mts file extension?" %}
We change `vite.config.ts` to `vite.config.mts` because `'@sveltejs/vite-plugin-svelte'` is an ESM only package. As a result, we need to use the `.mts` extension to tell Nx to use the ESM loader. See more here: [ESM Package](https://vitejs.dev/guide/troubleshooting.html#this-package-is-esm-only)
{% /callout %}
Change your `tsconfig.lib.json` to `tsconfig.app.json`. It should look like this:

Update your `tsconfig.app.json` with the following content:

```json {% fileName="/apps/acme/tsconfig.app.json" %}
```json {% fileName="/tsconfig.app.json" %}
{
"extends": "./tsconfig.json",
"compilerOptions": {
"moduleResolution": "node",
"target": "esnext",
"ignoreDeprecations": "5.0",
"isolatedModules": true,
"sourceMap": true,
"types": ["svelte", "node", "vite/client"],
"strict": false,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"checkJs": true
"outDir": "./dist/out-tsc",
"declaration": true,
"types": ["node"]
},
"include": [
"src/**/*.d.ts",
"src/**/*.ts",
"src/**/*.js",
"src/**/*.svelte",
"vite.config.mts"
],
"include": ["src/**/*.ts", "src/**/*.svelte"],
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
}
```

Navigate to `project.json` and update it with the following content:

```json {% fileName="/apps/acme/project.json" %}
```json {% fileName="/project.json" %}
{
"targets": {
"build": {
"executor": "@nx/vite:build",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
"outputPath": "dist/apps/acme"
"outputPath": "dist/acme"
},
"configurations": {
"development": {
Expand Down Expand Up @@ -259,7 +255,7 @@ Test it out
nx build acme
```

Your build artifacts should be in `dist/apps/acme`
Your build artifacts should be in `dist/acme`

**Serve the application**

Expand All @@ -281,7 +277,7 @@ The command below uses the `as-provided` directory flag behavior, which is the d
nx generate @nx/js:library --name=Counter --directory=libs/counter --unitTestRunner=vitest --bundler=vite --importPath=@acme/counter
```

Create the Counter component at `libs/counter/src/lib/Counter.svelte` and copy the contents of your `apps/acme/src/App.svelte` file into it.
Create the Counter component at `libs/counter/src/lib/Counter.svelte` and copy the contents of your `src/App.svelte` file into it.

Update your `libs/counter/src/lib/index.ts` to export your Counter component.

Expand All @@ -293,7 +289,7 @@ export { default as Counter } from './Counter.svelte';
The `default` is import here as due to the aliasing we'll be doing later, we'll need to import the Counter component as `import { Counter } from '@acme/counter'`.
{% /callout %}

Update your project's `/apps/acme/vite.config.mts` to include the following:
Update your project's `vite.config.ts` to include the following:

```ts
export default defineConfig({
Expand All @@ -310,7 +306,7 @@ export default defineConfig({

This allows the runtime to resolve the `@acme/counter` import to the correct location.

Finally update your `apps/acme/src/App.svelte` to use the counter component.
Finally update your `src/App.svelte` to use the counter component.

```ts
<script lang="ts">
Expand All @@ -326,7 +322,7 @@ Now we can build and serve our application again.
nx build acme
```

To generate the build artifact at `dist/apps/acme`.
To generate the build artifact at `dist/acme`.

```shell
nx serve acme
Expand Down

1 comment on commit 02ee93f

@vercel
Copy link

@vercel vercel bot commented on 02ee93f Nov 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nx-dev – ./

nx-dev-nrwl.vercel.app
nx.dev
nx-five.vercel.app
nx-dev-git-master-nrwl.vercel.app

Please sign in to comment.