diff --git a/.changeset/css-bundle-skip-packages.md b/.changeset/css-bundle-skip-packages.md new file mode 100644 index 00000000000..9afad9e2e9d --- /dev/null +++ b/.changeset/css-bundle-skip-packages.md @@ -0,0 +1,5 @@ +--- +"@remix-run/dev": patch +--- + +Improve performance of CSS bundle build by skipping compilation of Remix/React packages that are known not to contain CSS imports diff --git a/packages/remix-dev/compiler/css/compiler.ts b/packages/remix-dev/compiler/css/compiler.ts index 9517a3aa9e5..cc56b0dc7fb 100644 --- a/packages/remix-dev/compiler/css/compiler.ts +++ b/packages/remix-dev/compiler/css/compiler.ts @@ -79,6 +79,10 @@ const createEsbuildConfig = (ctx: Context): esbuild.BuildOptions => { absoluteCssUrlsPlugin(), externalPlugin(/^https?:\/\//, { sideEffects: false }), mdxPlugin(ctx), + // Skip compilation of common packages/scopes known not to include CSS imports + emptyModulesPlugin(ctx, /^(@remix-run|react|react-dom)(\/.*)?$/, { + includeNodeModules: true, + }), emptyModulesPlugin(ctx, /\.server(\.[jt]sx?)?$/), externalPlugin(/^node:.*/, { sideEffects: false }), ], diff --git a/packages/remix-dev/compiler/plugins/emptyModules.ts b/packages/remix-dev/compiler/plugins/emptyModules.ts index a8b34c00e6f..9ae03d6c74a 100644 --- a/packages/remix-dev/compiler/plugins/emptyModules.ts +++ b/packages/remix-dev/compiler/plugins/emptyModules.ts @@ -9,18 +9,21 @@ import type { Context } from "../context"; */ export function emptyModulesPlugin( { config }: Context, - filter: RegExp + filter: RegExp, + { includeNodeModules = false } = {} ): esbuild.Plugin { return { name: "empty-modules", setup(build) { build.onResolve({ filter }, (args) => { - let resolved = path.resolve(args.resolveDir, args.path); if ( + includeNodeModules || // Limit this behavior to modules found in only the `app` directory. // This allows node_modules to use the `.server.js` and `.client.js` // naming conventions with different semantics. - resolved.startsWith(config.appDirectory) + path + .resolve(args.resolveDir, args.path) + .startsWith(config.appDirectory) ) { return { path: args.path, namespace: "empty-module" }; }