Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,4 @@ test/fixture/functions
# Generated types
*.d.ts
!runtime-meta.d.ts
test/unit/.tmp-server-assets-perf/
20 changes: 20 additions & 0 deletions docs/1.guide/8.assets.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,23 @@ export default defineEventHandler(async (event) => {
return html
})
```

### Large catalogs (`embed`)

By default each file becomes a lazy Rollup `raw:` module (`embed: true`). For directories with many small files you can opt in:

| `embed` | Behavior |
| --- | --- |
| `true` (default) | One `raw:` chunk per file (unchanged) |
| `"inline"` | Single virtual module (fast builds; larger server entry) |
| `false` | Copy to `server/assets/<baseName>` and read from disk at runtime (Node/Bun/Deno) |

```ts
export default defineNitroConfig({
serverAssets: [{
baseName: 'i18n',
dir: './i18n-data',
embed: 'inline', // or false
}]
})
```
37 changes: 33 additions & 4 deletions src/core/utils/fs-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ import prettyBytes from "pretty-bytes";
import { isTest } from "std-env";
import { runParallel } from "./parallel";

/**
* Build a printable size tree for the server output directory.
*
* Files under `chunks/raw/` (one Rollup module per `serverAssets` file) are
* summarized with `stat` only. Gzipping each of them dominated build wall time
* for large catalogs (nitrojs/nitro#1833).
*/
export async function generateFSTree(
dir: string,
options: { compressedSizes?: boolean } = {}
Expand All @@ -15,7 +22,10 @@ export async function generateFSTree(
return;
}

const files = await globby("**/*.*", { cwd: dir, ignore: ["*.map"] });
const files = await globby("**/*.*", {
cwd: dir,
ignore: ["*.map", "chunks/raw/**"],
});

const items: { file: string; path: string; size: number; gzip: number }[] =
[];
Expand Down Expand Up @@ -43,9 +53,9 @@ export async function generateFSTree(
let treeText = "";

for (const [index, item] of items.entries()) {
let dir = dirname(item.file);
if (dir === ".") {
dir = "";
let _dir = dirname(item.file);
if (_dir === ".") {
_dir = "";
}
const rpath = relative(process.cwd(), item.path);
const treeChar = index === items.length - 1 ? "└─" : "β”œβ”€";
Expand All @@ -69,6 +79,25 @@ export async function generateFSTree(
totalGzip += item.gzip;
}

const rawFiles = await globby("chunks/raw/**/*.*", {
cwd: dir,
ignore: ["*.map"],
});
if (rawFiles.length > 0) {
let rawSize = 0;
await runParallel(
new Set(rawFiles),
async (file) => {
rawSize += (await fsp.stat(resolve(dir, file))).size;
},
{ concurrency: 25 }
);
totalSize += rawSize;
treeText += colors.gray(
` β”œβ”€ chunks/raw/* (${rawFiles.length} files, ${prettyBytes(rawSize)}, gzip skipped)\n`
);
}

treeText += `${colors.cyan("Ξ£ Total size:")} ${prettyBytes(
totalSize + totalNodeModulesSize
)}`;
Expand Down
3 changes: 3 additions & 0 deletions src/rollup/plugins/raw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ function isBinary(id: string) {
return true;
}

/** Shared with server-assets inline embedding. */
export { isBinary };

function getHelpers() {
const js = String.raw;
return js`
Expand Down
Loading