While Svelte encourages Rollup as the preferred bundler, there is no denying the popularity of Webpack and Babel. However, resources for Svelte Webpack Babel are scarce and often lacking in meaningful description.

In fact, it is a common question among developers whether Svelte works with Webpack or not.

In this post, we are going to address this paucity of content by building a Svelte Webpack starter project from scratch. Moreover, we are going to go through every configuration step with detailed explanations. In my view, It is always better to understand the steps rather than simply copy pasting the configuration items.

1 – Creating a Svelte Project Folder

In the first step, we will quickly create our project directories.

$ mkdir svelte-webpack-demo
$ cd svelte-webpack-demo
$ npm init -y
$ mkdir public
$ mkdir src

Basically, we have initialized the project and created the public and src folders. The public folder will contain the index.html file. The src will have our application source code.

2 – Installing Babel Dependencies

In this step, we will setup and configure Babel for our Svelte project.

But why do we need Babel? What is the use of Babel?

Babel converts modern Javascript into plain-old Javascript that any browser (including the old ones) can understand and run. In technical terms, Babel is a transpiler. It enables all the new ES6 features such as classes and arrow functions to work seamlessly in old browsers.

Since we are going to use the newer Javascript features to build our Svelte application, we need Babel to make our code compatible with older browsers.

To use Babel, we have to install the below packages:

$ npm install @babel/core @babel/preset-env @babel/polyfill babel-loader --save-dev

Quite a bunch of packages!

Let’s understand what each package does.

2.1 – Babel Core

This is the core Babel package. All the Babel functionality resides in this package and no other packages related to Babel will work without this. Hence, we need to definitely install @babel/core.

2.2 – Babel Preset-Env

This is an interesting package. While @babel/core is the backbone of Babel, it does not really do anything on its own.

Instead, Babel needs various plugins to perform its task. Each plugin corresponds to a particular ES6 feature and has its own npm package. While it is possible to install ES6 feature specific plugins, it can become cumbersome to install a bunch of individual packages to cover all the features we might use in our application.

The @babel/preset-env bundles together common Babel plugins in a single package. It is basically a preset provided by the creators of Babel that combines a bunch of plugins. By installing the @babel/preset-env package, we automatically get access to all the other plugins.

While this is a high-level overview of Babel presets, we will cover more about Babel Preset Env in another post.

2.3 – Babel Polyfills

The @babel/polyfill package also helps in supporting the newer ES6 features. It is basically used by the @babel/preset-env package.

2.4 – Babel Loader

The babel-loader package makes Babel work with Webpack. This is needed because we want to control our application build process using Webpack. Therefore, Webpack should integrate with Babel.

3 – The Babel Configuration File

With the necessary Babel packages installed, we need to create a configuration file named .babelrc in the root of the project.

See below:

{
    "presets": [
        "@babel/preset-env"
    ]
}

Basically, we are using .babelrc file to tell Babel which presets we want to use for our project.

4 – Installing Webpack Dependencies

Now we can proceed to install the necessary Webpack dependencies.

You can execute the below command to do so.

$ npm install webpack webpack-cli webpack-dev-server html-webpack-plugin css-loader mini-css-extract-plugin dotenv-webpack svelte-loader --save-dev

Let’s understand what each package is needed for:

  • The webpack package is the core package and hence, we need to install it. At the time of writing, we are using Webpack 5. This is the central package in the Webpack ecosystem.
  • Earlier webpack-cli package was part of the core webpack package. However, they have been separated now. We need webpack-cli to execute webpack commands.
  • The webpack-dev-server creates a server to process and serve our built files. It provides a port number where we can test our application locally. It also helps with hot-reloading of our application when we make some changes to the source code.
  • The html-webpack-plugin makes it easy to create HTML files to serve the javascript bundle.
  • As the name suggests, the css-loader package helps with the loading of CSS files. It resolves import and @url() statements that we may use to load CSS in our application components.
  • The mini-css-extract-plugin extracts the CSS into a separate file. It creates a CSS file per JS file.
  • The dotenv-webpack package is used to load any environment files we might use in our application.
  • Lastly, the svelte-loader package is required to handle .svelte files as part of the Webpack process.

