Closed nathanjhood closed 3 weeks ago
found in the esbuild docs about the CSS loader:
If the generated output names are not straightforward (for example if you have added [hash] to the [entry names](https://esbuild.github.io/api/#entry-names) setting and the output file names have content hashes) then you will likely want to look up the generated output names in the metafile. To do this, first find the JS file by looking for the output with the matching entryPoint property. This file goes in the \<script> tag. The associated CSS file can then be found using the cssBundle property. This file goes in the \<link> tag.
draft, in testing on esbuild-scripts:
(() => {
return {
name: 'html',
setup(build) {
const escapeStringRegexp = (str: string) => {
str
.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')
.replace(/-/g, '\\x2d');
}
// Run HTML through a series of user-specified string replacements.
build.onLoad({ filter: /\.html$/ }, async (args) => {
let html = await fs.promises.readFile(args.path, 'utf8');
Object.keys(proc.env).forEach((key) => {
const value = proc.env[key];
if(value) html = html.replace(
new RegExp('%' + escapeStringRegexp(key) + '%', 'g'),
value
);
});
return {
contents: html,
loader: 'file',
};
});
},
};
})()
It's done:
const buildHTML = (options: { appHtml: string; appBuild: string }) => {
let html = fs.readFileSync(options.appHtml, { encoding: 'utf8' });
Object.keys(proc.env).forEach((key) => {
const escapeStringRegexp = (str: string) => {
return str
.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')
.replace(/-/g, '\\x2d');
};
const value = proc.env[key];
const htmlsrc = new RegExp('%' + escapeStringRegexp(key) + '%', 'g');
if (value) html = html.replaceAll(htmlsrc, value);
});
return fs.writeFileSync(path.resolve(options.appBuild, 'index.html'), html);
};
Now, I need to update this project to consume esbuild-scripts
instead of carrying it's own scripts.
Solved.
I need an
InterpolateHtmlPlugin
for esbuild...The is the Webpack plugin definition, written in CommonJS, that ships with
react-scripts
, which handles the var replacements (%PUBLIC_URL%
) inside thepublic/index.html
file of a standard React/Webpack project:I need to adapt this to an esbuild plugin, written in Typescript to be transpiled to JS for distro.
Sure enough we can do a slow
fs.read
/fs.write
of some sort, and even mark it as async. I'm wondering - influenced by an idea from expo - if perhaps the HTML file could be parsed as JSX, and then the transformation can be done in some sort of JS function on the interpreted JSX version of the HTML file...The parsed JSX version of the HTML would look something like:
Another option using the above JSX idea, is to just import the assets and pass them to the JSX, and let esbuild's loaders config work it out:
In either case, it would be useful opportunity to inject chunk hash names if necessary. Thinking about doing so makes me wonder if the JSX is probably the better idea, rather than parsing the HTML file.
Well this should be fun.