This is a library that makes it possible to change the configuration values of the Remix compiler (esbuild).
For example, Next.js allows you to control webpack option values from a configuration file (next.config.js
).
Remix does not have that functionality. A member of the development team says in a PR comment that this is because exposing the configuration values would lock in the compiler's choices and also risk breaking the application.
I support that argument, but in actual use cases, I often want to change the settings.
So I decided to provide that functionality outside of Remix (in this 3rd-party library).
# npm
npm install -D remix-esbuild-override
# yarn
yarn add -D remix-esbuild-override
You can define function properties in remix.config.js
that can override esbuild configuration values.
// remix.config.js
const { withEsbuildOverride } = require("remix-esbuild-override");
/**
* Define callbacks for the arguments of withEsbuildOverride.
* @param option - Default configuration values defined by the remix compiler
* @param isServer - True for server compilation, false for browser compilation
* @param isDev - True during development.
* @return {EsbuildOption} - You must return the updated option
*/
withEsbuildOverride((option, { isServer, isDev }) => {
// update the option
option.plugins = [
someEsbuildPlugin,
...option.plugins
]
return option;
})
/**
* @type {import('@remix-run/dev').AppConfig}
*/
module.exports = {
// ...
};
๐ NOTE: Compilation is executed twice, once for the server and once for the browser.
This is an example of choosing Cloudflare Workers at runtime and using emotion.
yarn add @emotion/server @emotion/react @emotion/cache
yarn add -D no-op esbuild-plugin-alias
// reactShims.ts
import { jsx } from "@emotion/react";
import * as React from "react";
export { jsx, React };
// remix.config.js
const path = require("node:path");
const alias = require("esbuild-plugin-alias");
const { withEsbuildOverride } = require("remix-esbuild-override");
withEsbuildOverride((option, { isServer }) => {
option.jsxFactory = "jsx";
option.inject = [path.resolve(__dirname, "reactShims.ts")];
option.plugins = [
alias({
through: require.resolve("no-op"),
"html-tokenize": require.resolve("no-op"),
multipipe: require.resolve("no-op"),
}),
...option.plugins,
];
if (isServer) option.mainFields = ["browser", "module", "main"];
return option;
})
/**
* @type {import('@remix-run/dev').AppConfig}
*/
module.exports = {
serverBuildTarget: "cloudflare-workers",
server: "./server.js",
devServerBroadcastDelay: 1000,
ignoredRouteFiles: [".*"],
};