This is my project template for Svelte apps that uses Webpack v5 and TypeScript v4.
It is basically the updated version of the official template found here
To create a new project based on this template use degit:
In your terminal, type the following: npx degit federico-paolillo/svelte-template-webpack-typescript svelte-app
Note: you will need to have Node.js installed, this template was made using Node.js v17 and NPM v8. Note: All the commands are implied to be run from the project folder.
To build the application run npm run build
in a terminal. The output bundle will be in dist/
To run the application in development mode run in a terminal npm start
and navigate to http://localhost:65535
.
If the app greets you in italian, it works !
To check for issues in your Svelte files, you can run npm run check
which uses svelte-check.
Additionally, npm run lint
will use eslint
with Svelte specific plugin eslint-plugin-svelte3
to check your TypeScript and Svelte files for any questionable practice.
Like any frontend framework, the tooling required has many moving parts with some weird bits that are hard to understand without an explanation.
Starting from the tsconfig.json
, we extend (like the official template) @tsconfig/svelte
from tsconfig/bases.
As the documentation specifies, after version 2.0.0 of @tsconfig/svelte
compiler option types: ["svelte"]
was removed, so we have to include either in a .d.ts
file or in main.ts
the Svelte module types using /// <reference types="svelte" />
this will allow to import .svelte
files and will make sure that ts-loader
is able to load TypeScript during compilation successfully. In this template I've setup a global.d.ts
that can contain all the extra type definitions that should be available globally.
The application can be configured using dotenv files, there is one .env.example
that should be checked-in and contains all the possible configuration entries (with example values) that must be specified in the application .env
file. Once you have configured a value you can access it using proces.env.<variable>
. As the author of dotenv
recommends, the application .env
file should not be checked in as it will contain the real secret values.
Note that, ideally, all your configuration values should start with SVELTE_APP_
to avoid exposing your build server environment variables when bundling, but this rule is not enforced.
To avoid having to create an .env
file after cloning the template I've commited one as an example and commented the corresponding .gitignore
line.
svelte-preprocess
is installed and is used by svelte-loader
. svelte-preprocess
is necessary because Svelte does not understand TypeScript so we need a middle man to transform TypeScript to JavaScript so that svelte-loader
(and in turn the Svelte compiler) is able to work its magic.svelte-preprocess
is configured in auto-processing mode with svelte-loader
in webpack.config.js
Static assets are served through webpack-dev-server
from the public/
folder under http://localhost:65535/assets/
historyApiFallback
has been enabled to make sure that we always server index.html
on 404s so that when you refresh the page and have some routing libraries that use the browser's History API
index.html
is generated automatically using html-webpack-plugin
and will automatically contain all the bundles and the assets generated by Webpack.
Webpack optimization.moduleIds
and optimization.runtimeChunk
have been configured to avoid changing chunk content hashes when the file contents don't change and to have a single Webpack runtime for all the chunks.
The resolve.alias
option is used to make sure that only one copy of the Svelte runtime is bundled in the app, even if you are npm link
ing in dependencies with their own copy of the svelte
package. Having multiple copies of the internal scheduler in an app, besides being inefficient, can also cause various problems.
Webpack's resolve.mainFields
option determines which fields in package.json are used to resolve identifiers. If you're using Svelte components installed from npm, you should specify this option so that your app can use the original component source code, rather than consuming the already-compiled version (which is less efficient).
To avoid confusing relative imports I've added a paths
configuration to TypeScript compiler options so that I can alias under @svelte-app
all the imports for the application. Unfortunately, Webpack does not natively supports TypeScript paths, so tsconfig-paths-webpack-plugin
comes to the rescue to enable loading modules aliased under @svelte-app
. The plugin requires that we re-specify the same extensions set in Webpack resolve.extensions
.
Build time validation is provided by the Webpack plugin eslint-webpack-plugin for which only errors will fail the build.
In .eslintrc.json
there is one global variable enable: process
. This allows to reference process.env
without issues throught the codebase.
svelte.config.js
is required to make sure that svelte-vscode
works correctly with TypeScript as specified in the language tools documentation. To make sure that we can share the same configuration between svelte-vscode
and svelte-loader
the preprocess builder has been exported from svelte.config.js
.
Hot Module Replacement has been enabled using webpack-dev-server
through svelte-loader
that in turns uses svelte-hmr
so all the options that can be configured in svelte-loader
are forwarded to svelte-hmr
. This enables automatic module replacement when a file is changed, making development faster.