post.thumbnail.alt

Set up a React starter with Snowpack

18th April 2021

Filed Under:

  • Studio Notes

Photo by Chris Biron on Unsplash

We want a react app with, Typescript, Jest, Eslint, Prettier, and React Testing Library all ready to go.

TLDR: The npm install commands

npm init
npm install react react-dom
npm install --save-dev snowpack eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin prettier eslint-config-prettier eslint-plugin-prettier eslint-config-xo jest @testing-library/react @testing-library/jest-dom ts-jest babel-jest eslint-plugin-jest @snowpack/plugin-typescript @snowpack/plugin-build-script @snowpack/plugin-run-script @snowpack/plugin-sass @types/react @types/react-dom @types/jest

If you want you can just clone the repo

Start a new project

npm init

Then add Snowpack

npm install --save-dev snowpack

Setup React

npm install react react-dom

Linting

At this point we have a dilemma. With Webpack I would install and setup xo-cli, however XO does not have a CLI plugin for snowpack. We have two options either we create our own plugin, or simply use the XO eslint config. Writing a snowpack-plugin seems pretty straight forward; but it’s my weekend and I’ve not yet decided to use this toolchain in my day to day job — so quick wins for the win… I have a toolchain to configure so I can build my app. Onwards!

Add eslint-config-xo

npm install --save-dev eslint-config-xo

Setup eslint and prettier

npm install --save-dev eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin prettier eslint-config-prettier eslint-plugin-prettier @snowpack/plugin-build-script @snowpack/plugin-typescript @snowpack/plugin-run-script

Add an eslintConfig to your package.json


/* the start of your package.json */
 "eslintConfig": {
        "root": true,
        "parser": "@typescript-eslint/parser",
        "plugins": [
            "@typescript-eslint",
            "eslint-plugin-prettier",
            "jest"
        ],
        "extends": [
            "eslint-config-xo",
            "eslint-config-prettier"
        ],
        "env": {
            "browser": true,
            "jest/globals": true
        },
        // I don't like semi-colons so I turn them off that's just me
        "rules": {
            "semi": "off"
        }
    },
/* the rest of your package.json */

Install Jest & React Testing Library

npm install --save-dev jest @testing-library/react @testing-library/jest-dom ts-jest babel-jest eslint-plugin-jest @babel/preset-react

Install SCSS support

npm install --save-dev @snowpack/plugin-sass

Install your types

npm install --save-dev @types/react @types/jest

Setup Babel & Jest

Create a babel.config.js


 module.exports = {presets: ['@babel/preset-env']}

create a setupTests.ts


import '@testing-library/jest-dom/extend-expect';

Create a jest.config.js


module.exports = {
  preset: 'ts-jest',
  setupFilesAfterEnv: ['<rootdir>/setupTests.ts'],
  transform: {
    '^.+\\.(ts|tsx)?$': 'ts-jest',
    '^.+\\.(js|jsx)$': 'babel-jest',
  },
};</rootdir>

Create a src directory

Setup Typescript by creating a tsconfig.json

{
    "compilerOptions": {
        "outDir": "./dist/",
        "sourceMap": true,
        "strict": true,
        "noImplicitReturns": true,
        "noImplicitAny": true,
        "module": "es6",
        "moduleResolution": "node",
        "target": "es5",
        "allowJs": true,
        "jsx": "react",
        "esModuleInterop": true,
    },
    "include": [
        "./src/**/*",
        "./setupTests.ts",
    ]
}

Create a snowpack.config.json


{
    "mount": {
        "dist": "/",
        "src": "/"
    },
    "plugins": [
        ["@snowpack/plugin-sass", { "style": "compressed" }],
        [
            "@snowpack/plugin-run-script",
            {
                "cmd": "eslint --ext .js,.jsx,.ts,.tsx",
                "watch": "npx esw -w --clear src --ext .js,.jsx,.ts,.tsx"
            }
        ]
    ]
}

Add build rules to your .gitignore

.cache/
coverage/
dist/*
!dist/index.html
node_modules/
*.log

Setup a basic structure for your React app

Create a components folder and create an App.tsx

import * as React from 'react';
interface Props {
}
export default function App({}: Props) {
  return (
    <div>
      <h1>Hello world</h1>
    </div>
  )
}

Create a styles folder

Reset your css

Create a new file styles/config/_reset.scss and add your reset.

I’m using Andy Bell’s modern-css-reset

Create a styles/index.scss

@import 'config/reset';

Create an index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Your Project Name</title>
    <meta name="description" content="A description of my app" />
    <meta name="author" content="Neil Ross" />
    <meta charset="utf-8" />
    <link rel="stylesheet" href="styles/index.css">
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="index.js"></script>
  </body>
</html>

Create an index.tsx

import * as React from 'react';
import * as ReactDOM from "react-dom";
import App from './components/App';
import "./styles/index.scss";
var mountNode = document.getElementById("app");
ReactDOM.render(<App />, mountNode);

Insert snowpack scripts into your package.json

// <the start of your package.json >
 "scripts": {
    "clean": "rm dist/bundle.js",
    "start": "snowpack dev",
    "build": "snowpack build",
    "test": "jest",
    "jest": "jest --watch"
  },
// <the rest of your package.json >

Start the Project

npm start

Comments

Add your comment