Feature flag auto_import_buffer since it's not fully implemented yet

This commit is contained in:
Jarred Sumner
2021-09-13 20:56:22 -07:00
parent a0b6892c09
commit 4f0d4cee0b
4 changed files with 27 additions and 437 deletions

5
.vscode/launch.json vendored
View File

@@ -98,7 +98,7 @@
// "args": ["--serve", "--origin=http://localhost:3000"],
"args": ["dev", "--origin=http://localhost:3000"],
"cwd": "${workspaceFolder}/examples/hello-next",
"console": "internalConsole"
"console": "internalConsole"
},
{
"type": "lldb",
@@ -247,7 +247,7 @@
"console": "internalConsole"
},
{
"type": "lldb",
"type": "cppvsdbg",
"request": "launch",
"name": "Fixtures Rel",
"program": "${workspaceFolder}/build/macos-x86_64/bun",
@@ -257,6 +257,7 @@
},
{
"type": "lldb",
"request": "launch",
"name": "Context Dev",
"program": "${workspaceFolder}/build/debug/macos-x86_64/bun",

View File

@@ -1,417 +0,0 @@
globalThis.global = globalThis;
globalThis.Bun_disableCSSImports = true;
import "./bun-error";
import * as React from "react";
var onlyChildPolyfill = React.Children.only;
React.Children.only = function (children) {
if (children && typeof children === "object" && children.length == 1) {
return onlyChildPolyfill(children[0]);
}
return onlyChildPolyfill(children);
};
import * as ReactDOM from "react-dom";
import App from "next/app";
import mitt, { MittEmitter } from "next/dist/shared/lib/mitt";
import { RouterContext } from "next/dist/shared/lib/router-context";
import Router, {
AppComponent,
AppProps,
delBasePath,
hasBasePath,
PrivateRouteInfo,
} from "next/dist/shared/lib/router/router";
import * as NextRouteLoader from "next/dist/client/route-loader";
import { isDynamicRoute } from "next/dist/shared/lib/router/utils/is-dynamic";
import {
urlQueryToSearchParams,
assign,
} from "next/dist/shared/lib/router/utils/querystring";
import { setConfig } from "next/dist/shared/lib/runtime-config";
import {
getURL,
loadGetInitialProps,
NEXT_DATA,
ST,
} from "next/dist/shared/lib/utils";
// import { Portal } from "next/dist/client/portal";
import initHeadManager from "next/dist/client/head-manager";
import { HeadManagerContext } from "next/dist/shared/lib/head-manager-context";
import PageLoader from "./page-loader";
import measureWebVitals from "next/dist/client/performance-relayer";
import { RouteAnnouncer } from "next/dist/client/route-announcer";
import {
createRouter,
makePublicRouterInstance,
} from "next/dist/client/router";
export const emitter: MittEmitter<string> = mitt();
declare global {
interface Window {
/* test fns */
__NEXT_HYDRATED?: boolean;
__NEXT_HYDRATED_CB?: () => void;
/* prod */
__NEXT_PRELOADREADY?: (ids?: (string | number)[]) => void;
__NEXT_DATA__: NEXT_DATA;
__NEXT_P: any[];
}
}
function nextDataFromBunData() {
const {
router: { routes, route, params: paramsList },
problems,
} = globalThis.__BUN_DATA__;
const paramsMap = new Map();
for (let i = 0; i < paramsList.keys.length; i++) {
paramsMap.set(
decodeURIComponent(paramsList.keys[i]),
decodeURIComponent(paramsList.values[i])
);
}
const params = {};
var url = new URL(location.href);
Object.assign(params, Object.fromEntries(url.searchParams.entries()));
Object.assign(params, Object.fromEntries(paramsMap.entries()));
const pages = routes.reduce((acc, route) => {
var name = route.substring(route.indexOf("_next") + "_next/".length);
while (name.startsWith("/")) {
name = name.substring(1);
}
if (name.startsWith("pages")) {
name = name.substring("pages".length);
}
while (name.startsWith("/")) {
name = name.substring(1);
}
if (name.endsWith(".jsx")) {
name = name.substring(0, name.length - ".jsx".length);
}
if (name.endsWith(".tsx")) {
name = name.substring(0, name.length - ".tsx".length);
}
if (name.endsWith(".ts")) {
name = name.substring(0, name.length - ".ts".length);
}
if (name.endsWith(".js")) {
name = name.substring(0, name.length - ".js".length);
}
acc["/" + name] = [route];
return acc;
}, {});
return {
page: routes[route],
buildId: "1234",
assetPrefix: "",
isPreview: false,
locale: null,
locales: [],
isFallback: false,
err: null,
props: {},
query: params,
pages,
};
}
type RenderRouteInfo = PrivateRouteInfo & {
App: AppComponent;
scroll?: { x: number; y: number } | null;
};
type RenderErrorProps = Omit<RenderRouteInfo, "Component" | "styleSheets">;
const nextDataTag = document.getElementById("__NEXT_DATA__");
const data: typeof window["__NEXT_DATA__"] = nextDataTag
? JSON.parse(document.getElementById("__NEXT_DATA__")!.textContent!)
: nextDataFromBunData();
window.__NEXT_DATA__ = data;
const {
props: hydrateProps,
err: hydrateErr,
page,
query,
buildId,
assetPrefix,
runtimeConfig,
dynamicIds,
isFallback,
locale,
locales,
domainLocales,
isPreview,
} = data;
const prefix: string = assetPrefix || "";
setConfig({
serverRuntimeConfig: {},
publicRuntimeConfig: runtimeConfig || {},
});
let asPath: string = getURL();
// make sure not to attempt stripping basePath for 404s
if (hasBasePath(asPath)) {
asPath = delBasePath(asPath);
}
export const pageLoader: PageLoader = new PageLoader(
buildId,
prefix,
data.pages
);
const headManager: {
mountedInstances: Set<unknown>;
updateHead: (head: JSX.Element[]) => void;
} = initHeadManager();
const appElement: HTMLElement | null = document.getElementById("__next");
let lastRenderReject: (() => void) | null;
let webpackHMR: any;
export let router: Router;
let CachedApp: AppComponent, onPerfEntry: (metric: any) => void;
export default function boot(EntryPointNamespace, loader) {
_boot(EntryPointNamespace).then(() => {}, false);
}
class Container extends React.Component<{
fn: (err: Error, info?: any) => void;
}> {
componentDidCatch(componentErr: Error, info: any) {
this.props.fn(componentErr, info);
}
componentDidMount() {
this.scrollToHash();
// We need to replace the router state if:
// - the page was (auto) exported and has a query string or search (hash)
// - it was auto exported and is a dynamic route (to provide params)
// - if it is a client-side skeleton (fallback render)
if (
router.isSsr &&
// We don't update for 404 requests as this can modify
// the asPath unexpectedly e.g. adding basePath when
// it wasn't originally present
page !== "/404" &&
page !== "/_error" &&
(isFallback ||
(data.nextExport &&
(isDynamicRoute(router.pathname) ||
location.search ||
process.env.__NEXT_HAS_REWRITES)) ||
(hydrateProps &&
hydrateProps.__N_SSG &&
(location.search || process.env.__NEXT_HAS_REWRITES)))
) {
// update query on mount for exported pages
router.replace(
router.pathname +
"?" +
String(
assign(
urlQueryToSearchParams(router.query),
new URLSearchParams(location.search)
)
),
asPath,
{
// @ts-ignore
// WARNING: `_h` is an internal option for handing Next.js
// client-side hydration. Your app should _never_ use this property.
// It may change at any time without notice.
_h: 1,
// Fallback pages must trigger the data fetch, so the transition is
// not shallow.
// Other pages (strictly updating query) happens shallowly, as data
// requirements would already be present.
shallow: !isFallback,
}
);
}
}
componentDidUpdate() {
this.scrollToHash();
}
scrollToHash() {
let { hash } = location;
hash = hash && hash.substring(1);
if (!hash) return;
const el: HTMLElement | null = document.getElementById(hash);
if (!el) return;
// If we call scrollIntoView() in here without a setTimeout
// it won't scroll properly.
setTimeout(() => el.scrollIntoView(), 0);
}
render() {
return this.props.children;
}
}
let CachedComponent: React.ComponentType;
const wrapApp =
(App: AppComponent) =>
(wrappedAppProps: Record<string, any>): JSX.Element => {
const appProps: AppProps = {
...wrappedAppProps,
Component: CachedComponent,
err: hydrateErr,
router,
};
return (
<AppContainer>
<App {...appProps} />
</AppContainer>
);
};
function AppContainer({
children,
}: React.PropsWithChildren<{}>): React.ReactElement {
return (
<Container fn={(error) => <div>{JSON.stringify(error)}</div>}>
<RouterContext.Provider value={makePublicRouterInstance(router)}>
<HeadManagerContext.Provider value={headManager}>
{children}
</HeadManagerContext.Provider>
</RouterContext.Provider>
</Container>
);
}
export async function _boot(EntryPointNamespace, isError) {
NextRouteLoader.default.getClientBuildManifest = () => Promise.resolve({});
const PageComponent = EntryPointNamespace.default;
const appScripts = globalThis.__NEXT_DATA__.pages["/_app"];
if (appScripts && appScripts.length > 0) {
let appSrc;
for (let asset of appScripts) {
if (!asset.endsWith(".css")) {
appSrc = asset;
break;
}
}
if (appSrc) {
const AppModule = await import(appSrc);
console.assert(
AppModule.default,
appSrc + " must have a default export'd React component"
);
CachedApp = AppModule.default;
} else {
CachedApp = App;
}
}
router = createRouter(page, query, asPath, {
initialProps: hydrateProps,
pageLoader,
App: CachedApp,
Component: CachedComponent,
wrapApp,
err: null,
isFallback: Boolean(isFallback),
subscription: async (info, App, scroll) => {
return render(
Object.assign<
{},
Omit<RenderRouteInfo, "App" | "scroll">,
Pick<RenderRouteInfo, "App" | "scroll">
>({}, info, {
App,
scroll,
})
);
},
locale,
locales,
defaultLocale: "",
domainLocales,
isPreview,
});
globalThis.next.router = router;
if (isError) {
ReactDOM.render(
<TopLevelRender
App={CachedApp}
Component={PageComponent}
props={{ pageProps: hydrateProps }}
/>,
document.querySelector("#__next")
);
} else {
ReactDOM.hydrate(
<TopLevelRender
App={CachedApp}
Component={PageComponent}
props={{ pageProps: hydrateProps }}
/>,
document.querySelector("#__next")
);
}
}
function TopLevelRender({ App, Component, props, scroll }) {
return (
<AppContainer scroll={scroll}>
<App Component={Component} {...props}></App>
</AppContainer>
);
}
export function render(props) {
ReactDOM.render(
<TopLevelRender {...props} />,
document.querySelector("#__next")
);
}
export function renderError(e) {
ReactDOM.render(
<AppContainer>
<App Component={<div>UH OH!!!!</div>} pageProps={data.props}></App>
</AppContainer>,
document.querySelector("#__next")
);
}
globalThis.next = {
version: "11.1.0",
emitter,
render,
renderError,
};

View File

@@ -66,3 +66,4 @@ pub const CSSInJSImportBehavior = enum {
// having issues compiling WebKit with this enabled
pub const remote_inspector = false;
pub const auto_import_buffer = false;

View File

@@ -2342,24 +2342,26 @@ pub const Parser = struct {
var runtime_imports_iter = p.runtime_imports.iter();
// If they use Buffer...just automatically import it.
// magic ✨ (i don't like this)
if (p.symbols.items[p.buffer_ref.inner_index].use_count_estimate > 0) {
var named_import = p.named_imports.getOrPut(p.buffer_ref);
if (FeatureFlags.auto_import_buffer) {
// If they use Buffer...just automatically import it.
// ✨ magic ✨ (i don't like this)
if (p.symbols.items[p.buffer_ref.inner_index].use_count_estimate > 0) {
var named_import = p.named_imports.getOrPut(p.buffer_ref);
// if Buffer is actually an import, let them use that one instead.
if (!named_import.found_existing) {
const import_record_id = p.addImportRecord(
.require,
logger.Loc.empty,
NodeFallbacks.buffer_fallback_import_name,
);
var import_stmt = p.s(S.Import{
.namespace_ref = p.buffer_ref,
.star_name_loc = loc,
.is_single_line = true,
.import_record_index = import_record_id,
}, loc);
// if Buffer is actually an import, let them use that one instead.
if (!named_import.found_existing) {
const import_record_id = p.addImportRecord(
.require,
logger.Loc.empty,
NodeFallbacks.buffer_fallback_import_name,
);
var import_stmt = p.s(S.Import{
.namespace_ref = p.buffer_ref,
.star_name_loc = loc,
.is_single_line = true,
.import_record_index = import_record_id,
}, loc);
}
}
}
@@ -3537,7 +3539,10 @@ pub fn NewParser(
p.exports_ref = try p.declareCommonJSSymbol(.unbound, "exports");
p.module_ref = try p.declareCommonJSSymbol(.unbound, "module");
p.require_ref = try p.declareCommonJSSymbol(.unbound, "require");
p.buffer_ref = try p.declareCommonJSSymbol(.unbound, "Buffer");
if (FeatureFlags.auto_import_buffer) {
p.buffer_ref = try p.declareCommonJSSymbol(.unbound, "Buffer");
}
if (p.options.enable_bundling) {
p.runtime_imports.__reExport = try p.declareGeneratedSymbol(.other, "__reExport");