I encountered a similar issue that needed a fast fix for a client that had multiple customers with different domains for each customer so I had to get the webpack module federation to use dynamic remotes, I used relative paths for the remotes:
name: 'container',
//The value is constructed as follows:
// - the part before the '@' is the name mentioned in the remote ModuleFederationPlugin
// - the part after the '@' is the URL of the remote entry file
// WARNING: never name the remote project as a class name, it will cause a conflict
remotes: {
media: `media@/media/latest/remoteEntry.js`,
},
In the browser, relative paths are resolved to the website's root path, which is perfect in this case. because the domain was the only difference in my case between the customers.
if you need other common variables between the micro frontends
I found out that the go-to solution is to use a relative request in index.js to /config.json and inject the variables into the window object before calling the bootstrap file something like:
// main.js or index.js in the host app
async function loadConfig() {
try {
const response = await fetch('/config.json');
const config = await response.json();
window.__sharedConfig__ = config;
} catch (error) {
console.error('Error loading config.json:', error);
}
}
(async () => {
await loadConfig();
await import('./bootstrap');
})();
NOTE: didn't test the snippet of the code loadConfig above take it more as an example of what suppose to be done.
if you need to template other env vars in the webpack config file after the bundle (I don't recommend this solution it feels 'hacky' for me; but didn't find alternatives for templating vars in the webpack config):
- the bash script (you need to specify each env var in the envsubst or it will break the script); in the next example it will replace the string '$SOME_VAR' in all the bundle files with the desired value:
#!/bin/sh
# Replace the placeholders in the JavaScript files with the actual values
if [ -n "$SOME_VAR" ]; then
export SOME_VAR
for file in /usr/share/nginx/html/container/latest/*.js; do
envsubst "SOME_VAR" <"$file" >"$file.tmp"
mv "$file.tmp" "$file"
done
fi
# Start Nginx
nginx -g "daemon off;"
- the Dockerfile that I used (if you don't use the entrypoint solution comment out the last 3 steps: COPY, RUN chmod adn the ENTRYPOINT)
FROM node:18-alpine3.17 as base
WORKDIR /usr/src/app
COPY yarn.lock tsconfig.json package.json nx.json lerna.json ./
# copy package.json for install dependencies
COPY ./packages/eslint-config/package.json ./packages/eslint-config/package.json
COPY ./web/container/package.json ./web/container/package.json
# install dependencies
# TODO: need to move all relevat dependencies from devDependencies to dependencies
# better even create package for webpack container configuration
RUN yarn install --frozen-lockfile
# --production
# copy source code
COPY ./packages/eslint-config ./packages/eslint-config
COPY ./web/container ./web/container
# build container service
RUN yarn build --scope=@premade/container-host
# Use the official Nginx image as the base
FROM nginx:stable-alpine3.17
EXPOSE 80
# Copy your built frontend assets
COPY --from=base /usr/src/app/web/container/build /usr/share/nginx/html/container/latest
# Copy your Nginx configuration
COPY --from=base /usr/src/app/web/container/config/nginx.conf /etc/nginx/conf.d/default.conf
# TODO: seems there a more popular way to do this
# /config.json request on bootstrap to relative path
# to serve common variables or env variables
# Copy your entrypoint.sh script to handle the environment variables
COPY ./web/container/scripts/entrypoint.sh /usr/local/bin/entrypoint.sh
# Set the proper permissions for the entrypoint.sh script
RUN chmod +x /usr/local/bin/entrypoint.sh
# Set the entrypoint.sh script as the entrypoint
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
used Lerna monorepo in the docker file I mention again I didn't use the entrypoint eventually and went with the relative path solution for some reason when you try to template remote paths it duplicates the domain in the remote path request, but it worked like a charm for other env vars in the webpack config.
process.env
object in this file ? try console.log(process.env) in this file. – Ebneter