Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: always write manifest to disk #4074

Merged
merged 6 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
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
44 changes: 44 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,50 @@ 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).

If your HTML template is provided by the server, you need to inject the web output files into the HTML template. Output manifests can be easily obtained using the [output.manifest](/config/output/manifest) configuration. You can refer to the following example:
9aoy marked this conversation as resolved.
Show resolved Hide resolved

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

```ts title=server.ts
function renderHtmlPage(): string {
const { entries } = JSON.parse(
fs.readFileSync('./dist/manifest.json', 'utf-8'),
9aoy marked this conversation as resolved.
Show resolved Hide resolved
);

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

const scriptTags = js
.map((file) => `<script src="${file}" defer></script>`)
9aoy marked this conversation as resolved.
Show resolved Hide resolved
.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)
44 changes: 44 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,50 @@ startDevServer(process.cwd());

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

## 获取资源清单

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

如果你的 HTML 模版是由服务器端提供,此时需要将 web 端的 js 和 css 产物资源注入到 HTML 模版中。使用 [output.manifest](/config/output/manifest) 配置可以轻松获取资源清单。可参考以下示例:
9aoy marked this conversation as resolved.
Show resolved Hide resolved

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

```ts title=server.ts
function renderHtmlPage(): string {
const { entries } = JSON.parse(
fs.readFileSync('./dist/manifest.json', 'utf-8'),
);

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)
Loading