# Configure for development

To configure Rslib for a development environment, execute the following steps 👇

# Install the packages

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

pnpm add -D @workleap/rslib-configs @rslib/core @rsbuild/core
yarn add -D @workleap/rslib-configs @rslib/core @rsbuild/core
npm install -D @workleap/rslib-configs @rslib/core @rsbuild/core

# Configure Rslib

# tsconfig.build.json

First, create a tsconfig.build.json file at the root of the project:

library-project
β”œβ”€β”€ src
β”œβ”€β”€β”€β”€ ...
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
β”œβ”€β”€ tsconfig.build.json

Then, open the newly created tsconfig.build.json file and copy/paste the following content:

tsconfig.build.json
{
    "extends": "@workleap/typescript-configs/library.json",
    "include": ["src"],
    "exclude": ["dist", "node_modules"]
}

# rslib.dev.ts

Next, create a configuration file named rslib.dev.ts at the root of the project:

library-project
β”œβ”€β”€ src
β”œβ”€β”€β”€β”€ ...
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
β”œβ”€β”€ tsconfig.build.json
β”œβ”€β”€ rslib.dev.ts

Then, open the newly created file and export the Rslib configuration by using the defineDevConfig(options) function:

rslib.dev.ts
import { defineDevConfig } from "@workleap/rslib-configs";

export default defineDevConfig();

# Use predefined options

