Setting Up a Svelte + NestJS Application
Do you want to develop your web in both frontend and backend at the same time and at the same port? For the sake of saving your development time. If so. This article is for you. Of course, you can do this with other frameworks mixing, too. E.g. Next.js and NestJS, and other more. However, I’ll do this with my favorite framework, Svelte, and NestJS (as the title said 😁).
The Objectives
- Implement a mono-repository with NestJS and Svelte combined.
- Set up the development environment, running NestJS and Svelte altogether in the same port, e.g., localhost:3000 in both frontend and backend. Just run only npm run dev command.
- When Svelte files get updated, the web will be reloaded without reloading the whole backend side.
- Set up Svelte in JavaScript (not TypeScript).
- The compiled result from Svelte will be served as a client-side rendering application (CSR).
Preparation
At the beginning of setting up, you need, of course, a project repository. Let’s create one in your GitHub account and clone it into your working directory. Then set up your Svelte environment by running this command I brought from the official docs.
npx degit sveltejs/template [destination]
After that, run this script to install the NestJS template. Be careful! Don’t install at the same directory as it can override some of the Svelte files! It needs to be in a different directory for further configuration. In the below script, if you already installed @nestjs/cli
, just run only the second line. (I brought this script from the official docs.)
npm i -g @nestjs/cli
nest new [destination]
Merging Svelte and NestJS Together
Merging “src” folder
After you run both Svelte and NestJS scripts, now, it’s time to merge them together. Firstly, re-structure the root src folder to…
As you can see, I moved the Svelte and NestJS files into the same src folder. But I separated them into two parts, client and server, or whatever you want to name to indicate that they are not the same part. The client folder is the folder that I moved from Svelte src, and the server folder is the folder that I moved from NestJS src.
Merging package.json
Next, we have to merge the package.json file. You can copy from both Svelte and NestJS [dev]dependencies into the new package.json file as they don’t overlap with each other. Then, you have to config some of the scripts options or simply copy the below code. I’ve already rearranged the scripts, devDependencies, and dependencies. But you have to format this in your package.json file. DON’T BLINDLY COPY-AND-PASTE!
"scripts": {
"build": "rollup -c && nest build",
"dev": "rollup -c -w",
"start": "nest start",
"prod": "node dist/main",
"server:dev": "nest start --watch"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^17.0.0",
"@rollup/plugin-node-resolve": "^11.0.0",
"rollup": "^2.3.4",
"rollup-plugin-css-only": "^3.1.0",
"rollup-plugin-livereload": "^2.0.0",
"rollup-plugin-svelte": "^7.0.0",
"rollup-plugin-terser": "^7.0.0",
"svelte": "^3.0.0",
"@nestjs/cli": "^8.0.0",
"@nestjs/schematics": "^8.0.0",
"@nestjs/testing": "^8.0.0",
"@types/express": "^4.17.13",
"@types/jest": "^27.0.1",
"@types/node": "^16.0.0",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^27.2.5",
"prettier": "^2.3.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "^27.0.3",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "^3.10.1",
"typescript": "^4.3.5"
},
"dependencies": {
"sirv-cli": "^2.0.0",
"@nestjs/common": "^8.0.0",
"@nestjs/core": "^8.0.0",
"@nestjs/platform-express": "^8.0.0",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0"
}
Make sure that you properly format your package.json file. And finally, run the familiar npm i
command. (The dependencies are not up-to-date, as of Feb. 15, 2022)
Updating nest-cli.json
You have to move the nest-cli.json file to your root directory. And change the “sourceRoot” property to your server-part folder which is the server folder that I previously named. You can simply copy and paste the code into the file.
{
"collection": "@nestjs/schematics",
"sourceRoot": "src/server"
}
Updating tsconfig.json
You have to move the tsconfig.build.json and the tsconfig.json file to your root directory. That’s it.
The Final Structure
Let’s Write the Code
Woah! Is that too much? This is the final process. We have to write code to make them work together. It’s not much. Follow me along.
Coding rollup.config.json
Replace the highlighted section of code with…
"npm", ["run", "server:dev"]
And change your Svelte entry point.
That’s it.
The reason behind this: when we run the npm run dev
command, it will execute this file first. The main process is watching Svelte files for changes, and another process (at the replaced code) is for running the NestJS server.
Serving the Public Folder
You have to look up the main.ts file located in src/server. For serving contents in the public folder, you need to add only a single line of code. (For simplification, I won’t use @nestjs/serve-static
)
Just add this line of code…
app.useStaticAssets(join(__dirname, '..', 'public'));
Note: you have to add NestExpressApplication
type in the <>
for acquiring the useStaticAssets
method.
Now, it’s time to run the npm run dev
command, and everything should work well.
If you want to build for production, run the npm run build
and npm start
command.
That’s all for setting up a Svelte + NestJS application. In fact, I’ve implemented a Svelte with TypeScript one, but that will be a very complex and long setup for this article. (The JavaScript version alone is too much. 😅) If you have better approaches, you can put them down in the comment. And if you have any problems, you can also comment down here. I’ll try my best to respond to you. Have a great day!