Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@umijs/server

Package Overview
Dependencies
Maintainers
0
Versions
651
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@umijs/server - npm Package Compare versions

Comparing version 4.0.0-canary.20240626.1 to 4.0.0-canary.20240702.1

25

dist/ssr.d.ts

@@ -0,3 +1,5 @@

/// <reference lib="webworker" />
import type { RequestHandler } from '@umijs/bundler-utils/compiled/express';
import React from 'react';
import type { UmiRequest } from './types';
import type { IhtmlPageOpts, UmiRequest } from './types';
interface RouteLoaders {

@@ -15,3 +17,3 @@ [key: string]: () => Promise<any>;

routesWithServerLoader: RouteLoaders;
PluginManager: any;
pluginManager: any;
manifest: ((sourceDir?: string) => {

@@ -22,4 +24,2 @@ assets: Record<string, string>;

};
getPlugins: () => any;
getValidKeys: () => any;
getRoutes: (PluginManager: any) => any;

@@ -29,8 +29,23 @@ getClientRootComponent: (PluginManager: any) => any;

helmetContext?: any;
reactVersion: string;
ServerInsertedHTMLContext: React.Context<ServerInsertedHTMLHook | null>;
htmlPageOpts: IhtmlPageOpts;
__INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
pureApp: boolean;
pureHtml: boolean;
};
mountElementId: string;
}
export declare function createMarkupGenerator(opts: CreateRequestHandlerOptions): (url: string) => Promise<unknown>;
export default function createRequestHandler(opts: CreateRequestHandlerOptions): (req: any, res: any, next: any) => Promise<any>;
declare type IExpressRequestHandlerArgs = Parameters<RequestHandler>;
declare type IWorkerRequestHandlerArgs = [
ev: FetchEvent,
opts?: {
modifyResponse?: (res: Response) => Promise<Response> | Response;
}
];
export default function createRequestHandler(opts: CreateRequestHandlerOptions): (...args: IExpressRequestHandlerArgs | IWorkerRequestHandlerArgs) => Promise<void>;
export declare function createUmiHandler(opts: CreateRequestHandlerOptions): (req: UmiRequest, params?: CreateRequestHandlerOptions) => Promise<NodeJS.ReadableStream>;
export declare function createUmiServerLoader(opts: CreateRequestHandlerOptions): (req: UmiRequest) => Promise<any>;
export declare function createAppRootElement(opts: CreateRequestHandlerOptions): (...args: IExpressRequestHandlerArgs | IWorkerRequestHandlerArgs) => Promise<() => React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined>;
export {};

343

dist/ssr.js

@@ -32,2 +32,3 @@ var __create = Object.create;

