Skip to content

Commit c87d732

Browse files
Elliott Marquezcopybara-github
authored andcommitted
build(catalog): implement esbuild config
PiperOrigin-RevId: 534634293
1 parent 494a3a0 commit c87d732

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed

catalog/esbuild.config.mjs

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/**
2+
* @license
3+
* Copyright 2023 Google LLC
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
import gzipPlugin from '@luncheon/esbuild-plugin-gzip';
8+
import esbuild from 'esbuild';
9+
import {copyFileSync} from 'fs';
10+
import {createRequire} from 'node:module';
11+
import {join} from 'path';
12+
import tinyGlob from 'tiny-glob';
13+
14+
// dev mode build
15+
const DEV = process.env.NODE_ENV === 'DEV';
16+
// Output folder for TS files
17+
const jsFolder = DEV ? 'lib' : 'build';
18+
19+
// can use glob syntax. this will create a bundle for those specific files.
20+
// you want to add SSR'd files here so that you can hydrate them later with
21+
// <lit-island import="js/components/element-definition.js"></lit-island>
22+
const tsEntrypoints = [
23+
// entrypoints for hydrating SSR'd components
24+
'./src/hydration-entrypoints/*.ts',
25+
// also include a bundle for each individual page
26+
'./src/pages/*.ts',
27+
// SSR stuff
28+
'./src/ssr-utils/lit-hydrate-support.ts',
29+
'./src/ssr-utils/is-land.ts',
30+
];
31+
const filesPromises = tsEntrypoints.map(async (entry) => tinyGlob(entry));
32+
const entryPoints = (await Promise.all(filesPromises)).flat();
33+
34+
// Shared esbuild config values
35+
let config = {
36+
bundle: true,
37+
outdir: jsFolder,
38+
minify: false,
39+
format: 'esm',
40+
treeShaking: true,
41+
write: true,
42+
sourcemap: true,
43+
splitting: true,
44+
};
45+
46+
let componentsBuild = Promise.resolve();
47+
48+
// development build
49+
if (DEV) {
50+
componentsBuild = esbuild
51+
.build({
52+
...config,
53+
entryPoints,
54+
})
55+
.catch(() => process.exit(1));
56+
57+
// production build
58+
} else {
59+
// config must be same for SSR and client builds to prevent hydration template
60+
// mismatches because we minify the templates in prod
61+
config = {
62+
bundle: true,
63+
outdir: jsFolder,
64+
minify: true,
65+
format: 'esm',
66+
treeShaking: true,
67+
legalComments: 'external',
68+
plugins: [
69+
// TODO: this plugin currently breaks certain css props for SVGs
70+
// (circularprogress) minifyHTMLLiteralsPlugin({
71+
// shouldMinify: (template) => {
72+
// const tag = template.tag && template.tag.toLowerCase();
73+
// return (
74+
// !!tag &&
75+
// (tag.includes('html') || tag.includes('svg')) &&
76+
// // tag name interpolations break
77+
// tag !== 'statichtml'
78+
// );
79+
// },
80+
// }),
81+
gzipPlugin({
82+
gzip: true,
83+
}),
84+
],
85+
// Needs to be off per the gzipPlugin docs
86+
write: false,
87+
splitting: true,
88+
};
89+
90+
componentsBuild = esbuild
91+
.build({
92+
...config,
93+
entryPoints,
94+
})
95+
.catch(() => process.exit(1));
96+
}
97+
98+
// seperate build so that the SSR bundle doesn't affect bundling for the
99+
// frontend
100+
const ssrBuild = esbuild
101+
.build({
102+
...config,
103+
format: 'iife',
104+
splitting: false,
105+
conditions: ['node'],
106+
entryPoints: ['src/ssr.ts'],
107+
})
108+
.catch(() => process.exit(1));
109+
110+
// Glob of files that will be inlined on the page in <script> tags
111+
const tsInlineEntrypoints = [
112+
'./src/ssr-utils/dsd-polyfill.ts',
113+
// Anything in this directory will be inlined
114+
'./src/inline/*.ts',
115+
];
116+
const inlineFilesPromises =
117+
tsInlineEntrypoints.map(async (entry) => tinyGlob(entry));
118+
const inlineEntryPoints = (await Promise.all(inlineFilesPromises)).flat();
119+
120+
// this code is inlined into the HTML because it is performance-sensitive
121+
const inlineBuild = esbuild
122+
.build({
123+
...config,
124+
format: 'iife',
125+
splitting: false,
126+
entryPoints: inlineEntryPoints,
127+
})
128+
.catch(() => process.exit(1));
129+
130+
await Promise.all([componentsBuild, ssrBuild, inlineBuild]);
131+
132+
// Copy the playground-elements worker to the build folder
133+
const require = createRequire(import.meta.url);
134+
copyFileSync(
135+
require.resolve('playground-elements/playground-typescript-worker.js'),
136+
join(jsFolder, 'playground-typescript-worker.js'));
137+
138+
process.exit(0);

0 commit comments

Comments
 (0)