safe React apps in vanilla JavaScript
Webpack config
Now let’s call for help our internal Senior Webpack Config Developer to setup our module bundler ? :
Standard stuff… setting up entry, output, loaders, plugins, bla bla bla… ?
Application folder structure
With our environment setup and configured, let’s build standard folder structure and add React dependencies:
mkdir -p src/app && \touch src/{main.js,index.html,style.css,app/app.jsx}
which will get us folder structure like following:
|-src/| |- app/| | |- app.jsx| |- index.html| |- main.js| |- style.css
And at last add React and stuff…
PRO TIP ?:
3rd party types (@types/*
) should be installed as dev dependencies. Why ? Well your production code doesn't use them nor runtime as they are striped away ?
yarn add react{,-dom} tslib papercss
# as React is not written with TypeScript # we need to install external type annotationsyarn add -D @types/react{,-dom}
Now our index.html
is gonna contain some basic boilerplate for booting up a React SPA ( mount point div) and it's gonna be processed by webpack, which will inject our bundle file within it (kudos to html-webpack-plugin
src/index.html:
<body> <div id="app">Loading... ?</div></body>
Now let’s finally write some JavaScript !
Introducing our root App component:
src/app/app.jsx:
import React, { Component } from 'react'
export class App extends Component { render() { return <div className="container">It Works!</div> }}
Looks good. Now we write a tiny bootstrap function to mount our React app to the DOM:
src/main.js:
import { createElement } from 'react'import { render } from 'react-dom'
import 'papercss/dist/paper.min.css'import './style.css'
import { App } from './app/app'
const bootstrap = () => { const mountTo = document.getElementByID('app') render(createElement(App), mountTo)}
bootsrap()
Alright! Let’s see if it works.
Execute order 66, bah I meant webpack-dev-server in dev mode:
yarn webpack-dev-server -d
Boom ? ? ? we got errors! Oh no!
Fixing our webpack config
So what’s the standard workflow to fix this error? Well, let’s call our Senior Webpack specialist. But wait! he wrote that config, if he cannot get it right, who can? Maybe Sean T. Larkin ? He’ll be busy for sure …? .. mmm so who again?
TypeScript can! ???
What ?! Are you kidding ?
TypeScript has superb capabilities in terms of both vanilla JS and TS files type checking and because our app is just vanilla JS, we would like to leverage that former behavior.
To enable type checking within JavaScript,
we need to add //@ts-check
pragma in our js file.
Let’s do that now:
webpack.config.js:
// @ts-check
We’ll get immediate feedback that something’s not ok, supported by red squiggles within our editor on our module.export
line... whops it need's to be module.exports
Martin, common it's common ... JS ! Let's fix it.
Now our webpack is still failing…
We don’t have time for this, let’s fix it for good, shall we ?
First we need to install 3rd party type definitions for packages that are not shipped with those (or aren’t written in TS):
yarn add -D @types/{node,html-webpack-plugin,webpack,webpack-dev-server}
Now let’s annotate our webpack config constant via standard JSDoc which will leverage TypeScript for importing particular type declaration from any file or library:
/** * @type {import('webpack').Configuration} */const config = { /*...*/}
and with that, we’ll immediately see what’s wrong with our config! TYPOS! GRR ???
Let’s fix those and try to run our app again
Compilation succeeded ! YAY!
Let’s check our bundled app running within a browser:
Whaaaat? ? errors again?
Fixing our initial app runtime errors
To get proper type checking within our components and js files in general, we need to annotate those with // @ts-check
as we did within our webpack.config.js
And with that we can immediately see all the errors! Typos again…
We can already see benefits of having a type system within our app even without knowing about it!
With that covered let’s build our React Todo App