Speed up JavaScript builds with spack bundler in Rust
source link: https://blog.logrocket.com/using-spack-bundler-in-rust-to-speed-up-builds/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Because 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.
What is 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.
Transpiling through 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: {}, });
Configuring bundlers and transpilers
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", } } }
Using spack
to bundle JavaScript
The 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));
Transpiling to older JavaScript
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.
Bundling multiple JavaScript entries
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: {}, });
Bundling TypeScript
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", } } }
Conclusion
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: Full visibility into production Rust apps
Debugging Rust applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking 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 apps, recording literally everything that happens on your Rust app. 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.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK