diff --git a/integration/svg-in-node-modules-test.ts b/integration/svg-in-node-modules-test.ts
new file mode 100644
index 00000000000..96e604c02b8
--- /dev/null
+++ b/integration/svg-in-node-modules-test.ts
@@ -0,0 +1,48 @@
+import { test, expect } from "@playwright/test";
+
+import { PlaywrightFixture } from "./helpers/playwright-fixture";
+import type { Fixture, AppFixture } from "./helpers/create-fixture";
+import { createAppFixture, createFixture, js } from "./helpers/create-fixture";
+
+let fixture: Fixture;
+let appFixture: AppFixture;
+
+test.beforeEach(async ({ context }) => {
+ await context.route(/_data/, async (route) => {
+ await new Promise((resolve) => setTimeout(resolve, 50));
+ route.continue();
+ });
+});
+
+test.beforeAll(async () => {
+ fixture = await createFixture({
+ files: {
+ "app/routes/_index.tsx": js`
+ import imgSrc from "getos/imgs/logo.svg";
+
+ export default function () {
+ return (
+
+
+
+ )
+ }
+ `,
+ },
+ });
+
+ appFixture = await createAppFixture(fixture);
+});
+
+test.afterAll(() => {
+ appFixture.close();
+});
+
+test("renders SVG images imported from node_modules", async ({ page }) => {
+ let app = new PlaywrightFixture(appFixture, page);
+ // You can test any request your app might get using `fixture`.
+ await app.goto("/");
+ expect(await page.getByTestId("example-svg").getAttribute("src")).toMatch(
+ /\/build\/_assets\/logo-.*\.svg/
+ );
+});
diff --git a/packages/remix-dev/compiler/server/plugins/bareImports.ts b/packages/remix-dev/compiler/server/plugins/bareImports.ts
index cbe99bab0f0..a4e1851248a 100644
--- a/packages/remix-dev/compiler/server/plugins/bareImports.ts
+++ b/packages/remix-dev/compiler/server/plugins/bareImports.ts
@@ -10,6 +10,7 @@ import { isCssSideEffectImportPath } from "../../plugins/cssSideEffectImports";
import { createMatchPath } from "../../utils/tsconfig";
import { detectPackageManager } from "../../../cli/detectPackageManager";
import type { Context } from "../../context";
+import { getLoaderForFile } from "../../utils/loaders";
/**
* A plugin responsible for resolving bare module ids based on server target.
@@ -59,8 +60,23 @@ export function serverBareModulesPlugin(ctx: Context): Plugin {
return undefined;
}
- // Always bundle CSS files so we get immutable fingerprinted asset URLs.
- if (path.endsWith(".css")) {
+ // Skip assets that are treated as files (.css, .svg, .png, etc.).
+ // Otherwise, esbuild would emit code that would attempt to require()
+ // or import these files --- which aren't JavaScript!
+ let loader;
+ try {
+ loader = getLoaderForFile(path);
+ } catch (e) {
+ if (
+ !(
+ e instanceof Error &&
+ e.message.startsWith("Cannot get loader for file")
+ )
+ ) {
+ throw e;
+ }
+ }
+ if (loader === "file") {
return undefined;
}