DEV Community

loading...
Cover image for Blazing fast TypeScript with Webpack and ESBuild

Blazing fast TypeScript with Webpack and ESBuild

Karan Pratap Singh
Software Engineer & Solutions Architect
Updated on ・2 min read

Recently, I migrated a project I've been working on to TypeScript. I decided to use Webpack in combination with esbuild loader. The reason being esbuild ecosystem is still relatively new when compared to other bundlers like Webpack, rollup, parcel etc. in terms of plugins and loaders.

Code for this article is available here.

I've also made a video for you, if you're a visual learner like me!

What is Webpack?

At its core, webpack is a static module bundler for modern JavaScript applications. Basically it takes all your code, assets, dependencies and bundles them into static files that are easier to work with and deploy. You can read more about it here

What is esbuild?

esbuild is an extremely fast JavaScript bundler, upto 10-100x fast. You can check the benchmark and read more here.

esbuild-benchmark

Getting started

Let's assume we have simple hello world typescript project

├── dist
├── index.ts
├── package.json
├── tsconfig.json
└── yarn.lock
Enter fullscreen mode Exit fullscreen mode

Installing Webpack

Let's install webpack and webpack-cli, we'll be using Webpack 5

yarn add -D webpack webpack-cli
Enter fullscreen mode Exit fullscreen mode

Let's install the plugins

Now we'll install the following plugins:

esbuild-loader (secret sauce!)
fork-ts-checker-webpack-plugin (helps us with typechecking)
nodemon-webpack-plugin (We can also use webpack-dev-server)

yarn add -D esbuild-loader fork-ts-checker-webpack-plugin nodemon-webpack-plugin
Enter fullscreen mode Exit fullscreen mode

Let's create our Webpack config

Let's build our webpack config! You can read more about the config here

// External modules
const path = require('path');

// Webpack plugins
const NodemonPlugin = require('nodemon-webpack-plugin');
const ForkTsCheckerPlugin = require('fork-ts-checker-webpack-plugin');

// Environment config
const isDevelopment = process.env.NODE_ENV !== 'production';
const mode = isDevelopment ? 'development' : 'production';

// Bundle config options
const BUNDLE = {
  entry: './index.ts',
  output: {
    filename: 'app.js',
    path: path.resolve(__dirname, 'dist')
  }
};

module.exports = {
  mode,
  target: 'node',
  entry: BUNDLE.entry,
  stats: 'errors-only',
  module: getLoaders(),
  plugins: getPlugins(),
  resolve: {
    extensions: ['.tsx', '.ts', '.js', '.json']
  },
  output: BUNDLE.output
};

/**
 * Loaders used by the application.
 */
function getLoaders() {
  const esbuild = {
    test: /\.(js|jsx|ts|tsx)?$/,
    loader: 'esbuild-loader',
    options: {
      loader: 'tsx',
      target: 'es2015'
    },
    exclude: /node_modules/
  };

  const loaders = {
    rules: [esbuild]
  };

  return loaders;
}

/**
 * Plugins
 */
function getPlugins() {
  const nodemon = new NodemonPlugin();
  const tsChecker = new ForkTsCheckerPlugin();

  return [tsChecker, nodemon];
}
Enter fullscreen mode Exit fullscreen mode

Adding scripts

Let's add some scripts to our package.json. During development we'll take advantage of Webpack's Hot Module Replacement with the --hot flag

"start": "yarn build --watch --hot",
"build": "webpack --color --progress"
Enter fullscreen mode Exit fullscreen mode

Let's start our app!

yarn start
Enter fullscreen mode Exit fullscreen mode

Note: You can use webpack-node-externals to ignore any node_modules from your bundle

Great! Now you should be up and running! Feel free to reach out to me on Twitter if you face any issues.

Discussion (2)

Collapse
mindplay profile image
Rasmus Schultz

Can you explain why? What's the advantage of this over just running esbuild?

The only reason I can think to do this, is the need for something like Babel to down-level the code for IE11 - but if you add Babel, the build is immediately slow again. And speed seems to be the primary advantage to using esbuild, right?

Who would someone combine webpack and esbuild? What are you getting that esbuild can't give you?

Collapse
karanpratapsingh profile image
Karan Pratap Singh Author

Hi, this is a great question...We can certianly replace the webpack with just esbuild alone, my reason for not doing so was due to the fact webpack's ecosystem has better plugins which was quite important for the project I was working on.

Since this setup is mainly focused for node, so I didn't require babel loader to optimize for browsers...for frontend I use vitejs.dev (also uses esbuild).

But if just esbuild fits your project, you can certainly do it without webpack

Hopefully this answer helps