Skip to content

Commit

Permalink
Deletes empty output client-side JavaScript bundles.
Browse files Browse the repository at this point in the history
This updates the Rollup config to avoid generating empty bundles. This used to be a warning, but now the bundles are not emitted at all. The build process will properly skip injecting a pointless `<script>` tag, so everything works as expected.
  • Loading branch information
dgp1130 committed Jul 24, 2023
1 parent a1962af commit 62f2eab
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 4 deletions.
47 changes: 47 additions & 0 deletions examples/empty_script/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
load("//:index.bzl", "prerender_pages", "web_resources_devserver")
load("//tools/jasmine:defs.bzl", "jasmine_web_test_suite")
load("//tools/typescript:defs.bzl", "ts_project")

prerender_pages(
name = "site",
entry_point = "./site.js",
prerender = ":prerender",
scripts = ":scripts",
)

ts_project(
name = "prerender",
srcs = ["site.tsx"],
deps = [
"//:node_modules/@rules_prerender/preact",
"//:node_modules/preact",
],
)

ts_project(
name = "scripts",
srcs = ["empty_script.mts"],
)

web_resources_devserver(
name = "devserver",
resources = ":site",
)

ts_project(
name = "test_lib",
srcs = ["test.mts"],
testonly = True,
deps = [
"//common/testing:devserver",
"//common/testing:webdriver",
"//:node_modules/@types/jasmine",
],
)

jasmine_web_test_suite(
name = "test",
browsers = ["//tools/browsers:chromium-local"],
data = [":devserver"],
deps = [":test_lib"],
)
1 change: 1 addition & 0 deletions examples/empty_script/empty_script.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// Empty script, should not be injected into the page.
17 changes: 17 additions & 0 deletions examples/empty_script/site.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { PrerenderResource, renderToHtml, includeScript } from '@rules_prerender/preact';

export default function*(): Generator<PrerenderResource, void, void> {
yield PrerenderResource.fromHtml('/index.html', renderToHtml(
<html>
<head>
<meta charSet="utf8" />
<title>Empty script</title>
</head>
<body>
<h2>Empty script</h2>

{includeScript('./empty_script.mjs', import.meta)}
</body>
</html>
));
}
20 changes: 20 additions & 0 deletions examples/empty_script/test.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useDevserver } from '../../common/testing/devserver.mjs';
import { useWebDriver } from '../../common/testing/webdriver.mjs';

describe('empty_scripts', () => {
const devserver = useDevserver('examples/empty_script/devserver.sh');
const wd = useWebDriver(devserver);

describe('index page', () => {
it('renders without a script', async () => {
const browser = wd.get();
await browser.url('/');

expect(await browser.$('h2').getText()).toBe('Empty script');

// Expect only the live reload script.
const scripts = await browser.$$('script');
expect(scripts.length).toBe(1);
});
});
});
26 changes: 22 additions & 4 deletions packages/rules_prerender/rollup.config.mts
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
import { nodeResolve } from '@rollup/plugin-node-resolve';
import { RollupOptions } from 'rollup';
import { Plugin, RollupOptions } from 'rollup';

/**
* Deletes any empty output bundles before they are written to disk. This
* prevents the build process from injecting an empty script onto the page.
*/
const deleteEmptyBundles: Plugin = {
name: 'delete-empty-bundles',

// Called right before writing output bundles to disk.
generateBundle(_options, bundle): void {
for (const [ key, value ] of Object.entries(bundle)) {
if (value.type === 'chunk' && value.isEntry && value.code.trim() === '') {
delete bundle[key];
}
}
},
};

export default {
plugins: [
// Needed to support absolute imports.
nodeResolve({ browser: true }),
deleteEmptyBundles,
],

// Fail the build on any warning.
onwarn(warning) {
if (warning.code === 'EMPTY_BUNDLE') {
// Give a better suggestion when no JavaScript is generated.
console.warn('Generated an empty JavaScript bundle, do you have'
+ ' any JavaScript?\n\n' + warning.message);
// Ignore empty output errors because the `deleteEmptyBundles`
// plugin will delete them after the fact. This is not considered a
// problem and does not need to warn or error.
return;
}

Expand Down

0 comments on commit 62f2eab

Please sign in to comment.