Mastering code configuration for efficient svelte development - part 1
May 18, 2024
introduction
Before developing SvelteJs.io, starting a new project was a cumbersome task. I either used npm init svelte to create a fresh project and then spent time tweaking a few configuration settings, or I forked an existing starter repository. Neither approach was ideal. These methods often resulted in inconsistent configurations across projects or included configurations I didn’t fully understand, leading to potential code smells. I strive to avoid having any code in my codebase that I don’t fully grasp. Most of the times, your project has already been set up for a long time and you’d only want to check if you have already the best configuration at that time, which isn’t possible with a start repository either.
For SvelteJs.io, I aimed to discover the ultimate starter repository in the world. I couldn’t find one, so I compiled a list of over 40 starter repositories and blog articles on Svelte best practices. However, none of them encompassed all the best practices of the others or provided documentation explaining what the configurations did and why they were included. In addition, some of them were opinionated, either with a database adapter or an auth library or even TailwindCss! A starter is good for a MVP but not for a real world app.
Configuring your development environment is crucial. Proper setup and configuration are key to a seamless and efficient development process.
That’s why I decided to write this series of three articles: to share my findings and help others navigate the complexities of setting up and optimizing their own websites. Whether you’re a seasoned developer or just starting out, these articles aim to provide practical tips and best practices to streamline your workflow and enhance your site’s functionality.
- part 1: code configuration (you’re reading it!)
- part 2: tools configuration (coming soon)
- part 3: core features (coming soon)
what is code configuration?
Code configuration refers to the process of organizing, structuring, and optimizing the underlying code and coding development of a website, typically done through configuration files. It involves setting up the language of your project, configuring the tools you’re using, and managing your code environment.
language configuration
typescript
More than 50% of front-end developers primarily use TypeScript as their main development language, according to the (2022 state of Js) survey. Given its widespread adoption, it’s essential to understand and work with TypeScript effectively. Fortunately, configuring TypeScript is straightforward, thanks to the tsconfig.json file.
To get started, consider adding the following compiler options to the compilerOptions object:
// https://www.typescriptlang.org/tsconfig#isolatedModules
// instructs TypeScript to warn you if you write code that can't be correctly interpreted by a single-file transpilation process.
"isolatedModules": true,
// https://www.typescriptlang.org/tsconfig#downlevelIteration
// Enables support for a more accurate implementation of how modern JavaScript iterates through new concepts in older JavaScript runtimes.
"downlevelIteration": true,
// https://www.typescriptlang.org/tsconfig#importHelpers
// Imports helper functions from the `tslib` module, rather than including them inline.
"importHelpers": true,
// https://www.typescriptlang.org/tsconfig#allowUnreachableCode
// Raises compiler errors about unreachable code
"allowUnreachableCode": false,
// https://www.typescriptlang.org/tsconfig#noImplicitReturns
// Ensures that all code paths in a function explicitly return a value
"noImplicitReturns": true,
// https://www.typescriptlang.org/tsconfig#noUncheckedIndexedAccess
// Adds undefined to the type of a property retrieved from an array by its index.
"noUncheckedIndexedAccess": true,
// https://www.typescriptlang.org/tsconfig#noUnusedLocals
// Reports an error for unused local variables.
"noUnusedLocals": true,
// https://www.typescriptlang.org/tsconfig#noUnusedParameters
// Reports an error for unused parameters in functions
"noUnusedParameters": true,
// https://www.typescriptlang.org/tsconfig#noImplicitOverride
// Ensures that methods overriding a base class method are explicitly marked with the override keyword
"noImplicitOverride": true,
// https://www.typescriptlang.org/tsconfig#strictFunctionTypes
// Enforces stricter checking of function types
"strictFunctionTypes": true,
svelte
Both Svelte and SvelteKit can be configured using the svelte.config.js
file. However, the specifics of this configuration will depend on your deployment platform. It’s recommended to use the adapter provided by your development platform, as it will allow you to configure platform-specific options.
If you’re deploying your application manually using Docker, for example, you may want to use the adapter-node
or adapter-static
.
One feature that can significantly streamline your development process, especially on larger projects, is the svelte inspector. I’ve been configuring it in all my projects since its experimental release. This Vite plugin adds a Svelte Inspector to your browser, displaying the file location where the element under the cursor is defined. With a single click, you can quickly open your code editor at that location, saving you valuable time and effort. Here’s how to configure it:
const config = {
// ...
vitePlugin: {
inspector: {
holdMode: true,
showToggleButton: 'always',
toggleButtonPos: 'bottom-right'
}
}
};
vite
Vite can be configured using the vite.config.js
file. This is where you add any Vite plugin libraries you might be using. In my case, I don’t have anything to add to this file.
format & linting
eslint
ESLint can be configured using the .eslintrc.cjs
file. I’ve added three extra rules:
module.exports = {
// ...
rules: {
// https://stackoverflow.com/a/64067915/11320442
// Allows unused variables if they start with an underscore (_)
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_'
}
],
// https://eslint.org/docs/latest/rules/no-console
// Disallows the use of console.info() and console.log()
'no-console': [
'error',
{
allow: ['warn', 'error']
}
],
// https://eslint.org/docs/latest/rules/no-control-regex
// Permits writing new RegExp("\t"), which is typically only possible with /\t/
'no-control-regex': 0
}
};
Note that JavaScript/TypeScript compiler errors reported by svelte-check can be silenced with the comment // @ts-expect-error <description>
(the description is required by default). This is preferable to // @ts-ignore
because it will produce an error itself if no error is found.
I don’t edit .eslintignore
by default.
Additionally, at the time of writing this article, I have encountered some unusual ESLint behavior:
- The rule
no-unreachable
reports an error in a Svelte file but not in a TypeScript file. - The rule
no-var
reports an error in a TypeScript file but not in a Svelte file.
prettier
Prettier can be configured using the .prettierrc
file. I’ve added two extra rules that are highly specific to my preferences. You should only copy them if you find them necessary:
{
// ...
"tabWidth": 4,
"bracketSameLine": false
}
I don’t modify the .prettierignore
file by default.
.editorconfig
While examining starter repositories, I occasionally encountered a .editorconfig
file. This file is based on EditorConfig, which aims to maintain consistent coding styles for multiple developers working on the same project across various editors.
I won’t delve into this configuration file in detail here, but you can find a solid example in navneetsharmaui’s sveltekit-starter.