The defineDevConfig(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 👇

# entry

  • Type: An object literal accepting any source.entry options.
  • Default: { index: "./src/**" } when the bundle option is false, otherwise { index: ["./src/index.ts", "./src/index.js"] }.

Set Rslib source.entry option.

rslib.dev.ts
import { defineDevConfig } from "@workleap/rslib-configs";

export default defineDevConfig({
    entry: {
        index: "./src/another-entry.tsx"
    }
});

# syntax

  • Type: string
  • Default: esnext

Set Rslib lib.syntax option.

rslib.dev.ts
import { defineDevConfig } from "@workleap/rslib-configs";

export default defineDevConfig({
    syntax: "es2024"
});

# bundle

  • Type: boolean
  • Default: false

Whether or not to ouput a single code bundle. To output a single code bundle, set the option to true.

rslib.dev.ts
import { defineDevConfig } from "@workleap/rslib-configs";

export default defineDevConfig({
    bundle: true
});

# tsconfigPath

  • Type: string
  • Default: undefined

Set Rslib source.tsconfigPath option. When the bundle option is set to false (default value), the tsconfigPath option is required.

rslib.dev.ts
import { defineDevConfig } from "@workleap/rslib-configs";
import path from "node:path";

export default defineDevConfig({
    tsconfigPath: path.resolve("./tsconfig.build.json")
});

# dts

  • Type: An object literal accepting any lib.dts options.
  • Default: false

Whether or not to generate TypeScript *.d.ts files. To generate *.d.ts files, set the option to true.

rslib.dev.ts
import { defineDevConfig } from "@workleap/rslib-configs";

export default defineDevConfig({
    dts: true
});

# target

  • Type: string
  • Default: web

Set Rslib output.target option.

rslib.dev.ts
import { defineDevConfig } from "@workleap/rslib-configs";

export default defineDevConfig({
    target: "node"
});

# distPath

  • Type: string
  • Default: dist

Set Rsbuild output.distPath option.

rslib.build.ts
import { defineDevConfig } from "@workleap/rslib-configs";
import path from "node:path";

export default defineDevConfig({
    distPath: path.resolve("./a-custom-folder")
});

# plugins

Append the provided Rsbuild plugins to the configuration.

rslib.dev.ts
import { defineDevConfig } from "@workleap/rslib-configs";
import { pluginAssetsRetry } from "@rsbuild/plugin-assets-retry";

export default defineDevConfig({
    plugins: [pluginAssetsRetry()]
});

# sourceMap

  • Type: false or an object literal accepting any output.sourceMap options.
  • Default: { js: "cheap-module-source-map", css: true }

Whether or not to generate source maps. To disable source map, set the option to false.

rslib.dev.ts
import { defineDevConfig } from "@workleap/rslib-configs";

export default defineDevConfig({
    sourceMap: false
});

To customize the source map configuration, provide an object literal.

rslib.dev.ts
import { defineDevConfig } from "@workleap/rslib-configs";

export default defineDevConfig({
    sourceMap: {
        css: false
    }
});

# react

  • Type: true or (defaultOptions: PluginReactOptions) => PluginReactOptions
  • Default: defaultOptions => defaultOptions

Whether or not to transform React code. To enable React code transformation, set the option to true.

rslib.dev.ts
import { defineDevConfig } from "@workleap/rslib-configs";

export default defineDevConfig({
    react: true
});

To customize plugin-react, provide a function to extend the default options.

rslib.dev.ts
import { defineDevConfig } from "@workleap/rslib-configs";

export default defineDevConfig({
    react: defaultOptions => {
        return {
            ...defaultOptions,
            swcReactOptions: {
                ...(defaultOptions.swcReactOptions ?? {}),
                runtime: "classic"
            }
        };
    }
});

# svgr

  • Type: true or (defaultOptions: PluginSvgrOptions) => PluginSvgrOptions
  • Default: defaultOptions => defaultOptions

Whether or not to handle .svg files with plugin-svgr. To enable SVGR transformation, set the option to true. When this option is not activated, the .svg files will be handled by the asset/resource rule.

rslib.dev.ts
import { defineDevConfig } from "@workleap/rslib-configs";

export default defineDevConfig({
    svgr: false
});

To customize the plugin-svgr, provide a function extending the default options.

rslib.dev.ts
import { defineDevConfig } from "@workleap/rslib-configs";

export default defineDevConfig({
    svgr: defaultOptions => {
        return {
            svgrOptions: {
                ...(defaultOptions.svgrOptions ?? {}),
                ref: true
            }
            ...defaultOptions,

        }
    }
});

# Typings

When an SVG asset in referenced in TypeScript code, TypeScript may prompt that the module is missing a type definition:

TS2307: Cannot find module './logo.svg' or its corresponding type declarations.

To fix this, add a type declaration for the SVG assets, by creating a src/env.d.ts file, and add the type declaration.

src/env.d.ts
declare module '*.svg' {
  export const ReactComponent: React.FunctionComponent<
    React.SVGProps<SVGSVGElement>
  >;
}
declare module '*.svg?react' {
  const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
  export default ReactComponent;
}

For additional information, refer to the plugin documentation.

# Import images

By default, plugin-svgr is configured to support named import for ReactComponent:

import { ReactComponent as Logo } from "./logo.svg";

export const App = () => <Logo />;

# Configuration transformers

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

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

# transformers

  • Type: ((config: RslibConfig, context: RslibConfigTransformerContext) => RslibConfig)[]
  • Default: []
transformer(config: RslibConfig, context: RslibConfigTransformerContext) => RslibConfig
rslib.dev.ts
import { defineDevConfig, type RslibConfig, type RslibConfigTransformer } from "@workleap/rslib-configs";

const forceNamedChunkIdsTransformer: RslibConfigTransformer = (config: RslibConfig) => {
    config.tools = config.tools ?? {};
    config.tools.rspack = config.tools.rspack ?? {};

    config.tools.rspack.optimization = {
        ...(config.tools.rspack.optimization ?? {}),
        chunkIds: "named"
    };

    return config;
};

export default defineDevConfig({
    transformers: [forceNamedChunkIdsTransformer]
});

# 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.ts
import type { RslibConfig, RslibConfigTransformer } from "@workleap/rslib-configs";

export const transformer: RslibConfigTransformer = (config: RslibConfig) => {
    if (context.environment === "dev") {
        config.tools = config.tools ?? {};
        config.tools.rspack = config.tools.rspack ?? {};

        config.tools.rspack.optimization = {
            ...(config.tools.rspack.optimization ?? {}),
            chunkIds: "named"
        };
    }

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

# Setup nodemon

Nodemon is a utility that will monitor for any changes in the rslib.dev.ts file and restart Rslib watch process whenever a change occurs.

First, add a nodemon.json file at the root of the project:

library-project
β”œβ”€β”€ src
β”œβ”€β”€β”€β”€ ...
β”œβ”€β”€ package.json
β”œβ”€β”€ rslib.dev.ts
β”œβ”€β”€ nodemon.json

Then, open the nodemon.json file and copy/paste the following content:

nodemon.json
{
    "watch": ["rslib.dev.ts"],
    "exec": "rslib build -w -c ./rslib.dev.ts"
}

Finally, add a CLI script at the next step of this guide.

# Add a CLI script

To initiate the watch process, add the following script to the project package.json file:

package.json
{
    "dev": "nodemon"
}

# CSS modules typings

When CSS Modules are imported from TypeScript code, TypeScript may prompt that the module is missing a type definition:

TS2307: Cannot find module './index.module.css' or its corresponding type declarations.

To fix this, add a type declaration file for the CSS Modules, by creating a src/env.d.ts file, and adding the corresponding type declaration.

env.d.ts
/// <reference types="@rsbuild/core/types" />

# Monorepo

If the solution is a monorepo, ensure that projects referencing the packages that include CSS Modules, also include the necessary type definitions

For example, given the following structure:

workspace
β”œβ”€β”€ app
β”œβ”€β”€β”€β”€ tsconfig.ts
β”œβ”€β”€ packages
β”œβ”€β”€β”€β”€ components
β”œβ”€β”€β”€β”€β”€β”€ src
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€ Button.tsx
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€ Button.module.css
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€ env.d.ts
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€ tsconfig.ts
β”œβ”€β”€ package.json

Copy the CSS Modules typings into the app web application own env.d.ts file, or include the components package's typings into the apps web application tsconfig.ts configuration file:

app/tsconfig.ts
{
    "extends": "@workleap/typescript-configs/web-application.json",
    "include": [
        ".",
        "../**/src/env.d.ts"
    ],
    "exclude": ["public", "dist", "node_modules"]
}

# Try it 🚀

To test the new Rslib configuration, open a terminal at the root of the project and execute the CLI script added earlier. The library project should should be compiled without outputting any error in the terminal and watch process should start.