Note that all of these are dev dependencies and therefore, we use the flag –save-dev while installing them.

5 – The Svelte Webpack Configuration File

With the needed Webpack packages installed, we will now create the webpack.config.js file. Basically, this file controls the functioning of Webpack. It acts as the configuration for Svelte and Webpack working together.

This file sits in the root of the project.

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const Dotenv = require('dotenv-webpack');

module.exports = {
    // Specifying the mode
    mode: 'development',
    // Entry point to our application
    entry: './src/index.js',
    // Path to the Output
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js',
        publicPath: '/'
    },
    //Specifying the Loaders for Babel, Svelte and CSS
    module: {
        rules: [
            {
                test: /\.js?$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                }
            },
            {
                test: /\.svelte$/,
                use: {
                    loader: 'svelte-loader',
                }
            },
            {
                test: /\.css$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader'],
            },
        ]
    },
    
    plugins: [
        // Creates index.html file in the build folder
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, 'public/index.html'),
        }),
        // This grabs the CSS and places it in a single file
        new MiniCssExtractPlugin(),
        // Manages the environment variables in the .env file.
        new Dotenv(),
    ],
    // Configuring Webpack Dev Server and Set Hot Reloading to true
    devServer: {
        static: {
            directory: path.resolve(__dirname, 'dist'),
        },
        hot: true
    },
};

Let us walkthrough the configuration.

  • The mode specifies whether the settings are applicable for development or production.
  • The entry variables specifies the entry point to our application. This is usually the index.js file. We are yet to create the index.js file for our application and will be doing so in the next section.
  • The output specifies the location for the built artifacts. It also provides a name for the final javascript file. In this case, we name it bundle.js.
  • Next, we have the various loaders under the module object. As you may remember, we had installed loaders of Babel, Svelte and CSS. This section configures the loaders by specifying the file extensions and attaching a specific loader to every file type.
  • Moving on, we also use a few plugins. The HtmlWebpackPlugin creates the index.html file. The MiniCssExtractPlugin grabs the CSS and places it in a single file. Lastly, the Dotenv plugin makes the environment variables available in our project.
  • At the end, we configure the webpack dev server by specifying the path to the static directory and also setting the hot reload flag as true. This instructs Webpack to watch our source code for changes and deploy them. It is a very useful feature during development phase where we can quickly see the result of our code changes.

6 – Creating the Svelte App

With the Webpack configuration ready, we can now build our Svelte Application.

First, we will create the index.js.

import App from './App.svelte';
import './global.css'

const app = new App({
    target: document.getElementById('root')
});

export default app;

If you remember, this is the entry-point to our application. Here, we create an instance of the App component and inject it to the root element of our page.

Below is the App component. It is a very simple component that simply prints a greeting message. It gets access to the .env file from the process.env object.

<script>
    let name = process.env.name
</script>

<style>
    h1{
        color: red
    }
</style>

<h1>Greetings {name}</h1>

Below is the .env file that we create in the root (not the src folder) of our project.

name=WebNinja

Also, we have a global.css file to test whether Webpack properly loads the CSS.

body {
    background-color: lightblue
}

Lastly, we create the index.html in the public folder.

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Svelte Webpack Demo</title>
</head>
<body>
    <div id="root"></div>
</body>
</html>

You can see the div with id root over here. This is where index.js will inject the App component.

With this our Svelte application is ready. If you wish to know more about Svelte, you can refer to this detailed post on step-by-step walkthrough for a typical Svelte application.

7 – The Webpack NPM Scripts

Finally, we have to add the appropriate script to start the webpack-dev-server. We do so in the package.json file.

"scripts": {
    "dev": "webpack serve"
},

We can now start the application by executing npm run dev. This command starts our application on http://localhost:8080 where we will see the greeting message.

Conclusion

With this, we have successfully created a Svelte Webpack Babel application. The important thing is that we have understood each step and each configuration item so that we can make better decisions while creating a new application.

The code shown in this post is available on Github. You can use it as a basic Svelte Webpack template and build on top of it depending on requirements.

In case you prefer any bundler other than Webpack, we have another detailed post about Svelte Rollup integration.

If you have any comments or queries about this post, please mention them in the comments section below.


0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *