This is a premium alert message you can set from Layout! Get Now!

Introducing Turbopack: A Rust-based successor to webpack

0

Once upon a time in web development, building web pages required just HTML, CSS, and some JavaScript for interactivity. This was the typical code structure of most websites:

The typical code structure of most websites

Most often, developers would introduce third-party JavaScript libraries for extra interactivity:

Third-party JavaScript libraries for extra interactivity

JavaScript was perceived as a client-side scripting language during this period — and nothing more. That would soon change, especially with the introduction of Node.js.

Node.js proved that JavaScript had more than just client-side capabilities, and could handle network requests, routing, complex animations, and storage, too.

Then we started building large-scale products like ecommerce sites, social media apps, learning platforms, etc., with JavaScript. This introduced more third-party libraries, but since content delivery networks (CDNs) weren’t popular then, so you had to download the library’s JS files. This made code messy and difficult to maintain, and the developer experience was horrible.

During this period, the ever-progressive JS community started focusing on improving developer experience with developer tools. This led to the birth of bundlers.

Jump ahead:

What are bundlers?

A bundler is simply a development tool aggregating all JS files as input, and outputs a single JS file that is loadable on a web browser. A bundler ensures that all source code and third-party dependencies are up-to-date and error-free.

Before the era of bundling code, optimization and logging were major issues. Bundlers solve that with features such as:

  • Code splitting
  • Hot module replacement (HMR)
  • Loggers

So how do bundlers work behind the scenes?

  • Dependency resolution: The bundler generates a dependency graph of all served files
  • Bundling: The bundler outputs static assets that the browser can parse. This process is referred to as packing

Bundlers like Browserify have existed since 2010, using require to load npm packages in the browser. However, JavaScript didn’t have an inbuilt module system until the introduction of ES2015. A subsequent new wave of modular programming led to the birth of module bundlers like webpack, Rollup, Parcel, and esbuild.

Of all the bundlers, webpack got everyone’s attention first, and is currently the most used bundler with ~28 million weekly downloads.

How webpack approaches dependency resolution

webpack is a static module bundler. When introduced to a project, it generates a dependency graph from one or more entry points (more like index.js), and combines all the modules (JS and non-JS) into one bundle — or more, depending on your configuration.

These bundles become static files (HTML, CSS, JS, assets) that the browser can process. It requires no configuration to bundle your project, but is very configurable.

Let’s briefly take a look at how webpack approaches dependency resolution.

  • Entry point: This is where webpack starts when building its internal dependency graph. By default, it is an index.js file, but you can choose a different entry point or more than one point
webpack.config.js:
module.exports = {
  entry: ['../../index.js', '../../server.js'],
};
  • Output: This is the location of the bundles. By default, the output property creates a dist folder
const path = require('path');module.exports = {
output: {
path: path.resolve(__dirname, 'dist'), },
};
  • Loaders: Ever wondered how webpack parses assets such as HTML, CSS, and media files? it uses loaders, which convert these files into consumable modules and add them to the dependency graph
module.exports = {
module: {
rules: [
{
test: /.(js|jsx)$/,
exclude: "/node-modules/",
use: "babel-loader"
     },
     {
        test: /\.html$/,
        use: "html-loader"
     },
     {
        test: /\.(scss|sass)$/,
        use: ["style-loader", "css-loader", "sass-loader"]
     },
                    {
    test: /\.(png|jpe?g|gif)$/i,
    use: [
      {
        loader: 'file-loader',
      },
    ],
  },
  ]

}

}

  • Plugins: One of the major reasons webpack is loved by all is its plugin system. webpack plugins allow you to perform tasks such as bundle optimization, asset management, and injection of environment variables via plugins
const BrotliPlugin = require('brotli-webpack-plugin');
module.exports = {
plugins: [
new BrotliPlugin({
asset: '[path].br[query]',
test: /.(js|css|html|svg)$/,
})
]
}
  • Mode: By setting a mode, you choose the environment webpack optimizes for
module.exports = {
  mode: 'development',
};

These are the core concepts of webpack. If you’ve worked with JavaScript frameworks such as Vue, React, Angular, and so on, you’ll notice these core webpack concepts are implemented. This is because these frameworks use webpack for bundling.

The impact of webpack in frontend tooling and architecture is vast. It’s widely used in single-page applications (SPAs), applications that use server-side rendering (SSR), and static site generators (SSGs). In short, other language frameworks, such as PHP (Laravel) and Ruby (Rails), use webpack to manage JavaScript, CSS, and static assets, like images or fonts.

Moreover, with the availability of native ES modules in the browser and the rise of JavaScript tools written in compile-to-native languages, the choice of bundler requires more attention.

Known issues with webpack

  • Slow development server: The webpack plugin system is one of its biggest pros and cons: its heavy reliance on plugins to perform certain tasks can slow down the bundler and increase the time it takes to start the development server
  • Rebuilds on change: The entire application is rebuilt every time you make changes to a file. Imagine what happens in larger projects
  • Complexity: As a project grows and more plugins are introduced, the configuration becomes more complex
  • It generates code that is impossible to read. This is always a problem, especially when refactoring code in a large project

These issues led the ever-progressive JS community to develop better alternatives to webpack. One of the most successful alternatives so far is Vite. Let’s briefly explore Vite.

Comparing Vite to webpack

Vite is a build tool that provides a faster development experience in web projects. Unlike a bundler, Vite consists of two parts:

  1. Rollup, which is used for code bundling
  2. A dev server with extensive features, including fast Hot Module Replacement (HMR)

