You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// config/esbuild.config.tsexportfunctionconfigFactory(/** ... */){return{// ...entryNames: isEnvProduction
? "static/[ext]/[name].[hash]"
: isEnvDevelopment&&"static/[ext]/bundle",// There are also additional JS chunk files if you use code splitting.chunkNames: isEnvProduction
? "static/[ext]/[name].[hash].chunk"
: isEnvDevelopment&&"static/[ext]/[name].chunk",assetNames: "static/media/[name].[hash][ext]",// ...}}
This codeblock works beautifully, directly from the react-scripts webpack config into the esbuild one.
Unfortunately though, esbuild doesn't have the standard means of replacing parsed HTML with expanded variables...
... fortunately, I made my own. Adapted from the webpack plugin inside of react-scripts. And it works great!
The below variables containing %PUBLIC_URL% - and any other from the consumer project's .env files - are now being correctly interpolated:
<!-- public/index.html --><!DOCTYPE html><htmllang="en"><head><!-- ... --><linkrel="icon" href="%PUBLIC_URL%/favicon.ico" />
<linkrel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<linkrel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!-- Notice the use of %PUBLIC_URL% in the tags above. It will be replaced with the URL of the `public` folder during the build. Only files inside the `public` folder can be referenced from the HTML. Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --><title>React App</title></head><!-- ... --></html>
The trick next is to figure out how to get the hashes from build output files (and/or metafile) and inject those as well...
Requirement:
The un-processed HTML should look like the below, with the build output's index.html having the appropriate variables - [name] and [hash] and so forth - replaced with those found in the build config (from the 1st codeblock):
<!-- public/index.html --><!DOCTYPE html><htmllang="en"><head><!-- ... --><linkrel="icon" href="%PUBLIC_URL%/favicon.ico" />
<linkrel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<linkrel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!-- Notice the use of %PUBLIC_URL% in the tags above. It will be replaced with the URL of the `public` folder during the build. Only files inside the `public` folder can be referenced from the HTML. Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --><linkrel="stylesheet" href="%PUBLIC_URL%/static/css/[name].[hash]" />
<title>React App</title><scripttype="module" href="%PUBLIC_URL%/static/js/[name].[hash]" />
</head><!-- ... --></html>
Caveat:
Currently, I'm doing the HTML file build in a separate step, between copyPublicFolder (which runs first), and esbuild itself.
In order to get the variables that we need to inject into the HTML, we obviously need to run the HTML step after, not before, esbuild finishes each build run.
Thanks to the promise-chaining, there is some scope for placing that function call in exactly the place it needs to happen.
IMPORTANT:
It's worth noting that some implementations out there don't have any stylesheet-importing HTML tag in the template HTML file; it appears that the stylesheet-import gets injected into the HTML on every build run.
Probably a security thing, of course.
Additionally, we must never read and write to the same location at the same time; in fact, I'm going to scrap the "async CLI" idea because it's just bad. With that in mind, a lockfile (just an empty textfile placed at the root of dist) could be useful during build, as a kind of atomic flag; if a process is "holding" that lockfile, then it signals abort() to any other processes that attempt to alter the containing directory - dist - while that lockfile is held.
As long as the end-user isn't hitting build from multiple terminals consecutively (which is on them, not me), then there should be no need for the lockfile...
The text was updated successfully, but these errors were encountered:
Currently:
This codeblock works beautifully, directly from the
react-scripts
webpack config into the esbuild one.Unfortunately though, esbuild doesn't have the standard means of replacing parsed HTML with expanded variables...
... fortunately, I made my own. Adapted from the webpack plugin inside of
react-scripts
. And it works great!The below variables containing
%PUBLIC_URL%
- and any other from the consumer project's.env
files - are now being correctly interpolated:The trick next is to figure out how to get the hashes from build output files (and/or metafile) and inject those as well...
Requirement:
The un-processed HTML should look like the below, with the build output's
index.html
having the appropriate variables -[name]
and[hash]
and so forth - replaced with those found in the build config (from the 1st codeblock):Caveat:
Currently, I'm doing the HTML file build in a separate step, between
copyPublicFolder
(which runs first), and esbuild itself.In order to get the variables that we need to inject into the HTML, we obviously need to run the HTML step after, not before, esbuild finishes each build run.
Thanks to the promise-chaining, there is some scope for placing that function call in exactly the place it needs to happen.
IMPORTANT:
It's worth noting that some implementations out there don't have any stylesheet-importing HTML tag in the template HTML file; it appears that the stylesheet-import gets injected into the HTML on every build run.
Probably a security thing, of course.
Additionally, we must never read and write to the same location at the same time; in fact, I'm going to scrap the "async CLI" idea because it's just bad. With that in mind, a lockfile (just an empty textfile placed at the root of
dist
) could be useful during build, as a kind of atomic flag; if a process is "holding" that lockfile, then it signalsabort()
to any other processes that attempt to alter the containing directory -dist
- while that lockfile is held.As long as the end-user isn't hitting
build
from multiple terminals consecutively (which is on them, not me), then there should be no need for the lockfile...The text was updated successfully, but these errors were encountered: