# Configure for build

To configure SWC for a production environment, execute the following steps.

# Install the packages

Open a terminal at the root of the project and install the following packages:

pnpm add -D @workleap/swc-configs @swc/core @swc/helpers
yarn add -D @workleap/swc-configs @swc/core @swc/helpers
npm install -D @workleap/swc-configs @swc/core @swc/helpers

# Configure SWC

First, create a configuration file named swc.build.js at the root of the project:

web-project
├── src
├──── ...
├── package.json
├── swc.build.js

Then, open the newly created file and export the SWC configuration by using the defineBuildConfig(targets, options) function:

swc.build.js
// @ts-check

import { browserslistToSwc, defineBuildConfig } from "@workleap/swc-configs";

const targets = browserslistToSwc();

export const swcConfig = defineBuildConfig(targets);

# targets

In the previous code sample, the defineBuildConfig(targets, options) function receives a list of minimal browser versions to support through the targets parameter.

The expected behavior for the supported browsers would be for SWC to automatically load the minimal browser versions from the closest .browserslistrc configuration file. However, there is currently an issue preventing SWC from doing so when the configuration file include a query referencing an external Browserslist configuration:

.browserslistrc
extends @workleap/browserslist-config

Therefore, @workleap/swc-configs has chosen to delegate the loading of the Browserslist configuration to the consumer by making the targets option required.

# browserslistToSwc

To help consumers provide SWC targets from a Browserslist configuration, @workleap/swc-configs offers the browserslistToSwc(options) utility function.

This function can either transform an array of Browserslist queries to SWC targets:

swc.dev.js
// @ts-check

import { browserslistToSwc, defineBuildConfig } from "@workleap/swc-configs";

const targets = browserslistToSwc({ queries: ["extends @workleap/browserslist-config"] })

export const swcConfig = defineBuildConfig(targets);

Or load the closest .browserslistrc configuration file and convert the queries into SWC targets:

.browserslistrc
extends @workleap/browserslist-config
swc.build.js
// @ts-check

import { browserslistToSwc, defineBuildConfig } from "@workleap/swc-configs";

const targets = browserslistToSwc();

export const swcConfig = defineBuildConfig(targets);

The browserslistToSwc(options) utility function accepts any option supported by Browserslist JS API in addition to a queries option:

  • queries: string | string[]

# Use predefined options

The defineBuildConfig(targets, options) function can be used as shown in the previous example, however, if you wish to customize the default configuration, the function also accept a few predefined options to help with that 👇

# baseUrl

  • Type: string

Sets a base directory from which to resolve module names. This option is usually provided when custom paths are provided. Note that SWC requires the baseUrl to be an absolute path.

swc.build.js
// @ts-check

import path from "node:path";
import { browserslistToSwc, defineBuildConfig } from "@workleap/swc-configs";

const targets = browserslistToSwc();

export const swcConfig = defineBuildConfig(targets, {
    baseUrl: path.resolve("src")
});

# parser

  • Type: "ecmascript" | "typescript"
  • Default: "typescript"

Whether SWC should expect to parse JavaScript or TypeScript code.

swc.build.js
// @ts-check

import { browserslistToSwc, defineBuildConfig } from "@workleap/swc-configs";

const targets = browserslistToSwc();

export const swcConfig = defineBuildConfig(targets, {
    parser: "ecmascript"
});

# paths

  • Type: Record<string, string[]>

A series of entries which re-map imports to lookup locations relative to the baseUrl if set.

swc.dev.js
// @ts-check

import path from "node:path";
import { browserslistToSwc, defineBuildConfig } from "@workleap/swc-configs";

const targets = browserslistToSwc();

export const swcConfig = defineBuildConfig(targets, {
    baseUrl: path.resolve("src"),
    paths: {
        "@/*": ["*"]
    }
});

# Configuration transformers

The predefined options are useful to quickly customize the default build configuration of @workleap/swc-configs, but only covers a subset of an SWC configuration. If you need full control over the configuration, you can provide configuration transformer functions through the transformers option of the defineBuildConfig function. Remember, no locked in ❤️✌️.

To view the default development configuration of @workleap/swc-configs, have a look at the build.ts configuration file on GitHub.

# transformers

  • Type: ((config: SwcConfig, context: SwcConfigTransformerContext) => SwcConfig)[]
  • Default: []
transformer(config: SwcConfig, context: SwcConfigTransformerContext) => SwcConfig
swc.build.js
// @ts-check

import { browserslistToSwc, defineBuildConfig } from "@workleap/swc-configs";

const targets = browserslistToSwc();

/**
 * @type {import("@workleap/swc-configs").SwcConfigTransformer}
 */
function mangleMinifiedCode(config) {
    config.jsc.minify.mangle = true;

    return config;
}

export const swcConfig = defineBuildConfig(targets, {
    transformers: [mangleMinifiedCode]
});

# Execution context

Generic transformers can use the context parameter to gather additional information about their execution context, like the environment they are operating in:

transformer.js
// @ts-check

/**
 * @type {import("@workleap/swc-configs").SwcConfigTransformer}
 */
export function transformer(config, context) {
    if (context.environment === "build") {
        config.jsc.minify.mangle = true;
    }

    return config;
};
  • environment: "dev" | "build" | "jest"

# Configure webpack

To integrate with webpack, update your configuration file to include an swc-loader:

webpack.config.js
// @ts-check

import { swcConfig } from "./swc.build.js";

export default {
    ...
    module: {
        rules: [
            {
                test: /\.(js|jsx|ts|tsx)/i,
                exclude: /node_modules/,
                use: {
                    loader: "swc-loader",
                    options: swcConfig
                }
            }
        ]
    }
}

# Try it 🚀

To test your new SWC configuration, create a Typescript file with the following code:

say.ts
export function say(string: value) {
    console.log(value);
}

If you integrated SWC with webpack, make sure to import the previously created file in one of your webpack entry points, then execute your webpack build and find the transpiled code in the generated bundle files of your dist folder.

Otherwise, open a terminal at the root of your project and install @swc/cli:

pnpm add -D @swc/cli @swc/core
yarn add -D @swc/cli @swc/core
npm install -D @swc/cli @swc/core

Then, process the file with @swc/cli by executing the following command in the same terminal:

npx swc ./say.ts -o say.js --config-file swc.build.js

Whether you processed the file with webpack or @swc/cli, the transpiled code should be:

say.js
export function say(value) {
    console.log(value);
}