The HMR API in Vite is considerably faster than webpack. Vite solves the slow development server problem we have with webpack, even as the project expands. It also ushers in a new era of ESM-based development tools and bundleless architecture. We won’t go deep into Vite, cause it’s past the scope of this article, but the goal of introducing it is so you’ll note these points:

  • Vite is a build tool, not a bundler. It’s faster, and most teams are migrating from webpack to Vite as a result
  • Vite is not a direct replacement for webpack — it’s just better than webpack in most cases

These points raise the question, “If Vite isn’t the successor to Webpack, what is?” A few weeks ago, Vercel answered that question with the release of Turbopack. In the next section, we’ll learn about what Turbopack is, its pros and cons, how to use it in a Next.js project, and what makes it better than webpack. We’ll briefly discuss the future of webpack-based projects as well.

What is Turbopack?

Turbopack is an incremental bundler optimized for your JavaScript and TypeScript projects. Unlike other bundlers written in JS/TS, Turbopack is Rust-based. It’s the official successor to webpack, and is being built by the creators of webpack and Next.js.

Turbopack claims to be 700x faster than webpack and 10x faster than Vite in large project (though Vite’s creator disagrees with this). So what makes Turbopack so fast?

Compilation by request

We’ve discussed the importance of startup time in developer experience and how the webpack dev server is slow to start as the project gets bigger because it rebuilds the entire application every time a file is changed. Turbopack, on the other hand, compiles only the code needed to start the project.

Using Turbo Engine

Turbo Engine is a powerful Rust library that enables incremental computation. In computer science, incremental computation refers to using the previously computed output when computing a new output when a sequence of inputs is slightly different from each other, rather than computing the new output from scratch. This computation is applied when optimizing compilers. One way to achieve incremental computation is through caching. Turbo Engine implements incremental computation using function-level caching.  Let’s explore the features and drawbacks of Turbopack.

How function-level caching works.

Features and drawbacks of Turbopack

Let’s highlight some of the features of Turbopack:

  • Faster development server time: Turbopack supports HMR out of the box, and it’s way faster due to incremental computation. HMR ensures your dev server doesn’t fully refresh after every file change
  • Out-of-the-box support for JS & TS: Turbopack bundles JavaScript and TypeScript, but not with Babel. Instead, Turbopack uses a Rust-based compilation tool, SWC (Speedy Web Compiler). For context, SWC claims to be 17x faster than Babel
  • Out-of-the-box support for CJS and ESM imports: Whatever method you use to import modules — dynamic imports, ES Modules, or CommonJS — it’s supported by Turbopack
  • Live reloading for environmental variables: One of the most annoying experiences when developing is having to close and reload your server after changing environmental variables. Turbopack ships with live reloading for environmental variables

Let’s highlight some of Turbopack early drawbacks. It’s important to note that Turbopack is still very new and experimental, so these issues might be fixed as it matures.

  • Lacks god-level extensibility: webpack had what I refer to as god-level extensibility with its plugin API. Turbopack doesn’t support plugins, but they promise that the bundler will be extensible in future versions. However, they won’t be porting the webpack plugin API, meaning most webpack plugins you enjoy today won’t work with Turbopack.
  • Does not perform type checks: Turbopack uses SWC for compiling TypeScript, and doesn’t have out-of-the-box support for type checking. Like Vite and esbuild, with Turbopack, you must run tsc --watch or depend on your code IDE for type checking.
  • Only supports the Next.js dev server

How to use Turbopack

Turbopack is still in its alpha version and has only been deployed as a Next.js 13 dev server. To run a Next.js 13 project powered by Turbopack, run this command on your terminal:

<

pre class=”language-bash hljs>npx create-next-app –example with-turbopack

This command will bootstrap a Next.js 13 sample with React Server Components. Run yarn install to install dependencies.

Now for the moment of truth. Let’s run the project with yarn dev:

Running the project with yarn.dev.

A compilation time of 6.264ms with 20+ components!

For context, let’s compare this startup time with a non-Turbopack Next.js 13 project, with fewer components and dependencies.

Turbopack Next.js project

We compiled client and server in 11s, almost twice the Turbopack compile time!

The difference is clear. We can only look forward to when Turbopack will be a low-level engine for other frameworks.

Migrating from webpack

As we’ve discussed, Turbopack is still in experiment mode and is not yet ready for production environments. So at the time of writing this article, you can’t port your project to Turbopack.

What this means for webpack users

Firstly, for webpack aficionados, Turbopack is a preview of the future. webpack has roughly 26 million weekly downloads, which will continue for as long as possible until the project maintainers pull the plug.

If you visit Snowpack, which is not maintained anymore, you will be advised to use Vite. I imagine the same thing will happen with webpack and Turbopack in the future.

However, Turbopack is managed by Vercel, and we don’t know when the bundler will be ready for wide, production-grade adoption. I recommend using Vite in the interim if you’re looking for an alternative to webpack.

Conclusion

Turbopack is a promising project that will certainly redefine bundling tools architecture in an era where build tools such as Vite and esbuild are replacing bundlers. In this article, we learned what bundlers are and how they work. Then we introduced webpack as the bundler par excellence tool; we went on to learn its core concepts and briefly explored Vite as an alternative to webpack.

We also covered Vite as a build tool, and not a successor to webpack. This introduced us to Turbopack. We learned what Turbopack was, how it worked, its top features and issues, how to use it in a project, and how it affects existing webpack users.

The post Introducing Turbopack: A Rust-based successor to webpack appeared first on LogRocket Blog.



from LogRocket Blog https://ift.tt/XoGlHpZ
Gain $200 in a week
via Read more

Post a Comment

0 Comments
* Please Don't Spam Here. All the Comments are Reviewed by Admin.
Post a Comment

Search This Blog

To Top