npm package: @sohu-bpd/unplugin-cdn-upload
Description: Upload built assets to a CDN and update asset URLs.
Latest version: 0.1.2

# @sohu-bpd/unplugin-cdn-upload

Upload built assets to a private CDN storage service after the host build output is written.

## Features

- supports Vite, Rollup, webpack, Rspack, and Rolldown through host-specific adapters
- uploads files from the final build output directory after the corresponding host hook runs
- filters files with `include` / `exclude` rules
- excludes `**/*.html` by default
- signs `PUT Object` requests with the SCS HMAC-SHA1 flow
- keeps generated asset references unchanged

## Host Support

The package root exports the unplugin factory object. In app config, prefer the host-specific subpaths:

- `@sohu-bpd/unplugin-cdn-upload/vite`
- `@sohu-bpd/unplugin-cdn-upload/rollup`
- `@sohu-bpd/unplugin-cdn-upload/webpack`
- `@sohu-bpd/unplugin-cdn-upload/rspack`
- `@sohu-bpd/unplugin-cdn-upload/rolldown`

Rsbuild should use the `/rspack` entry through `tools.rspack`; there is no separate `./rsbuild` export.

## Usage

### Vite

```ts
import { defineConfig } from "vite";
import cdnUpload from "@sohu-bpd/unplugin-cdn-upload/vite";

export default defineConfig({
  plugins: [
    cdnUpload({
      bucket: "frontend-assets",
      prefix: "my-app/2026-03-30",
      host: process.env.SCS_HOST,
      concurrency: 3,
      include: ["assets/**"],
      exclude: ["**/*.html"]
    })
  ]
});
```

### Rollup

```ts
import cdnUpload from "@sohu-bpd/unplugin-cdn-upload/rollup";

export default {
  plugins: [
    cdnUpload({
      bucket: "frontend-assets",
      prefix: "my-app/2026-03-30"
    })
  ]
};
```

### Other Hosts

- Use `@sohu-bpd/unplugin-cdn-upload/webpack` in webpack configs.
- Use `@sohu-bpd/unplugin-cdn-upload/rspack` in Rspack configs and in Rsbuild via `tools.rspack.plugins`.
- Use `@sohu-bpd/unplugin-cdn-upload/rolldown` in Rolldown configs.

### Rsbuild

```ts
import cdnUpload from "@sohu-bpd/unplugin-cdn-upload/rspack";

export default {
  tools: {
    rspack: {
      plugins: [
        cdnUpload({
          bucket: "frontend-assets",
          prefix: "my-app/2026-03-30"
        })
      ]
    }
  }
};
```

## Options

- `bucket`: required bucket name
- `prefix`: optional object key prefix; leading and trailing `/` are removed
- `host`: optional SCS host or origin such as `bjcnc.scs.sohucs.com` or `http://bjcnc.scs.sohucs.com`
- `accessKey`: optional access key; falls back to `SCS_ACCESS_KEY`
- `secretKey`: optional secret key; falls back to `SCS_SECRET_KEY`
- `include`: optional glob rule or glob rule list; defaults to `["**/*"]`
- `exclude`: optional glob rule or glob rule list; defaults to `["**/*.html"]`
- `env`: optional custom env key mapping for `accessKey`, `secretKey`, and `host`
- `computeMd5`: whether to send `Content-MD5`; defaults to `true`
- `concurrency`: optional maximum number of concurrent uploads; defaults to `3`

## Behavior

Build output uploads are wired through the host adapters:

- Vite uploads after `closeBundle`
- Rollup and Rolldown upload after `writeBundle`
- webpack and Rspack upload after `afterEmit`

After the relevant host finishes writing output files, the plugin scans the resolved output directory, filters files with `include` and `exclude`, and uploads matching files to:

```text
<prefix>/<relative-output-path>
```

The plugin does not rewrite URLs inside generated files.
During upload it prints colored, structured console logs for `START`, one `UPLOADED` line per completed upload, `SUCCESS`, and `ERROR`. Uploads run with a bounded concurrency of `3` by default unless overridden by `concurrency`.

## Environment Variables

By default, the plugin reads these environment variables when the corresponding option is not provided:

- `SCS_ACCESS_KEY`
- `SCS_SECRET_KEY`
- `SCS_HOST`