Skip to content

Commit 85d3cf7

Browse files
committed
Adds shared chunks example.
Refs #26. This verifies that common code shared between multiple entry points is actually split into a common module and imported by all the referenced entry points at runtime. This is good for caching, since a user who starts on one page and navigates to another will already have any common code downloaded and get cache hits for it.
1 parent 0d3c4b2 commit 85d3cf7

7 files changed

Lines changed: 140 additions & 0 deletions

File tree

examples/shared_chunks/BUILD.bazel

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
load("//:index.bzl", "prerender_pages", "web_resources_devserver")
2+
load("//tools/jasmine:defs.bzl", "jasmine_node_test")
3+
load("//tools/typescript:defs.bzl", "ts_project")
4+
5+
prerender_pages(
6+
name = "site",
7+
src = "site.ts",
8+
scripts = [":hello", ":goodbye"],
9+
tsconfig = "//:tsconfig",
10+
source_map = True,
11+
lib_deps = ["//:node_modules/rules_prerender"],
12+
)
13+
14+
ts_project(
15+
name = "hello",
16+
srcs = ["hello.ts"],
17+
tsconfig = "//:tsconfig_client",
18+
deps = [":shared"],
19+
)
20+
21+
ts_project(
22+
name = "goodbye",
23+
srcs = ["goodbye.ts"],
24+
tsconfig = "//:tsconfig_client",
25+
deps = [":shared"],
26+
)
27+
28+
ts_project(
29+
name = "shared",
30+
srcs = ["shared.ts"],
31+
tsconfig = "//:tsconfig_client",
32+
)
33+
34+
web_resources_devserver(
35+
name = "devserver",
36+
resources = ":site",
37+
)
38+
39+
ts_project(
40+
name = "test_lib",
41+
srcs = ["test.ts"],
42+
testonly = True,
43+
data = [":site"],
44+
deps = [
45+
"//:node_modules/@types/jasmine",
46+
"//:node_modules/@types/node",
47+
],
48+
)
49+
50+
jasmine_node_test(
51+
name = "test",
52+
deps = [":test_lib"],
53+
)

examples/shared_chunks/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Shared Chunks
2+
3+
An example which bundles multiple entry points using a common dependency and
4+
verifies that the dependency is not duplicated.

examples/shared_chunks/goodbye.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { name } from './shared';
2+
3+
console.log(`Goodbye, ${name}!`);

examples/shared_chunks/hello.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { name } from './shared';
2+
3+
console.log(`Hello, ${name}!`);

examples/shared_chunks/shared.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const name = 'World';

examples/shared_chunks/site.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { includeScript, PrerenderResource } from 'rules_prerender';
2+
3+
export default function*(): Generator<PrerenderResource, void, void> {
4+
yield PrerenderResource.of('/index.html', `
5+
<!DOCTYPE html>
6+
<html>
7+
<head>
8+
<title>Shared Chunks</title>
9+
<meta charset="utf8">
10+
</head>
11+
<body>
12+
<ul>
13+
<li><a href="/hello.html">Hello</a></li>
14+
<li><a href="/goodbye.html">Goodbye</a></li>
15+
</ul>
16+
</body>
17+
</html>
18+
`.trim());
19+
20+
yield PrerenderResource.of('/hello.html', `
21+
<!DOCTYPE html>
22+
<html>
23+
<head>
24+
<title>Shared Chunks</title>
25+
<meta charset="utf8">
26+
</head>
27+
<body>
28+
<h2>Check console</h2>
29+
${includeScript('examples/shared_chunks/hello')}
30+
</body>
31+
</html>
32+
`.trim());
33+
34+
yield PrerenderResource.of('/goodbye.html', `
35+
<!DOCTYPE html>
36+
<html>
37+
<head>
38+
<title>Shared Chunks</title>
39+
<meta charset="utf8">
40+
</head>
41+
<body>
42+
<h2>Check console</h2>
43+
${includeScript('examples/shared_chunks/goodbye')}
44+
</body>
45+
</html>
46+
`.trim());
47+
}

examples/shared_chunks/test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { promises as fs } from 'fs';
2+
3+
const site = 'examples/shared_chunks/site';
4+
5+
describe('Shared Chunks', () => {
6+
it('generates `/hello.js` without inlining `shared.js`', async () => {
7+
const hello = await fs.readFile(`${site}/hello.js`, 'utf8');
8+
expect(hello).not.toContain('World');
9+
});
10+
11+
it('generates `/goodbye.js` without inlining `shared.js`', async () => {
12+
const goodbye = await fs.readFile(`${site}/goodbye.js`, 'utf8');
13+
expect(goodbye).not.toContain('World');
14+
});
15+
16+
it('generates a shared chunk containing `shared.js`', async () => {
17+
// Should generate exactly three JavaScript files: `hello.js`,
18+
// `goodbye.js`, and one other shared chunk with a generated name.
19+
const entries = await fs.readdir(site);
20+
const sharedChunks = entries
21+
.filter((entry) => entry.endsWith('.js'))
22+
.filter((entry) => entry !== 'hello.js' && entry !== 'goodbye.js');
23+
expect(sharedChunks.length).toBe(1);
24+
const [ shared ] = sharedChunks;
25+
26+
const sharedJs = await fs.readFile(`${site}/${shared}`, 'utf8');
27+
expect(sharedJs).toContain('World');
28+
});
29+
});

0 commit comments

Comments
 (0)