Usually we use create-react-app which does some magic behind the scenes like Webpack. Webpack is annoying, so let’s see how the app can work without it. I’ll try esbuild in this article instead.
We only need 3 packages:
yarn add react esbuild typescript
React is for components rendering
and esbuild to do all the magic instead of Webpack:
- Transform jsx to JavaScript
- Transform Typescript to JavaScript
- Bundling all our code and node modules to one file
- Simple http server to serve bundled index.js
So we don’t even need babel. I like babel, but esbuild already handles code transformation for us.
First of all let’s compile a command to use on yarn start:
./node_modules/.bin/esbuild index.tsx --bundle --outdir=. --servedir=. --loader:.js=tsx --watch
Where
—watch
- to watch for changes so live reload is possible
--loader:.js=tsx
- so esbuild understands and transforms Typescript
--outdir=. --servedir=.
- to use a local esbuild http server. “.”
- current path
Now let’s make index.html
. We only need some basic structure inside:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Minimal Example</title>
</head>
<body>
<div id="app"></div>
<script src="index.js"></script>
</body>
</html>
So we can try to write some code:
App.tsx
:
import React from 'react';
class App extends React.Component {
render() {
return (
<div>
</div>
);
}
}
React.render(<App />, document.body);
If we want to enable live reloading we also need this line in App.tsx:
new EventSource('/esbuild').addEventListener('change', () => location.reload())
The next step is to check if bundling works as expected. Let’s add a component in a separate file.
Final code:
App.tsx
:
import React from 'react';
import { Name } from './components/Name';
new EventSource('/esbuild').addEventListener('change', () => location.reload())
class App extends React.Component {
render() {
return (
<div>
<h1><Name name="Artem"></Name></h1>
</div>
);
}
}
React.render(<App />, document.body);
components/Name.tsx
:
import React from 'react';
type TName = 'Artem' | 'Vlad' | 'Ivan';
interface NameProps {
name: TName;
}
class Name extends React.Component<NameProps> {
render() {
return <div>Hello from {this.props.name}</div>
}
}
export { Name };
At last we can run the code to see how it works:
yarn start
// ./node_modules/.bin/esbuild index.tsx --bundle --outdir=. --servedir=. --loader:.js=tsx --watch
Top comments (0)