Preact Setup Timelapse Raw

Notes from setting up [a Preact-based SPA](https://github.com/afreeorange/preact-boilerplate-timelapse) from ground up.

### Initial Setup

```bash
# Initialize the project
npm init

# Install webpack stuff
npm install webpack@3.11.0 webpack-cli@2.0.9 webpack-dev-server@3.0.0 --save-dev
```

I had to install those specific versions. Webpack 4-beta didn't work for me. `webpack-dev-server@3.1.0` game me this delightful error

```
/Users/nikhil/Downloads/git-preact-wiki/node_modules/webpack-dev-server/bin/webpack-dev-server.js:405
    throw e;
    ^

TypeError: Cannot read property 'plugin' of undefined
```

The `stylelint-loader` didn't work with Webpack 4 and `webpack-dev-server`. Frontend development is _exciting_.

My project [looked like this](https://github.com/afreeorange/preact-boilerplate-timelapse/tree/1f6bf9bd17279b187f0805ae0657dfa89b7ed651) with a [base Webpack config](https://github.com/afreeorange/preact-boilerplate-timelapse/blob/1f6bf9bd17279b187f0805ae0657dfa89b7ed651/webpack.config.js).

I then created a [source folder](https://github.com/afreeorange/preact-boilerplate-timelapse/tree/eee2b920251ec08c9fa04353af4dfc869b037d09) with a simple [App.js](https://github.com/afreeorange/preact-boilerplate-timelapse/blob/eee2b920251ec08c9fa04353af4dfc869b037d09/src/App.js).

Added [two commands](https://github.com/afreeorange/preact-boilerplate-timelapse/blob/1f6bf9bd17279b187f0805ae0657dfa89b7ed651/package.json#L7) to `package.json`: one that builds the project and another that launches the live-reloading dev server.

### Babel


```bash
npm i -D babel-loader @babel/core @babel/preset-env
```

I [updated the Webpack config](https://github.com/afreeorange/preact-boilerplate-timelapse/commit/ac3acccd0a68b9092c302bf1c2f15028c491d95e) to use the loader and tested.

### HTML Template

```bash
npm i -D html-webpack-plugin
```

Created a small template for the SPA called [`./src/index.html`](https://github.com/afreeorange/preact-boilerplate-timelapse/commit/323fd386807c374096edd7e38a680c25161752f2#diff-e249faefed5757034596c5096d33dab6) and [updated the Webpack config](https://github.com/afreeorange/preact-boilerplate-timelapse/commit/323fd386807c374096edd7e38a680c25161752f2#diff-11e9f7f953edc64ba14b0cc350ae7b9d) to use it.

At this point, running `npm start` successfully showed me my SPA.

### Preact and a simple SPA

```bash
npm i -D preact
```

[Updated `src/App.js`](https://github.com/afreeorange/preact-boilerplate-timelapse/commit/36e1613fe31d33e6b3864364c284d05159b48338#diff-14b1e33d5bf5649597cdc0e4f684dadd) to import Preact and display a simple component.

### JSX

```bash
npm i -D babel-plugin-transform-react-jsx
```

[Updated the Webpack config](https://github.com/afreeorange/preact-boilerplate-timelapse/commit/f8e2435abbc602118320931e912d31b88be337a9#diff-11e9f7f953edc64ba14b0cc350ae7b9d) to use the plugin and tried [using JSX in `src/App.js`](https://github.com/afreeorange/preact-boilerplate-timelapse/commit/f8e2435abbc602118320931e912d31b88be337a9#diff-14b1e33d5bf5649597cdc0e4f684dadd). So far so good.

### Linting ES6

```bash
# Linting. Using the AirBnB guide. Make sure ESLint doesn't barf on JSX
npm i -D eslint \
         eslint-loader \
         eslint-plugin-import \
         eslint-config-airbnb-base \
         eslint-plugin-react \
         babel-eslint
```

Added a [basic ESLint configuration](https://github.com/afreeorange/preact-boilerplate-timelapse/commit/fad85772c0ee30d7db1552c71d0e0b3611a5d9d4#diff-df39304d828831c44a2b9f38cd45289c) to the root of the project and [updated Webpack](https://github.com/afreeorange/preact-boilerplate-timelapse/commit/fad85772c0ee30d7db1552c71d0e0b3611a5d9d4#diff-11e9f7f953edc64ba14b0cc350ae7b9d) to use the loader. Now I have linting with the live-reload server :)

### Clean Before Build

```bash
npm i -D clean-webpack-plugin
```

[Updated Webpack](https://github.com/afreeorange/preact-boilerplate-timelapse/commit/71b0ccdb30ad834aeeb1a6b379807ef8d814243c#diff-11e9f7f953edc64ba14b0cc350ae7b9d) to use the plugin. Easy-peasy.

### Uglify JS Output

```
npm i -D uglifyjs-webpack-plugin
```

And [updated Webpack](https://github.com/afreeorange/preact-boilerplate-timelapse/commit/467c225358d225086514891b5c3827010943fbe5#diff-11e9f7f953edc64ba14b0cc350ae7b9d).

### Getting Sassy

Wanted to add Sass support and create a separate, compiled, minified file `App.css` in the output

```bash
npm i -D extract-text-webpack-plugin style-loader css-loader sass-loader node-sass
```

Added [a simple Sass file](https://github.com/afreeorange/preact-boilerplate-timelapse/commit/c1189057ca0c36d035f8d4f5e5d0f7643e6da0c8#diff-f03d0bbe56a074dd841d993fa82c1bfb) and [updated Webpack](https://github.com/afreeorange/preact-boilerplate-timelapse/commit/c1189057ca0c36d035f8d4f5e5d0f7643e6da0c8#diff-11e9f7f953edc64ba14b0cc350ae7b9d) to use the plugins and spit out `App.css`.

### Add Sass Linting

```bash
# Does not work with Webpack 4 beta and the dev server
npm i -D stylelint stylelint-webpack-plugin stylelint-config-standard
```

Added [a basic StyleLint config](https://github.com/afreeorange/preact-boilerplate-timelapse/commit/e3f4312bd59452a3b3c162557ed6b1fb52f313b5#diff-3d9639f99b2cd6bda90b892bea090bef) and [updated Webpack](https://github.com/afreeorange/preact-boilerplate-timelapse/commit/e3f4312bd59452a3b3c162557ed6b1fb52f313b5#diff-11e9f7f953edc64ba14b0cc350ae7b9d) to use it.

### Assets → Base64

```bash
# Does not work with Webpack 4 beta
npm i -D base64-inline-loader
```

[Updated Webpack](https://github.com/afreeorange/preact-boilerplate-timelapse/commit/966c1b406968ccc60a173d55db84a4fc1f4c15cb#diff-11e9f7f953edc64ba14b0cc350ae7b9d)