Svelte with Webpack 5 and Babel
Tags: svelte, webpack, babel
Published: 2021-02-13 23:04:07

In this tutorial, you are going to learn how to set up a Svelte project from 0.

If you just want the code, here is the [repo](https://github.com/rogeliosamuel621/Dummy-Network/tree/main/packages/client)

## Tutorial

First of all, we create our folder

```bash
mkdir webpack5-svelte
cd webpack5-svelte
npm init --yes
mkdir src public
```

**Now we install the following dependencies**

- **Babel**
This lets us convert modern javascript into javascript which all browsers support

```bash
npm i @babel/core @babel/preset-env @babel/polyfill babel-loader svelte-loader --save-dev
```

- **Webpack**
Webpack is the tool that is going to convert all our svelte files to javascript files 

```bash
npm i webpack webpack-cli webpack-dev-server html-webpack-plugin css-loader mini-css-extract-plugin file-loader dotenv-webpack --save-dev
```

- **Svelte**
```
npm i svelte
```
**Config files**

After this, we create babel and webpack files in our src folder
```bash
touch .babelrc webpack.config.js
```

- **.babelrc**
```json
{
  "presets": [
    "@babel/preset-env"
  ]
}
```

- **Webpack.config.js**
```js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const Dotenv = require('dotenv-webpack');

module.exports = {
  // This says to webpack that we are in development mode and write the code in webpack file in different way
	mode: 'development',
  //Our index file
	entry: './src/index.js',
  //Where we put the production code
	output: {
		path: path.resolve(__dirname, 'dist'),
		filename: 'bundle.js',
		publicPath: '/',
	},
	module: {
		rules: [
      //Allows use of modern javascript
			{
				test: /\.js?$/,
				exclude: /node_modules/, //don't test node_modules folder
				use: {
					loader: 'babel-loader',
				},
			},
      //Allows use of svelte
			{
				test: /\.svelte$/,
				use: {
					loader: 'svelte-loader',
				},
			},
      //Allows use of CSS
			{
				test: /\.css$/,
				use: [MiniCssExtractPlugin.loader, 'css-loader'],
			},
      //Allows use of images
			{
				test: /\.(jpg|jpeg|png|svg)$/,
				use: 'file-loader',
			},
		],
	},
  //this is what enables users to leave off the extension when importing
	resolve: {
		extensions: ['.mjs', '.js', '.svelte'],
	},
	plugins: [
    //Allows to create an index.html in our build folder 
		new HtmlWebpackPlugin({
			template: path.resolve(__dirname, 'public/index.html'),
		}),
    //This gets all our css and put in a unique file
		new MiniCssExtractPlugin(),
    //take our environment variable in .env file
    //And it does a text replace in the resulting bundle for any instances of process.env.
		new Dotenv(),
	],
  ////Config for webpack-dev-server module
	devServer: {
		historyApiFallback: true,
		contentBase: path.resolve(__dirname, 'dist'),
		hot: true,
	},
};
```

**Create a Svelte app**

We are going to create 5 files
- `public/index.html` is the skeleton of our project
- `.env` to test that dotenv-webpack works
- `./src/index.svelte` the entry point
- `./src/app.svelte` our application file
- `./src/global.css` to test that css config in webpack works

```
touch ./public/index.html
touch .env
touch ./src/index.js
touch ./src/App.svelte
touch ./src/global.css
```

- **index.html**

```html
<!DOCTYPE html>
<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>Document</title>
</head>
<body>
  <!--This is the node that svelte is going to take to make the magic-->
  <div id="root"></div>
</body>
</html>
```

- **.env**
```
foo=bar
```

- **index.js**
```js
import App from './App.svelte';
import './global.css';

const app = new App({
	target: document.getElementById('root'), // entry point in ../public/index.html
});

export default app;
```

- **App.svelte**
```html
<script>
	let name = 'world';
  let envVariable = process.env.foo;
</script>

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

<h1>Hello {name}!</h1>
<p>env variable: {envVariable}</p>
```

- **global.css**
```css
body{
  background-color: #EEEEEE
}
```

**Run our project**

We add the following scripts in our `package.json`

```json
"scripts": {
  "start": "http-server ./dist/ --cors -o -c-1 --proxy",
  "build": "webpack --mode production",
  "dev": "webpack serve --open chrome"
},
```

Then we just run `npm run dev` and see the magic :)

After this, you can start making your svelte application with all features you will need.

If you'd like to contact me, here is my [website](https://rogeliosamuel621.netlify.app)