spack
bundler in RustBecause most JavaScript bundlers and transpilers are written in JavaScript itself, they tend to lack efficiency. However, if bundlers and transpilers were written in a faster, better compiled, and optimized language like Python or Rust, they could operate faster.
In this article, we will discuss how to use the spack
bundler with swc-project
in Rust to speed up JavaScript builds.
swc-project
?swc-project
is a collection of bundlers and a transpilers written in Rust. swc-project
can transpile Typescript, JSX, TSX, and other versions of JavaScript. Like Babel, SWC is a tool for reading source code; however, SWC works about 20 times faster than Babel.
swc
can be configured using the .swcrc
file; see different configurations here.
swc
with spack
spack
is a JS bundler with support for transpiling through swc
. It is an alternative for webpack
with support for dead code elimination and tree shaking.
spack
is purely written in Rust and used by Deno; Deno recently added a new TypeScript bundling and transpiling option based on spack
.
spack
internally relies on swc_bundler
crate for assets bundling.
const { config } = require("@swc/core/spack"); const path = require("path"); module.exports = config({ // starting point entry: { web: path.join(__dirname, "src", "index.ts"), }, // output file output: { path: path.join(__dirname, "dist"), }, module: {}, });
spack
is configured using .swcrc
files for transpilers and spack.config.js
files for bundlers.
To see how it works, create a directory named spack-demo
. In the spack-demo
folder, add the index.js
file and multiple files for demo purposes. Add spack.config.js
and .swcrc
file to directory.
The file structure should look like this.
├── index.js ├── spack.config.js └── .swcrc
Install required packages using npm i @swc/core @swc/cli @swc/helpers
.
For bundling: spack.config.js
// importing config creator const { config } = require("@swc/core/spack"); // import path module const path = require("path"); // export config module.exports = config({ // start file entry: { build: path.join(__dirname, "index.js"), }, // output file output: { path: path.join(__dirname), }, module: {}, });
For transpiling: .swcrc
{ "jsc": { // transpile to es2015 "target": "es2015", "parser": { // file use ecmascript "syntax": "ecmascript", } } }
spack
to bundle JavaScriptThe boilerplate code we added previously can be used for the basic bundling and transpiling required by most code bases like React.js and Node.js.
For a demo, create a directory named mod
with index.js and import index.js
in the root. The file structure should look like this.
├── index.js ├── mod │ └── index.js ├── spack.config.js └── .swcrc
Note that mod/index.js
and index.js
contain dummy code for demonstrating the spack
bundling features:
mod/index.js
export const sum=(a,b)=>a+b;
index.js
import {sum as add} from "./mod" console.log(add(1,2));
build.js
(This file is generated by spack
)
var sum = function(a, b) { return a + b; }; console.log(sum(1,2));
spack
uses swc
for transpiling to multiple version of JavaScript according to the target
key in .swcrc
file. swc
supports ES5, ES2015, ES2016, ES2018, ES2019 and ES2020.
In our previous demo, we wrote code supported by the newer ES2015 version of Javascript, but with spack
, we can transpile our code to older versions of JavaScript that are supported by older browsers. Almost all browsers support the ES5 version of JavaScript.
To see how it works, change target
to es5
and add some newer code to mod/index.js
.
mod/index.js
export const sum=(a,b)=>({...a,...b})
.swcrc
{ "jsc": { // transpile to es5 "target": "es5", "parser": { // file use ecmascript "syntax": "ecmascript", } } }
Your build.js
output file will now look like this:
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _objectSpread(target) { for(var i = 1; i < arguments.length; i++){ var source = arguments[i] != null ? arguments[i] : { }; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _defineProperty(target, key, source[key]); }); } return target; } var sum = function(a, b) { return _objectSpread({ }, a, b); }; console.log(sum({ }, { }));
When you take a closer look to at the build.js
output file, you’ll see that it now contains some extra code to support the newer JS features (like spread operator). All of the additional code is injected by spack
so that our code can run perfectly on browsers old and new, including those that only support the ES5 version of JavaScript.
When dealing with multiple bundles, the build can be optimized by caching common files or modules and avoiding duplicate work. spack
supports multiple bundles simultaneously with caching common files across bundles.
spack.config.js
const { config } = require("@swc/core/spack"); const path = require("path"); module.exports = config({ entry: { web: path.join(__dirname, "src", "index.js"), node: path.join(__dirname, "src", "node.js"), }, output: { path: path.join(__dirname, "dist"), }, module: {}, });
spack
is used by Deno for transpiling and bundling TypeScript. It has full support for TypeScript transpilation and bundling using swc
. swc
compiled passes all the tests on TypeScript repo. TypeScript can be supported by changing the syntax
key to TypeScript.
{ "jsc": { // transpile to es5 "target": "es5", "parser": { // file use ecmascript "syntax": "typescript", } } }
spack
is in its early stages, but until it is production-ready, it can still be used in Rust swc-project
for bundling in the development environment. spack
can also be used as a base library for creating a more robust bundler with multiple features, just as Deno has used for bundling TypeScript.
LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page and mobile apps.
Debugging Rust applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking the performance of your Rust apps, automatically surfacing errors, and tracking slow network requests and load time, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens on your Rust application. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app’s performance, reporting metrics like client CPU load, client memory usage, and more.
Modernize how you debug your Rust apps — start monitoring for free.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowBuild scalable admin dashboards with Filament and Laravel using Form Builder, Notifications, and Actions for clean, interactive panels.
Break down the parts of a URL and explore APIs for working with them in JavaScript, parsing them, building query strings, checking their validity, etc.
In this guide, explore lazy loading and error loading as two techniques for fetching data in React apps.
Deno is a popular JavaScript runtime, and it recently launched version 2.0 with several new features, bug fixes, and improvements […]
2 Replies to "Speed up JavaScript builds with <code>spack</code> bundler in Rust"
âťťa faster, better compiled, and optimized language like Python or Rustâťž
Are you kidding? OK for Rust, but Python is anything but.
when I read the title I assumed that this article must written by some skilled professional in the industry.
But then realised that It is written by someone who even don’t know that
python is not compiled and optimised.
It is definitely very slow when compared to JavaScript running in V8.