aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/bun-framework-next/appInjector.js15
-rw-r--r--packages/bun-framework-next/client.development.tsx123
-rw-r--r--packages/bun-framework-next/fallback.development.tsx68
-rw-r--r--packages/bun-framework-next/package.json2
-rw-r--r--packages/bun-framework-next/page-loader.ts8
-rw-r--r--packages/bun-framework-next/renderDocument.tsx18
-rw-r--r--src/bundler.zig10
-rw-r--r--src/http.zig12
-rw-r--r--src/js_printer.zig12
-rw-r--r--src/linker.zig188
-rw-r--r--src/runtime/hmr.ts10
11 files changed, 320 insertions, 146 deletions
diff --git a/packages/bun-framework-next/appInjector.js b/packages/bun-framework-next/appInjector.js
new file mode 100644
index 000000000..e8bf22d21
--- /dev/null
+++ b/packages/bun-framework-next/appInjector.js
@@ -0,0 +1,15 @@
+export function maybeInjectApp(expr) {
+ var app;
+ try {
+ const path = Bun.routesDir + "/_app";
+ app = Bun.resolveSync(path, Bun.cwd + "/");
+ } catch (exception) {
+ return undefined;
+ }
+
+ return (
+ <>
+ <import path={app} />
+ </>
+ );
+}
diff --git a/packages/bun-framework-next/client.development.tsx b/packages/bun-framework-next/client.development.tsx
index 1c51a97e8..fd8e43a20 100644
--- a/packages/bun-framework-next/client.development.tsx
+++ b/packages/bun-framework-next/client.development.tsx
@@ -41,6 +41,8 @@ import {
createRouter,
makePublicRouterInstance,
} from "next/dist/client/router";
+import { packageVersion } from "macro:./packageVersion";
+import NextHead from "next/head";
export const emitter: MittEmitter<string> = mitt();
@@ -61,6 +63,7 @@ function nextDataFromBunData() {
const {
router: { routes, route, params: paramsList },
} = globalThis.__BUN_DATA__;
+ const appStyles = globalThis.__BUN_APP_STYLES || [];
const paramsMap = new Map();
for (let i = 0; i < paramsList.keys.length; i++) {
@@ -76,8 +79,19 @@ function nextDataFromBunData() {
Object.assign(params, Object.fromEntries(paramsMap.entries()));
const pages = routes.keys.reduce((acc, routeName, i) => {
+ if (!routes.values[i].startsWith("/_next/")) {
+ routes.values[i] =
+ "/_next/" +
+ routes.values[i].substring(routes.values[i].startsWith("/") ? 1 : 0);
+ }
+
const routePath = routes.values[i];
- acc[routeName] = [routePath];
+ if (routeName === "/_app" && appStyles.length) {
+ acc[routeName] = [routePath, ...appStyles];
+ } else {
+ acc[routeName] = [routePath];
+ }
+
return acc;
}, {});
@@ -108,6 +122,11 @@ const data: NEXT_DATA & { pages: Record<string, string[]> } = nextDataTag
? JSON.parse(document.getElementById("__NEXT_DATA__")!.textContent!)
: nextDataFromBunData();
+var headManager: {
+ mountedInstances: Set<unknown>;
+ updateHead: (head: JSX.Element[]) => void;
+} = initHeadManager();
+
window.__NEXT_DATA__ = data;
const {
@@ -142,19 +161,33 @@ if (hasBasePath(asPath)) {
asPath = delBasePath(asPath);
}
+window.__DEV_PAGES_MANIFEST = pages;
export const pageLoader: PageLoader = new PageLoader(buildId, prefix, pages);
-const headManager: {
- mountedInstances: Set<unknown>;
- updateHead: (head: JSX.Element[]) => void;
-} = initHeadManager();
-
export let router: Router;
let CachedApp: AppComponent = null;
-
+var ranBoot = false;
export default function boot(EntryPointNamespace) {
- _boot(EntryPointNamespace, false);
+ if (ranBoot) return;
+ ranBoot = true;
+ switch (document.readyState) {
+ case "loading": {
+ document.addEventListener(
+ "DOMContentLoaded",
+ () => boot(EntryPointNamespace),
+ {
+ once: true,
+ passive: true,
+ }
+ );
+ break;
+ }
+ case "interactive":
+ case "complete": {
+ return _boot(EntryPointNamespace, false);
+ }
+ }
}
class Container extends React.Component<{
@@ -280,7 +313,9 @@ class BootError extends Error {
}
export async function _boot(EntryPointNamespace, isError) {
- NextRouteLoader.getClientBuildManifest = () => Promise.resolve({});
+ NextRouteLoader.getClientBuildManifest = () => {
+ return Promise.resolve({});
+ };
const PageComponent = EntryPointNamespace.default;
@@ -291,6 +326,7 @@ export async function _boot(EntryPointNamespace, isError) {
// @ts-expect-error
CachedApp = NextApp;
CachedComponent = PageComponent;
+ const styleSheets = [];
if (appScripts && appScripts.length > 0) {
let appSrc;
@@ -302,6 +338,7 @@ export async function _boot(EntryPointNamespace, isError) {
}
if (appSrc) {
+ const initialHeadCount = document?.head?.children?.length ?? 0;
const AppModule = await import(appSrc);
console.assert(
@@ -312,9 +349,50 @@ export async function _boot(EntryPointNamespace, isError) {
if ("default" in AppModule) {
CachedApp = AppModule.default;
}
+
+ if (pageLoader.cssQueue.length > 0) {
+ await Promise.allSettled(pageLoader.cssQueue.slice());
+ pageLoader.cssQueue.length = 0;
+ }
+
+ const newCount = document?.head?.children?.length ?? 0;
+ if (newCount > initialHeadCount && newCount > 1) {
+ // Move any <App />-inserted nodes to the beginning, preserving the order
+ // This way if there are stylesheets they appear in the expected order
+ var firstNonMetaTag = document.head.children.length;
+
+ for (let i = 0; i < document.head.childNodes.length; i++) {
+ if (document.head.children[i].tagName !== "META") {
+ firstNonMetaTag = i;
+ break;
+ }
+ }
+
+ if (firstNonMetaTag !== document.head.children.length) {
+ outer: for (let i = newCount - 1; i > initialHeadCount - 1; i--) {
+ const node = document.head.children[i];
+ if (
+ node.tagName === "LINK" &&
+ node.hasAttribute("href") &&
+ node.href
+ ) {
+ const normalized = new URL(node.href, location.origin).href;
+ for (let script of appScripts) {
+ if (new URL(script, location.origin).href === normalized)
+ continue outer;
+ }
+
+ appScripts.push(normalized);
+ }
+ styleSheets.push(node);
+ }
+ }
+ }
}
}
+ headManager = initHeadManager();
+
router = createRouter(page, query, asPath, {
initialProps: hydrateProps,
pageLoader,
@@ -356,12 +434,27 @@ export async function _boot(EntryPointNamespace, isError) {
domEl = nextEl;
}
+ const StylePreserver = () => {
+ React.useEffect(() => {
+ for (let i = 0; i < styleSheets.length; i++) {
+ if (!document.head.contains(styleSheets[i])) {
+ document.head.appendChild(styleSheets[i]);
+ }
+ }
+ }, []);
+
+ return null;
+ };
+
const reactEl = (
- <TopLevelRender
- App={CachedApp}
- Component={PageComponent}
- props={hydrateProps}
- />
+ <>
+ <TopLevelRender
+ App={CachedApp}
+ Component={PageComponent}
+ props={hydrateProps}
+ />
+ <StylePreserver />
+ </>
);
if (USE_REACT_18) {
@@ -436,7 +529,7 @@ export function renderError(e) {
}
globalThis.next = {
- version: "12.0.4",
+ version: packageVersion("next"),
emitter,
render,
renderError,
diff --git a/packages/bun-framework-next/fallback.development.tsx b/packages/bun-framework-next/fallback.development.tsx
index 460b5e165..67a6a387f 100644
--- a/packages/bun-framework-next/fallback.development.tsx
+++ b/packages/bun-framework-next/fallback.development.tsx
@@ -1,31 +1,50 @@
-import { insertStyleSheet } from "./page-loader";
import type { FallbackMessageContainer } from "../../src/api/schema";
+import { maybeInjectApp } from "macro:./appInjector";
+
+var globalStyles = [];
+function insertGlobalStyleSheet({ detail: url }) {
+ globalStyles.push(
+ new Promise((resolve, reject) => {
+ const link: HTMLLinkElement = document.createElement("link");
+ link.rel = "stylesheet";
+ link.href = url;
+ link.onload = resolve;
+ link.onabort = reject;
+ link.onerror = reject;
+ document.head.appendChild(link);
+ })
+ );
+}
+
+const nCSS = document.createElement("noscript");
+nCSS.setAttribute("data-n-css", "");
+document.head.appendChild(nCSS);
+
+document.addEventListener("onimportcss", insertGlobalStyleSheet);
var once = false;
function insertNextHeadCount() {
if (!once) {
document.head.insertAdjacentHTML(
"beforeend",
- `<meta name="next-head-count" content="${document.head.childElementCount}">`
+ `<meta name="next-head-count" content="0">`
);
once = true;
}
}
-function insertGlobalStyleSheet(detail) {
- pageLoader.cssQueue.push(
- insertStyleSheet(detail).then(() => {
- insertNextHeadCount();
- })
- );
-}
-[...globalThis["__BUN"].allImportedStyles].map((detail) =>
- insertGlobalStyleSheet(detail)
-);
+maybeInjectApp();
+
+globalThis.__BUN_APP_STYLES = [...globalThis["__BUN"].allImportedStyles].map(
+ (style) => {
+ const url = new URL(style, location.origin);
+ if (url.origin === location.origin && url.href === style) {
+ return url.pathname;
+ }
-document.addEventListener("onimportcss", insertGlobalStyleSheet, {
- passive: true,
-});
+ return style;
+ }
+);
import { _boot, pageLoader } from "./client.development";
@@ -39,24 +58,21 @@ function renderFallback({ router }: FallbackMessageContainer) {
}
document.removeEventListener("onimportcss", insertGlobalStyleSheet);
- document.addEventListener("onimportcss", pageLoader.onImportCSS, {
- passive: true,
- });
-
- globalThis.__NEXT_DATA__.pages["/_app"] = [
- ...(globalThis.__NEXT_DATA__.pages["/_app"] || []),
- ...globalThis["__BUN"].allImportedStyles,
- ];
-
+ document.addEventListener("onimportcss", pageLoader.onImportCSS);
+ var cssQueue;
return import(route)
.then((Namespace) => {
+ nCSS.remove();
+ document.head.appendChild(nCSS);
+ cssQueue = [...globalStyles, ...pageLoader.cssQueue];
+ pageLoader.cssQueue = [];
insertNextHeadCount();
return _boot(Namespace, true);
})
.then(() => {
- const cssQueue = pageLoader.cssQueue.slice();
+ cssQueue = [...cssQueue, ...pageLoader.cssQueue.slice()];
pageLoader.cssQueue = [];
- return Promise.all([...cssQueue]);
+ return Promise.allSettled(cssQueue);
})
.finally(() => {
document.body.style.visibility = "visible";
diff --git a/packages/bun-framework-next/package.json b/packages/bun-framework-next/package.json
index 46602ed0b..38043222c 100644
--- a/packages/bun-framework-next/package.json
+++ b/packages/bun-framework-next/package.json
@@ -1,6 +1,6 @@
{
"name": "bun-framework-next",
- "version": "12.1.1",
+ "version": "12.1.2",
"main": "empty.js",
"module": "empty.js",
"description": "bun compatibility layer for Next.js v12.x.x",
diff --git a/packages/bun-framework-next/page-loader.ts b/packages/bun-framework-next/page-loader.ts
index 3b31387d8..08919cb39 100644
--- a/packages/bun-framework-next/page-loader.ts
+++ b/packages/bun-framework-next/page-loader.ts
@@ -3,13 +3,13 @@ import NextPageLoader, {
} from "next/dist/client/page-loader";
import getAssetPathFromRoute from "next/dist/shared/lib/router/utils/get-asset-path-from-route";
-export function insertStyleSheet(url: string) {
+export function insertStyleSheet(url: string, isFallback: boolean = false) {
if (document.querySelector(`link[href="${url}"]`)) {
return Promise.resolve();
}
return new Promise((resolve, reject) => {
- const link = document.createElement("link");
+ const link: HTMLLinkElement = document.createElement("link");
link.rel = "stylesheet";
// marking this resolve as void seems to break other things
@@ -18,6 +18,10 @@ export function insertStyleSheet(url: string) {
link.href = url;
+ if (isFallback) {
+ link.setAttribute("data-href", url);
+ }
+
document.head.appendChild(link);
});
}
diff --git a/packages/bun-framework-next/renderDocument.tsx b/packages/bun-framework-next/renderDocument.tsx
index 1bf2086f9..694cb5f8c 100644
--- a/packages/bun-framework-next/renderDocument.tsx
+++ b/packages/bun-framework-next/renderDocument.tsx
@@ -112,9 +112,9 @@ function getScripts(files: DocumentFiles) {
var entryPointIndex = -1;
const scripts = [...normalScripts, ...lowPriorityScripts].map(
(file, index) => {
- if (file.includes(".entry.")) {
- entryPointIndex = index;
- }
+ // if (file.includes(".entry.")) {
+ // entryPointIndex = index;
+ // }
return (
<script
@@ -128,10 +128,10 @@ function getScripts(files: DocumentFiles) {
);
}
);
- if (entryPointIndex > 0) {
- const entry = scripts.splice(entryPointIndex, 1);
- scripts.unshift(...entry);
- }
+ // if (entryPointIndex > 0) {
+ // const entry = scripts.splice(entryPointIndex, 1);
+ // scripts.unshift(...entry);
+ // }
return scripts;
}
@@ -787,13 +787,13 @@ export async function render({
},
// Only enabled in production as development mode has features relying on HMR (style injection for example)
// @ts-expect-error
- unstable_runtimeJS: true,
+ unstable_runtimeJS: false,
// process.env.NODE_ENV === "production"
// ? pageConfig.unstable_runtimeJS
// : undefined,
// unstable_JsPreload: pageConfig.unstable_JsPreload,
// @ts-expect-error
- unstable_JsPreload: true,
+ unstable_JsPreload: false,
dangerousAsPath: router.asPath,
ampState: undefined,
props,
diff --git a/src/bundler.zig b/src/bundler.zig
index 63ebdcce5..bb6d73db9 100644
--- a/src/bundler.zig
+++ b/src/bundler.zig
@@ -1763,7 +1763,15 @@ pub const Bundler = struct {
const resolved_import: *const _resolver.Result = _resolved_import;
- const _module_data = BundledModuleData.getForceBundle(this, resolved_import) orelse unreachable;
+ const _module_data = BundledModuleData.getForceBundle(this, resolved_import) orelse {
+ // if a macro imports code that cannot be bundled
+ // we just silently disable it
+ // because...we need some kind of hook to say "don't bundle this"
+ import_record.path.is_disabled = true;
+ import_record.is_bundled = false;
+
+ continue;
+ };
import_record.module_id = _module_data.module_id;
std.debug.assert(import_record.module_id != 0);
import_record.is_bundled = true;
diff --git a/src/http.zig b/src/http.zig
index 22c7da30f..4a93da2b3 100644
--- a/src/http.zig
+++ b/src/http.zig
@@ -344,7 +344,15 @@ pub const RequestContext = struct {
bundler_parse_options,
@as(?*bundler.FallbackEntryPoint, &fallback_entry_point),
)) |*result| {
- try bundler_.linker.link(fallback_entry_point.source.path, result, this.origin, .absolute_url, false);
+ try bundler_.linker.linkAllowImportingFromBundle(
+ fallback_entry_point.source.path,
+ result,
+ this.origin,
+ .absolute_url,
+ false,
+ false,
+ );
+
var buffer_writer = try JSPrinter.BufferWriter.init(default_allocator);
var writer = JSPrinter.BufferPrinter.init(buffer_writer);
_ = try bundler_.print(
@@ -3316,7 +3324,7 @@ pub const Server = struct {
const kinds = slice.items(.kind);
const hashes = slice.items(.hash);
var file_descriptors = slice.items(.fd);
- var header = fbs.getWritten();
+ const header = fbs.getWritten();
defer ctx.watcher.flushEvictions();
defer Output.flush();
diff --git a/src/js_printer.zig b/src/js_printer.zig
index 2e03c9092..e4a641389 100644
--- a/src/js_printer.zig
+++ b/src/js_printer.zig
@@ -484,7 +484,7 @@ const ImportVariant = enum {
};
}
- pub fn determine(record: *const importRecord.ImportRecord, _: *const Symbol, s_import: *const S.Import) ImportVariant {
+ pub fn determine(record: *const importRecord.ImportRecord, s_import: *const S.Import) ImportVariant {
var variant = ImportVariant.path_only;
if (record.contains_import_star) {
@@ -3883,7 +3883,15 @@ pub fn NewPrinter(
const is_disabled = import_record.path.is_disabled;
const module_id = import_record.module_id;
- switch (ImportVariant.determine(&record, p.symbols.get(s.namespace_ref).?, s)) {
+ // If the bundled import was disabled and only imported for side effects
+ // we can skip it
+
+ if (record.path.is_disabled) {
+ if (p.symbols.get(s.namespace_ref) == null)
+ return;
+ }
+
+ switch (ImportVariant.determine(&record, s)) {
.path_only => {
if (!is_disabled) {
p.printCallModuleID(module_id);
diff --git a/src/linker.zig b/src/linker.zig
index 7d0a3ac41..7bc682a17 100644
--- a/src/linker.zig
+++ b/src/linker.zig
@@ -195,6 +195,18 @@ pub const Linker = struct {
comptime import_path_format: Options.BundleOptions.ImportPathFormat,
comptime ignore_runtime: bool,
) !void {
+ return linkAllowImportingFromBundle(linker, file_path, result, origin, import_path_format, ignore_runtime, true);
+ }
+
+ pub fn linkAllowImportingFromBundle(
+ linker: *ThisLinker,
+ file_path: Fs.Path,
+ result: *_bundler.ParseResult,
+ origin: URL,
+ comptime import_path_format: Options.BundleOptions.ImportPathFormat,
+ comptime ignore_runtime: bool,
+ comptime allow_import_from_bundle: bool,
+ ) !void {
const source_dir = file_path.sourceDir();
var externals = std.ArrayList(u32).init(linker.allocator);
var needs_bundle = false;
@@ -293,34 +305,36 @@ pub const Linker = struct {
}
}
- if (linker.options.node_modules_bundle) |node_modules_bundle| {
- if (Resolver.isPackagePath(import_record.path.text)) {
- const text = import_record.path.text;
+ if (comptime allow_import_from_bundle) {
+ if (linker.options.node_modules_bundle) |node_modules_bundle| {
+ if (Resolver.isPackagePath(import_record.path.text)) {
+ const text = import_record.path.text;
- var package_name = text;
- if (text[0] == '@') {
- if (std.mem.indexOfScalar(u8, text, '/')) |i| {
- if (std.mem.indexOfScalar(u8, text[i + 1 ..], '/')) |j| {
- package_name = text[0 .. i + 1 + j];
+ var package_name = text;
+ if (text[0] == '@') {
+ if (std.mem.indexOfScalar(u8, text, '/')) |i| {
+ if (std.mem.indexOfScalar(u8, text[i + 1 ..], '/')) |j| {
+ package_name = text[0 .. i + 1 + j];
+ }
+ }
+ } else {
+ if (std.mem.indexOfScalar(u8, text, '/')) |i| {
+ package_name = text[0..i];
}
}
- } else {
- if (std.mem.indexOfScalar(u8, text, '/')) |i| {
- package_name = text[0..i];
- }
- }
- if (package_name.len != text.len) {
- if (node_modules_bundle.getPackage(package_name)) |pkg| {
- const import_path = text[@minimum(text.len, package_name.len + 1)..];
- if (node_modules_bundle.findModuleIDInPackageIgnoringExtension(pkg, import_path)) |found_module| {
- import_record.is_bundled = true;
- node_module_bundle_import_path = node_module_bundle_import_path orelse
- linker.nodeModuleBundleImportPath(origin);
-
- import_record.path.text = node_module_bundle_import_path.?;
- import_record.module_id = node_modules_bundle.bundle.modules[found_module].id;
- needs_bundle = true;
- continue :outer;
+ if (package_name.len != text.len) {
+ if (node_modules_bundle.getPackage(package_name)) |pkg| {
+ const import_path = text[@minimum(text.len, package_name.len + 1)..];
+ if (node_modules_bundle.findModuleIDInPackageIgnoringExtension(pkg, import_path)) |found_module| {
+ import_record.is_bundled = true;
+ node_module_bundle_import_path = node_module_bundle_import_path orelse
+ linker.nodeModuleBundleImportPath(origin);
+
+ import_record.path.text = node_module_bundle_import_path.?;
+ import_record.module_id = node_modules_bundle.bundle.modules[found_module].id;
+ needs_bundle = true;
+ continue :outer;
+ }
}
}
}
@@ -332,21 +346,23 @@ pub const Linker = struct {
else => {},
// for fast refresh, attempt to read the version directly from the bundle instead of resolving it
.react_refresh => {
- if (linker.options.node_modules_bundle) |node_modules_bundle| {
- const runtime = linker.options.jsx.refresh_runtime;
- const package_name = runtime[0 .. strings.indexOfChar(runtime, '/') orelse runtime.len];
-
- if (node_modules_bundle.getPackage(package_name)) |pkg| {
- const import_path = runtime[@minimum(runtime.len, package_name.len + 1)..];
- if (node_modules_bundle.findModuleInPackage(pkg, import_path)) |found_module| {
- import_record.is_bundled = true;
- node_module_bundle_import_path = node_module_bundle_import_path orelse
- linker.nodeModuleBundleImportPath(origin);
-
- import_record.path.text = node_module_bundle_import_path.?;
- import_record.module_id = found_module.id;
- needs_bundle = true;
- continue :outer;
+ if (comptime allow_import_from_bundle) {
+ if (linker.options.node_modules_bundle) |node_modules_bundle| {
+ const runtime = linker.options.jsx.refresh_runtime;
+ const package_name = runtime[0 .. strings.indexOfChar(runtime, '/') orelse runtime.len];
+
+ if (node_modules_bundle.getPackage(package_name)) |pkg| {
+ const import_path = runtime[@minimum(runtime.len, package_name.len + 1)..];
+ if (node_modules_bundle.findModuleInPackage(pkg, import_path)) |found_module| {
+ import_record.is_bundled = true;
+ node_module_bundle_import_path = node_module_bundle_import_path orelse
+ linker.nodeModuleBundleImportPath(origin);
+
+ import_record.path.text = node_module_bundle_import_path.?;
+ import_record.module_id = found_module.id;
+ needs_bundle = true;
+ continue :outer;
+ }
}
}
}
@@ -390,54 +406,56 @@ pub const Linker = struct {
const loader = linker.options.loader(path.name.ext);
if (loader.isJavaScriptLikeOrJSON()) {
- bundled: {
- if (linker.options.node_modules_bundle) |node_modules_bundle| {
- const package_json = resolved_import.package_json orelse break :bundled;
- const package_base_dir = package_json.source.path.sourceDir();
- if (node_modules_bundle.getPackageIDByHash(package_json.hash)) |pkg_id| {
- const package = node_modules_bundle.bundle.packages[pkg_id];
-
- if (comptime Environment.isDebug) {
- std.debug.assert(strings.eql(node_modules_bundle.str(package.name), package_json.name));
- std.debug.assert(strings.eql(node_modules_bundle.str(package.version), package_json.version));
- }
+ if (comptime allow_import_from_bundle) {
+ bundled: {
+ if (linker.options.node_modules_bundle) |node_modules_bundle| {
+ const package_json = resolved_import.package_json orelse break :bundled;
+ const package_base_dir = package_json.source.path.sourceDir();
+ if (node_modules_bundle.getPackageIDByHash(package_json.hash)) |pkg_id| {
+ const package = node_modules_bundle.bundle.packages[pkg_id];
+
+ if (comptime Environment.isDebug) {
+ std.debug.assert(strings.eql(node_modules_bundle.str(package.name), package_json.name));
+ std.debug.assert(strings.eql(node_modules_bundle.str(package.version), package_json.version));
+ }
+
+ const package_relative_path = linker.fs.relative(
+ package_base_dir,
+ if (!strings.eqlComptime(path.namespace, "node")) path.pretty else path.text,
+ );
- const package_relative_path = linker.fs.relative(
- package_base_dir,
- if (!strings.eqlComptime(path.namespace, "node")) path.pretty else path.text,
- );
+ const found_module = node_modules_bundle.findModuleInPackage(&package, package_relative_path) orelse {
+ // linker.log.addErrorFmt(
+ // null,
+ // logger.Loc.Empty,
+ // linker.allocator,
+ // "New dependency import: \"{s}/{s}\"\nPlease run `bun bun` to update the .bun.",
+ // .{
+ // package_json.name,
+ // package_relative_path,
+ // },
+ // ) catch {};
+ break :bundled;
+ };
+
+ if (comptime Environment.isDebug) {
+ const module_path = node_modules_bundle.str(found_module.path);
+ std.debug.assert(
+ strings.eql(
+ module_path,
+ package_relative_path,
+ ),
+ );
+ }
- const found_module = node_modules_bundle.findModuleInPackage(&package, package_relative_path) orelse {
- // linker.log.addErrorFmt(
- // null,
- // logger.Loc.Empty,
- // linker.allocator,
- // "New dependency import: \"{s}/{s}\"\nPlease run `bun bun` to update the .bun.",
- // .{
- // package_json.name,
- // package_relative_path,
- // },
- // ) catch {};
- break :bundled;
- };
-
- if (comptime Environment.isDebug) {
- const module_path = node_modules_bundle.str(found_module.path);
- std.debug.assert(
- strings.eql(
- module_path,
- package_relative_path,
- ),
- );
+ import_record.is_bundled = true;
+ node_module_bundle_import_path = node_module_bundle_import_path orelse
+ linker.nodeModuleBundleImportPath(origin);
+ import_record.path.text = node_module_bundle_import_path.?;
+ import_record.module_id = found_module.id;
+ needs_bundle = true;
+ continue;
}
-
- import_record.is_bundled = true;
- node_module_bundle_import_path = node_module_bundle_import_path orelse
- linker.nodeModuleBundleImportPath(origin);
- import_record.path.text = node_module_bundle_import_path.?;
- import_record.module_id = found_module.id;
- needs_bundle = true;
- continue;
}
}
}
diff --git a/src/runtime/hmr.ts b/src/runtime/hmr.ts
index 14350146e..afffc4847 100644
--- a/src/runtime/hmr.ts
+++ b/src/runtime/hmr.ts
@@ -1338,9 +1338,11 @@ if (typeof window !== "undefined") {
// we cannot export new modules. we can only mutate existing ones.
const oldGraphUsed = HMRModule.dependencies.graph_used;
- var oldModule = HMRModule.dependencies.modules[this.module_index];
+ var oldModule =
+ HMRModule.dependencies.modules.length > this.module_index &&
+ HMRModule.dependencies.modules[this.module_index];
HMRModule.dependencies = orig_deps.fork(this.module_index);
- var blobURL = null;
+ var blobURL = "";
// We inject the source map URL into the end of the file.
// We do that here for a few reasons:
@@ -1366,6 +1368,8 @@ if (typeof window !== "undefined") {
blobURL = URL.createObjectURL(blob);
HMRModule.dependencies.blobToID.set(blobURL, this.module_id);
await import(blobURL);
+ this.bytes = null;
+ URL.revokeObjectURL(blobURL);
this.timings.import = performance.now() - importStart;
} catch (exception) {
HMRModule.dependencies = orig_deps;
@@ -1392,7 +1396,7 @@ if (typeof window !== "undefined") {
// If we do import a new module, we have to do a full page reload for now
}
- URL.revokeObjectURL(blobURL);
+ blobURL = "";
// Ensure we don't keep the bytes around longer than necessary
this.bytes = null;