Skip to content

Commit

Permalink
feat: always write manifest to disk (#4074)
Browse files Browse the repository at this point in the history
Co-authored-by: neverland <[email protected]>
  • Loading branch information
9aoy and chenjiahan authored Nov 27, 2024
1 parent 544cfa6 commit 377a94c
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 2 deletions.
35 changes: 34 additions & 1 deletion e2e/cases/output/manifest/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import { build } from '@e2e/helper';
import { build, dev } from '@e2e/helper';
import { expect, test } from '@playwright/test';

const fixtures = __dirname;
Expand Down Expand Up @@ -108,3 +108,36 @@ test('output.manifest when target is node', async () => {
},
});
});

test('output.manifest should always write to disk when dev', async ({
page,
}) => {
const rsbuild = await dev({
cwd: fixtures,
page,
rsbuildConfig: {
output: {
distPath: {
root: 'dist-dev',
},
manifest: true,
legalComments: 'none',
filenameHash: false,
},
performance: {
chunkSplit: {
strategy: 'all-in-one',
},
},
},
});

const files = await rsbuild.unwrapOutputJSON();

const manifestContent =
files[Object.keys(files).find((file) => file.endsWith('manifest.json'))!];

expect(manifestContent).toBeDefined();

await rsbuild.close();
});
4 changes: 3 additions & 1 deletion packages/core/src/plugins/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,10 @@ export const pluginManifest = (): RsbuildPlugin => ({
name: 'rsbuild:manifest',

setup(api) {
api.modifyBundlerChain(async (chain, { CHAIN_ID, environment }) => {
api.modifyBundlerChain(async (chain, { CHAIN_ID, environment, isDev }) => {
const {
output: { manifest },
dev: { writeToDisk },
} = environment.config;

if (manifest === false) {
Expand All @@ -163,6 +164,7 @@ export const pluginManifest = (): RsbuildPlugin => ({
chain.plugin(CHAIN_ID.PLUGIN.MANIFEST).use(RspackManifestPlugin, [
{
fileName,
writeToFileEmit: isDev && writeToDisk !== true,
generate: generateManifest(htmlPaths),
},
]);
Expand Down
43 changes: 43 additions & 0 deletions website/docs/en/guide/advanced/ssr.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,49 @@ If you need to preview the online effect of SSR rendering, you also need to modi

Now, you can run the `npm run dev` command to start the dev server with SSR rendering function, and visit `http://localhost:3000/` to see that the SSR content has been rendered to the HTML page.

## Get Manifest

By default, scripts and links associated with the current page are automatically inserted into the HTML template. At this time, the compiled HTML template content can be obtained through [getTransformedHtml](/guide/advanced/environments#environment-api).

When you need to dynamically generate HTML on the server side, you'll need to inject the URLs of JavaScript and CSS assets into the HTML. By configuring [output.manifest](/config/output/manifest), you can easily obtain the manifest information of these assets. Here's an example:

```ts title=rsbuild.config.ts
export default {
output: {
manifest: true,
},
};
```

```ts title=server.ts
async function renderHtmlPage(): Promise<string> {
const manifest = await fs.promises.readFile('./dist/manifest.json', 'utf-8');
const { entries } = JSON.parse(manifest);

const { js, css } = entries['index'].initial;

const scriptTags = js
.map((url) => `<script src="${url}" defer></script>`)
.join('\n');
const styleTags = css
.map((file) => `<link rel="stylesheet" href="${file}">`)
.join('\n');

return `
<!DOCTYPE html>
<html>
<head>
${scriptTags}
${styleTags}
</head>
<body>
<div id="root"></div>
</body>
</html>`;
}
```

## Examples

- [SSR + Express Example](https://github.com/rspack-contrib/rspack-examples/blob/main/rsbuild/ssr-express)
- [SSR + Express + Manifest Example](https://github.com/rspack-contrib/rspack-examples/blob/main/rsbuild/ssr-express-with-manifest)
43 changes: 43 additions & 0 deletions website/docs/zh/guide/advanced/ssr.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,49 @@ startDevServer(process.cwd());

现在,执行 `npm run dev` 命令即可启动带有 SSR 渲染功能的开发服务器,访问 `http://localhost:3000/` 即可看到 SSR 内容已经渲染到了 HTML 页面上。

## 获取资源清单

默认情况下,和当前页面关联的 scripts 和 links 会自动插入到 HTML 模版中,此时通过 [getTransformedHtml](/guide/advanced/environments#environment-api) 即可获取编译后的 HTML 模版内容。

当需要在服务器端动态生成 HTML 时,你需要将 JavaScript 和 CSS 资源的 URL 注入到 HTML 中。通过配置 [output.manifest](/config/output/manifest),你可以方便地获取这些资源的清单信息。示例如下:

```ts title=rsbuild.config.ts
export default {
output: {
manifest: true,
},
};
```

```ts title=server.ts
async function renderHtmlPage(): Promise<string> {
const manifest = await fs.promises.readFile('./dist/manifest.json', 'utf-8');

const { entries } = JSON.parse(manifest);
const { js, css } = entries['index'].initial;

const scriptTags = js
.map((file) => `<script src="${file}" defer></script>`)
.join('\n');
const styleTags = css
.map((file) => `<link rel="stylesheet" href="${file}">`)
.join('\n');

return `
<!DOCTYPE html>
<html>
<head>
${scriptTags}
${styleTags}
</head>
<body>
<div id="root"></div>
</body>
</html>`;
}
```

## 示例项目

- [SSR + Express Example](https://github.com/rspack-contrib/rspack-examples/blob/main/rsbuild/ssr-express)
- [SSR + Express + Manifest Example](https://github.com/rspack-contrib/rspack-examples/blob/main/rsbuild/ssr-express-with-manifest)

0 comments on commit 377a94c

Please sign in to comment.