clientshellclientshell
Bundlers

Webpack Plugin

Using Clientshell with Webpack.

Installation

pnpm add -D @clientshell/webpack @clientshell/cli

The Webpack Flow

Because Webpack config (webpack.config.cjs) usually runs in pure Node.js (CommonJS), we shouldn't attempt to require the TypeScript (.ts) schema file directly inside the Webpack config.

Instead, we use the clientshell CLI to compile the schema into a JSON manifest first, before Webpack runs.

1. Update Scripts

Update your package.json to generate the JSON file using the CLI (--import tsx ensures Node.js can interpret .ts correctly).

{
  "scripts": {
    "manifest": "node --import tsx ./node_modules/@clientshell/cli/bin/clientshell.js manifest --schema src/env.schema.ts --output clientshell.manifest.json",
    "build": "pnpm manifest && webpack --config webpack.config.cjs",
    "dev": "pnpm manifest && webpack serve --config webpack.config.cjs"
  }
}

2. Setup Webpack

Point the Webpack plugin directly to your pre-generated manifest JSON file!

// webpack.config.cjs
const { ClientshellWebpackPlugin } = require("@clientshell/webpack");

module.exports = {
  // ... other config ...
  plugins: [
    new ClientshellWebpackPlugin({
      manifestPath: "./clientshell.manifest.json",
      
      // Values to return in Development stubs
      devValues: {
        API_URL: "http://localhost:3000",
      },
    }),
  ],
};

What it does

  • Build (mode: "production"): Copies clientshell.manifest.json into your Webpack output directory (e.g., dist/).
  • Dev (mode: "development"): Writes a stub env-config.js to the output directory using the defaults in your manifest, overlaid with your provided devValues.

Docker Deployment

When deploying a Webpack app, ensure your Dockerfile runs the manifest step before or as part of the build.

# 1. Build Layer
FROM node:20-alpine AS builder
WORKDIR /app
COPY . .

# Ensure pnpm is installed and run pnpm build 
# (which should be "pnpm manifest && webpack")
RUN npm install -g pnpm && pnpm install && pnpm build

# 2. Production Layer
FROM clientshell
COPY --from=builder /app/dist /app/dist

The Go injector will look for /app/dist/clientshell.manifest.json inside the container at startup.

On this page