__export(ssr_exports, {
createAppRootElement: () => createAppRootElement,
createMarkupGenerator: () => createMarkupGenerator,

@@ -39,2 +40,3 @@ createUmiHandler: () => createUmiHandler,

module.exports = __toCommonJS(ssr_exports);
var import_semver = __toESM(require("@umijs/utils/compiled/semver"));
var import_react = __toESM(require("react"));

@@ -44,3 +46,12 @@ var ReactDomServer = __toESM(require("react-dom/server"));

var import_stream = require("stream");
var createJSXProvider = (Provider, serverInsertedHTMLCallbacks) => {
var MetaLoaderResultKeys = /* @__PURE__ */ ((MetaLoaderResultKeys2) => {
MetaLoaderResultKeys2["Title"] = "title";
MetaLoaderResultKeys2["Description"] = "description";
MetaLoaderResultKeys2["Keywords"] = "keywords";
MetaLoaderResultKeys2["Lang"] = "lang";
MetaLoaderResultKeys2["Metas"] = "metas";
return MetaLoaderResultKeys2;
})(MetaLoaderResultKeys || {});
var createJSXProvider = (Provider) => {
const serverInsertedHTMLCallbacks = /* @__PURE__ */ new Set();
const JSXProvider = (props) => {

@@ -58,3 +69,3 @@ const addInsertedHtml = import_react.default.useCallback(

};
return JSXProvider;
return [JSXProvider, serverInsertedHTMLCallbacks];
};

@@ -65,5 +76,3 @@ function createJSXGenerator(opts) {

routesWithServerLoader,
PluginManager,
getPlugins,
getValidKeys,
pluginManager,
getRoutes,

@@ -74,8 +83,4 @@ createHistory,

createHistory({ type: "memory", initialEntries: [url], initialIndex: 1 });
const pluginManager = PluginManager.create({
plugins: getPlugins(),
validKeys: getValidKeys()
});
const { routes, routeComponents } = await getRoutes(pluginManager);
await pluginManager.applyPlugins({
pluginManager.applyPlugins({
key: "patchRoutes",

@@ -93,3 +98,2 @@ type: "event",

const loaderData = {};
const metadata = {};
await Promise.all(

@@ -104,11 +108,15 @@ matches.filter((id) => routes[id].hasServerLoader).map(

if (routes[id].hasMetadataLoader) {
Object.assign(
metadata,
await executeMetadataLoader({
routesWithServerLoader,
routeKey: id,
serverLoaderArgs,
serverLoaderData: loaderData[id]
})
);
const metadataLoaderData = await executeMetadataLoader({
routesWithServerLoader,
routeKey: id,
serverLoaderArgs,
serverLoaderData: loaderData[id]
});
metadataLoaderData && Object.entries(metadataLoaderData).forEach(([k, v]) => {
if (Array.isArray(v)) {
opts.htmlPageOpts[k] = (opts.htmlPageOpts[k] || []).concat(v);
} else {
opts.htmlPageOpts[k] = v;
}
});
}

@@ -127,3 +135,5 @@ resolve();

loaderData,
metadata
htmlPageOpts: opts.htmlPageOpts,
__INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: opts.__INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
mountElementId: opts.mountElementId
};

@@ -139,9 +149,15 @@ const element = await opts.getClientRootComponent(

}
var getGenerateStaticHTML = (serverInsertedHTMLCallbacks) => {
var SERVER_INSERTED_HTML = "umi-server-inserted-html";
var getGenerateStaticHTML = (serverInsertedHTMLCallbacks, opts) => {
const children = import_react.default.createElement(import_react.default.Fragment, {
children: Array.from(serverInsertedHTMLCallbacks || []).map(
(callback) => callback()
)
});
return ReactDomServer.renderToString(
import_react.default.createElement(import_react.default.Fragment, {
children: Array.from(serverInsertedHTMLCallbacks || []).map(
(callback) => callback()
)
})
(opts == null ? void 0 : opts.wrapper) ? import_react.default.createElement(
"div",
{ id: SERVER_INSERTED_HTML, hidden: true },
children
) : children
) || "";

@@ -155,6 +171,4 @@ };

return new Promise(async (resolve, reject) => {
const serverInsertedHTMLCallbacks = /* @__PURE__ */ new Set();
const JSXProvider = createJSXProvider(
opts.ServerInsertedHTMLContext.Provider,
serverInsertedHTMLCallbacks
const [JSXProvider, serverInsertedHTMLCallbacks] = createJSXProvider(
opts.ServerInsertedHTMLContext.Provider
);

@@ -169,3 +183,6 @@ let chunks = [];

let html = Buffer.concat(chunks).toString("utf8");
html += await getGenerateStaticHTML(serverInsertedHTMLCallbacks);
const serverHTML = getGenerateStaticHTML(serverInsertedHTMLCallbacks);
if (serverHTML) {
html = html.replace(/<\/head>/, `${serverHTML}</head>`);
}
if (opts.helmetContext) {

@@ -192,2 +209,3 @@ html = html.replace(

},
bootstrapScripts: [jsx.manifest.assets["umi.js"] || "/umi.js"],
onError: reject

@@ -201,46 +219,207 @@ }

}
var normalizeRequest = (...args) => {
var _a, _b;
let request;
let serverLoaderRequest;
let serverLoaderArgs;
if (process.env.SSR_BUILD_TARGET === "worker") {
const [ev] = args;
const { pathname, searchParams } = new URL(ev.request.url);
request = {
url: ev.request.url,
pathname,
headers: ev.request.headers,
query: {
route: searchParams.get("route"),
url: searchParams.get("url")
}
};
} else {
const [req] = args;
request = {
url: `${req.protocol}://${req.get("host")}${req.originalUrl}`,
pathname: req.url,
headers: req.headers,
query: {
route: (_a = req.query.route) == null ? void 0 : _a.toString(),
url: (_b = req.query.url) == null ? void 0 : _b.toString()
}
};
}
if (request.pathname.startsWith("/__serverLoader") && request.query.route && request.query.url) {
serverLoaderRequest = new Request(request.query.url, {
headers: request.headers
});
serverLoaderArgs = {
request: serverLoaderRequest
};
}
return {
request,
serverLoaderArgs
};
};
function createRequestHandler(opts) {
const jsxGeneratorDeferrer = createJSXGenerator(opts);
return async function(req, res, next) {
if (req.url.startsWith("/__serverLoader") && req.query.route) {
const serverLoaderRequest = new Request(req.query.url, {
headers: req.headers
});
const normalizeHandlerArgs = (...args) => {
let ret;
const { request } = normalizeRequest(...args);
const replaceServerHTMLScript = `<script>!function(){var e=document.getElementById("${SERVER_INSERTED_HTML}");e&&(Array.from(e.children).forEach(e=>{document.head.appendChild(e)}),e.remove())}();</script>`;
if (process.env.SSR_BUILD_TARGET === "worker") {
const [ev, workerOpts] = args;
let asyncRespondWith;
ev.respondWith(new Promise((r) => asyncRespondWith = r));
ret = {
req: request,
async sendServerLoader(data) {
let res = new Response(JSON.stringify(data), {
headers: {
"content-type": "application/json; charset=utf-8"
},
status: 200
});
if (workerOpts == null ? void 0 : workerOpts.modifyResponse) {
res = await workerOpts.modifyResponse(res);
}
asyncRespondWith(res);
},
async sendPage(jsx) {
const [JSXProvider, serverInsertedHTMLCallbacks] = createJSXProvider(
opts.ServerInsertedHTMLContext.Provider
);
const stream = await ReactDomServer.renderToReadableStream(
import_react.default.createElement(JSXProvider, void 0, jsx.element),
{
// why not bootstrap umi.js
// ER will auto inject
// bootstrapScripts: [jsx.manifest.assets['umi.js'] || '/umi.js'],
onError(x) {
console.error(x);
}
}
);
const transformStream = new TransformStream({
flush(controller) {
if (serverInsertedHTMLCallbacks.size) {
const serverHTML = getGenerateStaticHTML(
serverInsertedHTMLCallbacks,
{ wrapper: true }
);
controller.enqueue(serverHTML);
controller.enqueue(replaceServerHTMLScript);
}
}
});
let res = new Response(stream.pipeThrough(transformStream), {
headers: {
"content-type": "text/html; charset=utf-8"
},
status: 200
});
if (workerOpts == null ? void 0 : workerOpts.modifyResponse) {
res = await workerOpts.modifyResponse(res);
}
asyncRespondWith(res);
},
otherwise() {
throw new Error("no page resource");
}
};
} else {
const [_, res, next] = args;
ret = {
req: request,
sendServerLoader(data) {
res.status(200).json(data);
},
async sendPage(jsx) {
const [JSXProvider, serverInsertedHTMLCallbacks] = createJSXProvider(
opts.ServerInsertedHTMLContext.Provider
);
const writable = new import_stream.Writable();
res.type("html");
writable._write = (chunk, _encoding, cb) => {
res.write(chunk);
cb();
};
writable.on("finish", async () => {
if (serverInsertedHTMLCallbacks.size) {
res.write(
getGenerateStaticHTML(serverInsertedHTMLCallbacks, {
wrapper: true
})
);
res.write(replaceServerHTMLScript);
}
res.end();
});
const canUseCrossOriginInBootstrap = import_semver.default.gte(
opts.reactVersion,
"19.0.0-rc"
);
const umiPath = jsx.manifest.assets["umi.js"] || "/umi.js";
const stream = ReactDomServer.renderToPipeableStream(
import_react.default.createElement(JSXProvider, void 0, jsx.element),
{
// @ts-ignore
bootstrapScripts: canUseCrossOriginInBootstrap ? [
{
src: umiPath,
crossOrigin: "anonymous"
}
] : [umiPath],
onShellReady() {
stream.pipe(writable);
},
onError(x) {
console.error(x);
}
}
);
},
otherwise: next
};
}
return ret;
};
return async function unifiedRequestHandler(...args) {
const { req, sendServerLoader, sendPage, otherwise } = normalizeHandlerArgs(
...args
);
if (req.pathname.startsWith("/__serverLoader") && req.query.route && req.query.url) {
const { serverLoaderArgs } = normalizeRequest(...args);
const data = await executeLoader({
routeKey: req.query.route,
routesWithServerLoader: opts.routesWithServerLoader,
serverLoaderArgs: { request: serverLoaderRequest }
serverLoaderArgs
});
res.status(200).json(data);
return;
await sendServerLoader(data);
} else {
const render = opts.pluginManager.applyPlugins({
key: "render",
type: "compose",
initialValue: () => jsxGeneratorDeferrer(req.pathname, {
request: new Request(req.url, {
headers: req.headers
})
})
});
const jsx = await render();
if (jsx) {
await sendPage(jsx);
} else {
await otherwise();
}
}
const fullUrl = `${req.protocol}://${req.get("host")}${req.originalUrl}`;
const request = new Request(fullUrl, {
headers: req.headers
});
const jsx = await jsxGeneratorDeferrer(req.url, { request });
if (!jsx)
return next();
const writable = new import_stream.Writable();
writable._write = (chunk, _encoding, next2) => {
res.write(chunk);
next2();
};
writable.on("finish", async () => {
res.write(await getGenerateStaticHTML());
res.end();
});
const stream = await ReactDomServer.renderToPipeableStream(jsx.element, {
bootstrapScripts: [jsx.manifest.assets["umi.js"] || "/umi.js"],
onShellReady() {
stream.pipe(writable);
},
onError(x) {
console.error(x);
}
});
};
}
function createUmiHandler(opts) {
let isWarned = false;
return async function(req, params) {
if (!isWarned) {
console.warn(
"[umi] `renderRoot` is deprecated, please use `requestHandler` instead"
);
isWarned = true;
}
const jsxGeneratorDeferrer = createJSXGenerator({

@@ -264,3 +443,10 @@ ...opts,

function createUmiServerLoader(opts) {
let isWarned = false;
return async function(req) {
if (!isWarned) {
console.warn(
"[umi] `serverLoader` is deprecated, please use `requestHandler` instead"
);
isWarned = true;
}
const query = Object.fromEntries(new URL(req.url).searchParams);

@@ -277,2 +463,10 @@ const serverLoaderRequest = new Request(query.url, {

}
function createAppRootElement(opts) {
return async (...args) => {
const jsxGeneratorDeferrer = createJSXGenerator(opts);
const { request, serverLoaderArgs } = normalizeRequest(...args);
const jsx = await jsxGeneratorDeferrer(request.pathname, serverLoaderArgs);
return () => jsx == null ? void 0 : jsx.element;
};
}
function matchRoutesForSSR(reqUrl, routesById) {

@@ -315,8 +509,3 @@ var _a;

async function executeMetadataLoader(params) {
const {
routesWithServerLoader,
routeKey,
serverLoaderArgs,
serverLoaderData
} = params;
const { routesWithServerLoader, routeKey, serverLoaderData } = params;
const mod = await routesWithServerLoader[routeKey]();

@@ -326,9 +515,15 @@ if (!mod.serverLoader || typeof mod.serverLoader !== "function") {

}
return mod.metadataLoader(
serverLoaderData,
serverLoaderArgs
const loaderDatas = mod.metadataLoader(
serverLoaderData
);
const result = {};
Object.values(MetaLoaderResultKeys).forEach((key) => {
if (loaderDatas == null ? void 0 : loaderDatas[key])
result[key] = loaderDatas[key];
});
return result;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
createAppRootElement,
createMarkupGenerator,

@@ -335,0 +530,0 @@ createUmiHandler,

@@ -0,1 +1,27 @@

export interface IOpts {
base: string;
routes: Record<string, {
path: string;
file: string;
id: string;
parentId?: string;
}>;
links?: Record<string, string>[];
metas?: Record<string, string>[];
styles?: (Record<string, string> | string)[];
favicons?: string[];
title?: string;
headScripts?: (Record<string, string> | string)[];
scripts?: (Record<string, string> | string)[];
mountElementId?: string;
esmScript?: boolean;
modifyHTML?: (html: string, args: {
path?: string;
}) => Promise<string>;
historyType?: 'hash' | 'browser';
}
export declare type IUserExtraRoute = string | {
path: string;
prerender: boolean;
};
export interface IRoute {

@@ -33,3 +59,11 @@ id: string;

}
export interface IhtmlPageOpts extends IMetadata {
headScripts?: (Record<string, string> | string)[];
links?: Record<string, string>[];
styles?: string[];
favicons?: string[];
scripts?: (Record<string, string> | string)[];
[key: string]: any;
}
export declare type MetadataLoader<T = any> = (serverLoaderData: T, req?: IServerLoaderArgs) => LoaderReturn<IMetadata>;
export {};
{
"name": "@umijs/server",
"version": "4.0.0-canary.20240626.1",
"version": "4.0.0-canary.20240702.1",
"description": "@umijs/server",

@@ -19,6 +19,6 @@ "homepage": "https://github.com/umijs/umi/tree/master/packages/server#readme",

"history": "5.3.0",
"react": "18.1.0",
"react-dom": "18.1.0",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-router-dom": "6.3.0",
"@umijs/bundler-utils": "4.0.0-canary.20240626.1"
"@umijs/bundler-utils": "4.0.0-canary.20240702.1"
},

@@ -25,0 +25,0 @@ "publishConfig": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc