Compare commits
7 commits
canary
...
lift-unive
Author | SHA1 | Date | |
---|---|---|---|
|
51f0f6e5c3 | ||
|
1b33835b14 | ||
|
03eba8f996 | ||
|
1fa178b627 | ||
|
127fccb133 | ||
|
849568cc14 | ||
|
001664e3bc |
38 changed files with 1910 additions and 190 deletions
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next",
|
"dev": "RSPACK_CONFIG_VALIDATE=loose-silent next",
|
||||||
"build": "next build",
|
"build": "cross-env RSPACK_CONFIG_VALIDATE=loose-silent NEXT_TELEMETRY_DISABLED=1 node --trace-deprecation --enable-source-maps ../../packages/next/dist/bin/next build",
|
||||||
"start": "next start"
|
"start": "next start"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next",
|
"dev": "RSPACK_CONFIG_VALIDATE=loose-silent next",
|
||||||
"build": "next build",
|
"build": "cross-env RSPACK_CONFIG_VALIDATE=loose-silent NEXT_TELEMETRY_DISABLED=1 node --trace-deprecation --enable-source-maps ../../packages/next/dist/bin/next build",
|
||||||
"start": "serve out"
|
"start": "serve out"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
77
examples/federation-single-app/components/SharedNav.tsx
Normal file
77
examples/federation-single-app/components/SharedNav.tsx
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
import React from "react";
|
||||||
|
import { Menu, Layout } from "antd";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import "./menu";
|
||||||
|
|
||||||
|
const SharedNav = () => {
|
||||||
|
const { asPath, push } = useRouter();
|
||||||
|
let activeMenu;
|
||||||
|
|
||||||
|
if (asPath === "/" || asPath.startsWith("/home")) {
|
||||||
|
activeMenu = "/";
|
||||||
|
} else if (asPath.startsWith("/shop")) {
|
||||||
|
activeMenu = "/shop";
|
||||||
|
} else if (asPath.startsWith("/checkout")) {
|
||||||
|
activeMenu = "/checkout";
|
||||||
|
}
|
||||||
|
|
||||||
|
const menuItems = [
|
||||||
|
{
|
||||||
|
className: "home-menu-link",
|
||||||
|
label: (
|
||||||
|
<>
|
||||||
|
Home <sup>3000</sup>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
key: "/",
|
||||||
|
onMouseEnter: () => {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
className: "shop-menu-link",
|
||||||
|
label: (
|
||||||
|
<>
|
||||||
|
Shop <sup>3001</sup>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
key: "/shop",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
className: "checkout-menu-link",
|
||||||
|
label: (
|
||||||
|
<>
|
||||||
|
Checkout <sup>3002</sup>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
key: "/checkout",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Layout.Header>
|
||||||
|
<div className="header-logo">nextjs-mf</div>
|
||||||
|
<Menu
|
||||||
|
theme="dark"
|
||||||
|
mode="horizontal"
|
||||||
|
selectedKeys={activeMenu ? [activeMenu] : undefined}
|
||||||
|
onClick={({ key }) => {
|
||||||
|
push(key);
|
||||||
|
}}
|
||||||
|
items={menuItems}
|
||||||
|
/>
|
||||||
|
<style jsx>
|
||||||
|
{`
|
||||||
|
.header-logo {
|
||||||
|
float: left;
|
||||||
|
width: 200px;
|
||||||
|
height: 31px;
|
||||||
|
margin-right: 24px;
|
||||||
|
color: white;
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
</style>
|
||||||
|
</Layout.Header>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SharedNav;
|
37
examples/federation-single-app/components/menu.tsx
Normal file
37
examples/federation-single-app/components/menu.tsx
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import type { ItemType } from "antd/es/menu/interface";
|
||||||
|
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import { Menu } from "antd";
|
||||||
|
|
||||||
|
const menuItems: ItemType[] = [
|
||||||
|
{ label: "Main home", key: "/" },
|
||||||
|
{ label: "Test hook from remote", key: "/home/test-remote-hook" },
|
||||||
|
{ label: "Test broken remotes", key: "/home/test-broken-remotes" },
|
||||||
|
{ label: "Exposed pages", key: "/home/exposed-pages" },
|
||||||
|
{
|
||||||
|
label: "Exposed components",
|
||||||
|
type: "group",
|
||||||
|
children: [{ label: "home/SharedNav", key: "/home/test-shared-nav" }],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function AppMenu() {
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
style={{ padding: "10px", fontWeight: 600, backgroundColor: "#fff" }}
|
||||||
|
>
|
||||||
|
Home App Menu
|
||||||
|
</div>
|
||||||
|
<Menu
|
||||||
|
mode="inline"
|
||||||
|
selectedKeys={[router.asPath]}
|
||||||
|
style={{ height: "100%" }}
|
||||||
|
onClick={({ key }) => router.push(key)}
|
||||||
|
items={menuItems}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
.tjhin {
|
||||||
|
display: flex;
|
||||||
|
}
|
5
examples/federation-single-app/next-env.d.ts
vendored
Normal file
5
examples/federation-single-app/next-env.d.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
/// <reference types="next" />
|
||||||
|
/// <reference types="next/image-types/global" />
|
||||||
|
|
||||||
|
// NOTE: This file should not be edited
|
||||||
|
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
13
examples/federation-single-app/next.config.js
Normal file
13
examples/federation-single-app/next.config.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
const nextConfig = {
|
||||||
|
webpack(config, options) {
|
||||||
|
config.plugins.push({
|
||||||
|
name: "xxx",
|
||||||
|
apply(compiler) {
|
||||||
|
compiler.options.devtool = false;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = nextConfig;
|
29
examples/federation-single-app/package.json
Normal file
29
examples/federation-single-app/package.json
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"name": "@module-federation/3000-home",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"next": "latest",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
|
"antd": "5.19.1",
|
||||||
|
"@ant-design/cssinjs": "^1.21.0",
|
||||||
|
"buffer": "5.7.1",
|
||||||
|
"encoding": "0.1.13",
|
||||||
|
"eslint-scope": "7.2.2",
|
||||||
|
"events": "3.3.0",
|
||||||
|
"js-cookie": "3.0.5",
|
||||||
|
"lodash": "4.17.21",
|
||||||
|
"node-fetch": "2.7.0",
|
||||||
|
"schema-utils": "3.3.0",
|
||||||
|
"terser-webpack-plugin": "5.3.10",
|
||||||
|
"typescript": "5.3.3",
|
||||||
|
"upath": "2.0.1",
|
||||||
|
"url": "0.11.3",
|
||||||
|
"util": "0.12.5"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"dev": "RSPACK_CONFIG_VALIDATE=loose-silent next",
|
||||||
|
"build": "cross-env RSPACK_CONFIG_VALIDATE=loose-silent NEXT_TELEMETRY_DISABLED=1 node --trace-deprecation --enable-source-maps ../../packages/next/dist/bin/next build"
|
||||||
|
}
|
||||||
|
}
|
70
examples/federation-single-app/pages/_app.tsx
Normal file
70
examples/federation-single-app/pages/_app.tsx
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import { useState } from "react";
|
||||||
|
import App from "next/app";
|
||||||
|
import { Layout, version, ConfigProvider } from "antd";
|
||||||
|
import { StyleProvider } from "@ant-design/cssinjs";
|
||||||
|
import Router, { useRouter } from "next/router";
|
||||||
|
|
||||||
|
const SharedNav = React.lazy(() => import("../components/SharedNav"));
|
||||||
|
import HostAppMenu from "../components/menu";
|
||||||
|
function MyApp(props) {
|
||||||
|
const { Component, pageProps } = props;
|
||||||
|
const { asPath } = useRouter();
|
||||||
|
const [MenuComponent, setMenuComponent] = useState(() => HostAppMenu);
|
||||||
|
const handleRouteChange = async (url) => {
|
||||||
|
if (url.startsWith("/shop")) {
|
||||||
|
} else if (url.startsWith("/checkout")) {
|
||||||
|
} else {
|
||||||
|
setMenuComponent(() => HostAppMenu);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// handle first route hit.
|
||||||
|
React.useEffect(() => {
|
||||||
|
handleRouteChange(asPath);
|
||||||
|
}, [asPath]);
|
||||||
|
|
||||||
|
//handle route change
|
||||||
|
React.useEffect(() => {
|
||||||
|
// Step 3: Subscribe on events
|
||||||
|
Router.events.on("routeChangeStart", handleRouteChange);
|
||||||
|
return () => {
|
||||||
|
Router.events.off("routeChangeStart", handleRouteChange);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<StyleProvider layer>
|
||||||
|
<ConfigProvider theme={{ hashed: false }}>
|
||||||
|
<Layout style={{ minHeight: "100vh" }} prefixCls={"dd"}>
|
||||||
|
<React.Suspense>
|
||||||
|
<SharedNav />
|
||||||
|
</React.Suspense>
|
||||||
|
<Layout>
|
||||||
|
<Layout.Sider width={200}>
|
||||||
|
<MenuComponent />
|
||||||
|
</Layout.Sider>
|
||||||
|
<Layout>
|
||||||
|
<Layout.Content style={{ background: "#fff", padding: 20 }}>
|
||||||
|
<Component {...pageProps} />
|
||||||
|
</Layout.Content>
|
||||||
|
<Layout.Footer
|
||||||
|
style={{
|
||||||
|
background: "#fff",
|
||||||
|
color: "#999",
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
antd@{version}
|
||||||
|
</Layout.Footer>
|
||||||
|
</Layout>
|
||||||
|
</Layout>
|
||||||
|
</Layout>
|
||||||
|
</ConfigProvider>
|
||||||
|
</StyleProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
MyApp.getInitialProps = async (ctx) => {
|
||||||
|
return App.getInitialProps(ctx);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MyApp;
|
26
examples/federation-single-app/pages/_document.js
Normal file
26
examples/federation-single-app/pages/_document.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import React from "react";
|
||||||
|
import Document, { Html, Head, Main, NextScript } from "next/document";
|
||||||
|
|
||||||
|
class MyDocument extends Document {
|
||||||
|
static async getInitialProps(ctx) {
|
||||||
|
const initialProps = await Document.getInitialProps(ctx);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...initialProps,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Html>
|
||||||
|
<Head />
|
||||||
|
<body>
|
||||||
|
<Main />
|
||||||
|
<NextScript />
|
||||||
|
</body>
|
||||||
|
</Html>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MyDocument;
|
3
examples/federation-single-app/pages/api/test.js
Normal file
3
examples/federation-single-app/pages/api/test.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export default function handler(req, res) {
|
||||||
|
res.status(200).json({ name: "John Doe" });
|
||||||
|
}
|
19
examples/federation-single-app/pages/home/exposed-pages.tsx
Normal file
19
examples/federation-single-app/pages/home/exposed-pages.tsx
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/* eslint-disable */
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
export default function ExposedPages() {
|
||||||
|
const [pageMap] = useState("");
|
||||||
|
const [pageMapV2] = useState("");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h1>This app exposes the following pages:</h1>
|
||||||
|
|
||||||
|
<h2>./pages-map</h2>
|
||||||
|
<pre>{JSON.stringify(pageMap, undefined, 2)}</pre>
|
||||||
|
|
||||||
|
<h2>./pages-map-v2</h2>
|
||||||
|
<pre>{JSON.stringify(pageMapV2, undefined, 2)}</pre>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/* eslint-disable */
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
export default function TestBrokenRemotes() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>This page is a test for broken remoteEntries.js</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Check unresolved host –{" "}
|
||||||
|
<Link href="/unresolved-host">/unresolved-host</Link> (on
|
||||||
|
http://localhost:<b>3333</b>/_next/static/chunks/remoteEntry.js)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Check wrong response for remoteEntry –{" "}
|
||||||
|
<Link href="/wrong-entry">/wrong-entry</Link> (on
|
||||||
|
http://localhost:3000/_next/static/chunks/remoteEntry<b>Wrong</b>
|
||||||
|
.js)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { NextPage } from "next";
|
||||||
|
|
||||||
|
const TestRemoteHook: NextPage = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
Page with custom remote hook. You must see text in red box below:
|
||||||
|
</div>
|
||||||
|
<div style={{ border: "1px solid red", padding: 5 }}>
|
||||||
|
blank text for now
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TestRemoteHook;
|
|
@ -0,0 +1,9 @@
|
||||||
|
import SharedNav from "../../components/SharedNav";
|
||||||
|
|
||||||
|
export default function TestSharedNav() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<SharedNav />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
139
examples/federation-single-app/pages/index.tsx
Normal file
139
examples/federation-single-app/pages/index.tsx
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
/* eslint-disable */
|
||||||
|
import React from "react";
|
||||||
|
import Head from "next/head";
|
||||||
|
|
||||||
|
const Home = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Head>
|
||||||
|
<title>Home</title>
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
</Head>
|
||||||
|
|
||||||
|
<h1 style={{ fontSize: "2em" }}>
|
||||||
|
This is SPA combined from 3 different nextjs applications.
|
||||||
|
</h1>
|
||||||
|
<p className="description">
|
||||||
|
They utilize omnidirectional routing and pages or components are able to
|
||||||
|
be federated between applications.
|
||||||
|
</p>
|
||||||
|
<p>You may open any application by clicking on the links below:</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="#reloadPage"
|
||||||
|
onClick={() => (window.location.href = "http://localhost:3000")}
|
||||||
|
>
|
||||||
|
localhost:3000
|
||||||
|
</a>
|
||||||
|
{" – "}
|
||||||
|
<b>home</b>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="#reloadPage"
|
||||||
|
onClick={() => (window.location.href = "http://localhost:3001")}
|
||||||
|
>
|
||||||
|
localhost:3001
|
||||||
|
</a>
|
||||||
|
{" – "}
|
||||||
|
<b>shop</b>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="#reloadPage"
|
||||||
|
onClick={() => (window.location.href = "http://localhost:3002")}
|
||||||
|
>
|
||||||
|
localhost:3002
|
||||||
|
</a>
|
||||||
|
{" – "}
|
||||||
|
<b>checkout</b>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h2 style={{ marginTop: "30px" }}>Federation test cases</h2>
|
||||||
|
<table border={1} cellPadding={5}>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>Test case</td>
|
||||||
|
<td>Expected</td>
|
||||||
|
<td>Actual</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>
|
||||||
|
Loading remote component (CheckoutTitle) from localhost:3002
|
||||||
|
<br />
|
||||||
|
<blockquote>
|
||||||
|
lazy(()=>import('checkout/CheckoutTitle'))
|
||||||
|
</blockquote>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<h3>This title came from checkout with hooks data!!!</h3>
|
||||||
|
</td>
|
||||||
|
<td>old</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>
|
||||||
|
Load federated component from checkout with old antd version
|
||||||
|
</td>
|
||||||
|
<td>[Button from antd@5.18.3]</td>
|
||||||
|
<td>test</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>
|
||||||
|
Loading remote component with PNG image from localhost:3001
|
||||||
|
<br />
|
||||||
|
<blockquote>(check publicPath fix in image-loader)</blockquote>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<img className="home-webpack-png" src="./webpack.png" />
|
||||||
|
</td>
|
||||||
|
<td>other thing</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>✅</td>
|
||||||
|
<td>
|
||||||
|
Loading remote component with SVG from localhost:3001
|
||||||
|
<br />
|
||||||
|
<blockquote>(check publicPath fix in url-loader)</blockquote>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<img src="./webpack.svg" />
|
||||||
|
</td>
|
||||||
|
<td>anothaaaaaa</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2 style={{ marginTop: "30px" }}>Other problems to fix:</h2>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
🐞 Incorrectly exposed modules in next.config.js (e.g. typo in path)
|
||||||
|
do not throw an error in console
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
📝 Try to introduce a remote entry loading according to prefix path.
|
||||||
|
It will be nice runtime improvement if you have eg 20 apps and load
|
||||||
|
just one remoteEntry instead of all of them.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
📝 It will be nice to regenerate remoteEntry if new page was added in
|
||||||
|
remote app.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
📝 Remote components do not regenerate chunks if they were changed.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
Home.getInitialProps = () => {
|
||||||
|
console.log("home calls get initial props");
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
export default Home;
|
0
examples/federation-single-app/public/.gitkeep
Normal file
0
examples/federation-single-app/public/.gitkeep
Normal file
BIN
examples/federation-single-app/public/favicon.ico
Normal file
BIN
examples/federation-single-app/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
examples/federation-single-app/public/webpack.png
Normal file
BIN
examples/federation-single-app/public/webpack.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
5
examples/federation-single-app/public/webpack.svg
Normal file
5
examples/federation-single-app/public/webpack.svg
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<svg viewBox="0 0 3046.7 875.7" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m387 0 387 218.9v437.9l-387 218.9-387-218.9v-437.9z" fill="#fff"/>
|
||||||
|
<path d="m704.9 641.7-305.1 172.6v-134.4l190.1-104.6zm20.9-18.9v-360.9l-111.6 64.5v232zm-657.9 18.9 305.1 172.6v-134.4l-190.2-104.6zm-20.9-18.9v-360.9l111.6 64.5v232zm13.1-384.3 312.9-177v129.9l-200.5 110.3-1.6.9zm652.6 0-312.9-177v129.9l200.5 110.2 1.6.9z" fill="#8ed6fb"/>
|
||||||
|
<path d="m373 649.3-187.6-103.2v-204.3l187.6 108.3zm26.8 0 187.6-103.1v-204.4l-187.6 108.3zm-201.7-331.1 188.3-103.5 188.3 103.5-188.3 108.7z" fill="#1c78c0"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 592 B |
5
examples/federation-single-app/remotes.d.ts
vendored
Normal file
5
examples/federation-single-app/remotes.d.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
declare module "shop/useCustomRemoteHook";
|
||||||
|
declare module "shop/WebpackSvg";
|
||||||
|
declare module "shop/WebpackPng";
|
||||||
|
declare module "checkout/CheckoutTitle";
|
||||||
|
declare module "checkout/ButtonOldAnt";
|
20
examples/federation-single-app/tsconfig.json
Normal file
20
examples/federation-single-app/tsconfig.json
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": false,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"incremental": true
|
||||||
|
},
|
||||||
|
"include": ["next-env.d.ts", "environment.d.ts", "**/*.ts", "**/*.tsx"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import css from "./hello-world.module.css";
|
import css from "./hello-world.module.css";
|
||||||
|
console.log('css:',css);
|
||||||
export default function HelloWorld() {
|
export default function HelloWorld() {
|
||||||
return (
|
return (
|
||||||
<div className={css.hello}>
|
<div className={css.hello}>
|
||||||
|
|
|
@ -99,6 +99,7 @@
|
||||||
"caniuse-lite": "^1.0.30001579",
|
"caniuse-lite": "^1.0.30001579",
|
||||||
"graceful-fs": "^4.2.11",
|
"graceful-fs": "^4.2.11",
|
||||||
"postcss": "8.4.31",
|
"postcss": "8.4.31",
|
||||||
|
"source-map-support": "0.5.21",
|
||||||
"styled-jsx": "5.1.6"
|
"styled-jsx": "5.1.6"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
@ -163,6 +164,7 @@
|
||||||
"@next/swc": "15.0.0-canary.56",
|
"@next/swc": "15.0.0-canary.56",
|
||||||
"@opentelemetry/api": "1.6.0",
|
"@opentelemetry/api": "1.6.0",
|
||||||
"@playwright/test": "1.41.2",
|
"@playwright/test": "1.41.2",
|
||||||
|
"@rspack/core": "alpha",
|
||||||
"@swc/core": "1.6.6",
|
"@swc/core": "1.6.6",
|
||||||
"@swc/types": "0.1.7",
|
"@swc/types": "0.1.7",
|
||||||
"@taskr/clear": "1.1.0",
|
"@taskr/clear": "1.1.0",
|
||||||
|
|
|
@ -922,8 +922,9 @@ export default async function getBaseWebpackConfig(
|
||||||
context,
|
context,
|
||||||
request,
|
request,
|
||||||
dependencyType,
|
dependencyType,
|
||||||
contextInfo.issuerLayer as WebpackLayerName,
|
contextInfo?.issuerLayer as WebpackLayerName,
|
||||||
(options) => {
|
(options) => {
|
||||||
|
return true as any;
|
||||||
const resolveFunction = getResolve(options)
|
const resolveFunction = getResolve(options)
|
||||||
return (resolveContext: string, requestToResolve: string) =>
|
return (resolveContext: string, requestToResolve: string) =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
|
@ -1037,7 +1038,6 @@ export default async function getBaseWebpackConfig(
|
||||||
}): boolean {
|
}): boolean {
|
||||||
return (
|
return (
|
||||||
!module.type?.startsWith('css') &&
|
!module.type?.startsWith('css') &&
|
||||||
module.size() > 160000 &&
|
|
||||||
/node_modules[/\\]/.test(module.nameForCondition() || '')
|
/node_modules[/\\]/.test(module.nameForCondition() || '')
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
@ -1104,35 +1104,35 @@ export default async function getBaseWebpackConfig(
|
||||||
const {
|
const {
|
||||||
TerserPlugin,
|
TerserPlugin,
|
||||||
} = require('./webpack/plugins/terser-webpack-plugin/src/index.js')
|
} = require('./webpack/plugins/terser-webpack-plugin/src/index.js')
|
||||||
new TerserPlugin({
|
// new TerserPlugin({
|
||||||
terserOptions: {
|
// terserOptions: {
|
||||||
...terserOptions,
|
// ...terserOptions,
|
||||||
compress: {
|
// compress: {
|
||||||
...terserOptions.compress,
|
// ...terserOptions.compress,
|
||||||
},
|
// },
|
||||||
mangle: {
|
// mangle: {
|
||||||
...terserOptions.mangle,
|
// ...terserOptions.mangle,
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
}).apply(compiler)
|
// }).apply(compiler)
|
||||||
},
|
},
|
||||||
// Minify CSS
|
// Minify CSS
|
||||||
(compiler: webpack.Compiler) => {
|
(compiler: webpack.Compiler) => {
|
||||||
const {
|
const {
|
||||||
CssMinimizerPlugin,
|
CssMinimizerPlugin,
|
||||||
} = require('./webpack/plugins/css-minimizer-plugin')
|
} = require('./webpack/plugins/css-minimizer-plugin')
|
||||||
new CssMinimizerPlugin({
|
// new CssMinimizerPlugin({
|
||||||
postcssOptions: {
|
// postcssOptions: {
|
||||||
map: {
|
// map: {
|
||||||
// `inline: false` generates the source map in a separate file.
|
// // `inline: false` generates the source map in a separate file.
|
||||||
// Otherwise, the CSS file is needlessly large.
|
// // Otherwise, the CSS file is needlessly large.
|
||||||
inline: false,
|
// inline: false,
|
||||||
// `annotation: false` skips appending the `sourceMappingURL`
|
// // `annotation: false` skips appending the `sourceMappingURL`
|
||||||
// to the end of the CSS file. Webpack already handles this.
|
// // to the end of the CSS file. Webpack already handles this.
|
||||||
annotation: false,
|
// annotation: false,
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
}).apply(compiler)
|
// }).apply(compiler)
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -1740,7 +1740,7 @@ export default async function getBaseWebpackConfig(
|
||||||
resource.request,
|
resource.request,
|
||||||
'.shared-runtime'
|
'.shared-runtime'
|
||||||
)
|
)
|
||||||
const layer = resource.contextInfo.issuerLayer
|
const layer = 'pages' as string
|
||||||
let runtime
|
let runtime
|
||||||
|
|
||||||
switch (layer) {
|
switch (layer) {
|
||||||
|
@ -1757,7 +1757,7 @@ export default async function getBaseWebpackConfig(
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
dev && new MemoryWithGcCachePlugin({ maxGenerations: 5 }),
|
dev && new MemoryWithGcCachePlugin({ maxGenerations: 5 }),
|
||||||
dev && isClient && new ReactRefreshWebpackPlugin(webpack),
|
// dev && isClient && new ReactRefreshWebpackPlugin(webpack),
|
||||||
// Makes sure `Buffer` and `process` are polyfilled in client and flight bundles (same behavior as webpack 4)
|
// Makes sure `Buffer` and `process` are polyfilled in client and flight bundles (same behavior as webpack 4)
|
||||||
(isClient || isEdgeServer) &&
|
(isClient || isEdgeServer) &&
|
||||||
new webpack.ProvidePlugin({
|
new webpack.ProvidePlugin({
|
||||||
|
@ -1788,7 +1788,7 @@ export default async function getBaseWebpackConfig(
|
||||||
runtimeAsset: `server/${MIDDLEWARE_REACT_LOADABLE_MANIFEST}.js`,
|
runtimeAsset: `server/${MIDDLEWARE_REACT_LOADABLE_MANIFEST}.js`,
|
||||||
dev,
|
dev,
|
||||||
}),
|
}),
|
||||||
(isClient || isEdgeServer) && new DropClientPage(),
|
// (isClient || isEdgeServer) && new DropClientPage(),
|
||||||
isNodeServer &&
|
isNodeServer &&
|
||||||
!dev &&
|
!dev &&
|
||||||
new (require('./webpack/plugins/next-trace-entrypoints-plugin')
|
new (require('./webpack/plugins/next-trace-entrypoints-plugin')
|
||||||
|
@ -1823,9 +1823,9 @@ export default async function getBaseWebpackConfig(
|
||||||
const { NextJsRequireCacheHotReloader } =
|
const { NextJsRequireCacheHotReloader } =
|
||||||
require('./webpack/plugins/nextjs-require-cache-hot-reloader') as typeof import('./webpack/plugins/nextjs-require-cache-hot-reloader')
|
require('./webpack/plugins/nextjs-require-cache-hot-reloader') as typeof import('./webpack/plugins/nextjs-require-cache-hot-reloader')
|
||||||
const devPlugins: any[] = [
|
const devPlugins: any[] = [
|
||||||
new NextJsRequireCacheHotReloader({
|
// new NextJsRequireCacheHotReloader({
|
||||||
serverComponents: hasAppDir,
|
// serverComponents: hasAppDir,
|
||||||
}),
|
// }),
|
||||||
]
|
]
|
||||||
|
|
||||||
if (isClient || isEdgeServer) {
|
if (isClient || isEdgeServer) {
|
||||||
|
@ -1876,11 +1876,11 @@ export default async function getBaseWebpackConfig(
|
||||||
require('./webpack/plugins/font-stylesheet-gathering-plugin') as {
|
require('./webpack/plugins/font-stylesheet-gathering-plugin') as {
|
||||||
FontStylesheetGatheringPlugin: typeof import('./webpack/plugins/font-stylesheet-gathering-plugin').FontStylesheetGatheringPlugin
|
FontStylesheetGatheringPlugin: typeof import('./webpack/plugins/font-stylesheet-gathering-plugin').FontStylesheetGatheringPlugin
|
||||||
}
|
}
|
||||||
return new FontStylesheetGatheringPlugin({
|
// return new FontStylesheetGatheringPlugin({
|
||||||
adjustFontFallbacks: config.experimental.adjustFontFallbacks,
|
// adjustFontFallbacks: config.experimental.adjustFontFallbacks,
|
||||||
adjustFontFallbacksWithSizeAdjust:
|
// adjustFontFallbacksWithSizeAdjust:
|
||||||
config.experimental.adjustFontFallbacksWithSizeAdjust,
|
// config.experimental.adjustFontFallbacksWithSizeAdjust,
|
||||||
})
|
// })
|
||||||
})(),
|
})(),
|
||||||
new WellKnownErrorsPlugin(),
|
new WellKnownErrorsPlugin(),
|
||||||
isClient &&
|
isClient &&
|
||||||
|
@ -1929,9 +1929,9 @@ export default async function getBaseWebpackConfig(
|
||||||
new NextFontManifestPlugin({
|
new NextFontManifestPlugin({
|
||||||
appDir,
|
appDir,
|
||||||
}),
|
}),
|
||||||
!dev &&
|
// !dev &&
|
||||||
isClient &&
|
// isClient &&
|
||||||
new CssChunkingPlugin(config.experimental.cssChunking === 'strict'),
|
// new CssChunkingPlugin(config.experimental.cssChunking === 'strict'),
|
||||||
!dev &&
|
!dev &&
|
||||||
isClient &&
|
isClient &&
|
||||||
new (require('./webpack/plugins/telemetry-plugin').TelemetryPlugin)(
|
new (require('./webpack/plugins/telemetry-plugin').TelemetryPlugin)(
|
||||||
|
@ -2266,22 +2266,22 @@ export default async function getBaseWebpackConfig(
|
||||||
const webpack5Config = webpackConfig as webpack.Configuration
|
const webpack5Config = webpackConfig as webpack.Configuration
|
||||||
|
|
||||||
// disable lazy compilation of entries as next.js has it's own method here
|
// disable lazy compilation of entries as next.js has it's own method here
|
||||||
if (webpack5Config.experiments?.lazyCompilation === true) {
|
// if (webpack5Config.experiments?.lazyCompilation === true) {
|
||||||
webpack5Config.experiments.lazyCompilation = {
|
// webpack5Config.experiments.lazyCompilation = {
|
||||||
entries: false,
|
// entries: false,
|
||||||
}
|
// }
|
||||||
} else if (
|
// } else if (
|
||||||
typeof webpack5Config.experiments?.lazyCompilation === 'object' &&
|
// typeof webpack5Config.experiments?.lazyCompilation === 'object' &&
|
||||||
webpack5Config.experiments.lazyCompilation.entries !== false
|
// webpack5Config.experiments.lazyCompilation.entries !== false
|
||||||
) {
|
// ) {
|
||||||
webpack5Config.experiments.lazyCompilation.entries = false
|
// webpack5Config.experiments.lazyCompilation.entries = false
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (typeof (webpackConfig as any).then === 'function') {
|
// if (typeof (webpackConfig as any).then === 'function') {
|
||||||
console.warn(
|
// console.warn(
|
||||||
'> Promise returned in next config. https://nextjs.org/docs/messages/promise-in-next-config'
|
// '> Promise returned in next config. https://nextjs.org/docs/messages/promise-in-next-config'
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
const rules = webpackConfig.module?.rules || []
|
const rules = webpackConfig.module?.rules || []
|
||||||
|
|
|
@ -591,7 +591,7 @@ export const css = curry(async function css(
|
||||||
if (ctx.isClient && (ctx.isProduction || ctx.hasAppDir)) {
|
if (ctx.isClient && (ctx.isProduction || ctx.hasAppDir)) {
|
||||||
// Extract CSS as CSS file(s) in the client-side production bundle.
|
// Extract CSS as CSS file(s) in the client-side production bundle.
|
||||||
const MiniCssExtractPlugin =
|
const MiniCssExtractPlugin =
|
||||||
require('../../../plugins/mini-css-extract-plugin').default
|
require('@rspack/core').CssExtractRspackPlugin;
|
||||||
fns.push(
|
fns.push(
|
||||||
plugin(
|
plugin(
|
||||||
// @ts-ignore webpack 5 compat
|
// @ts-ignore webpack 5 compat
|
||||||
|
|
|
@ -33,7 +33,7 @@ export function isCSSMod(mod: {
|
||||||
mod.loaders?.some(
|
mod.loaders?.some(
|
||||||
({ loader }) =>
|
({ loader }) =>
|
||||||
loader.includes('next-style-loader/index.js') ||
|
loader.includes('next-style-loader/index.js') ||
|
||||||
loader.includes('mini-css-extract-plugin/loader.js') ||
|
loader.includes('rspack.CssExtractRspackPlugin.loader') ||
|
||||||
loader.includes('@vanilla-extract/webpack-plugin/loader/')
|
loader.includes('@vanilla-extract/webpack-plugin/loader/')
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -568,7 +568,7 @@ function getExtractMetadata(params: {
|
||||||
metadataByEntry.clear()
|
metadataByEntry.clear()
|
||||||
const telemetry: Telemetry | undefined = traceGlobals.get('telemetry')
|
const telemetry: Telemetry | undefined = traceGlobals.get('telemetry')
|
||||||
|
|
||||||
for (const [entryName, entry] of compilation.entries) {
|
for (const [entryName, entry] of compilation.entries ?? []) {
|
||||||
if (entry.options.runtime !== EDGE_RUNTIME_WEBPACK) {
|
if (entry.options.runtime !== EDGE_RUNTIME_WEBPACK) {
|
||||||
// Only process edge runtime entries
|
// Only process edge runtime entries
|
||||||
continue
|
continue
|
||||||
|
@ -782,9 +782,9 @@ export default class MiddlewarePlugin {
|
||||||
compiler,
|
compiler,
|
||||||
compilation,
|
compilation,
|
||||||
})
|
})
|
||||||
hooks.parser.for('javascript/auto').tap(NAME, codeAnalyzer)
|
// hooks.parser.for('javascript/auto').tap(NAME, codeAnalyzer)
|
||||||
hooks.parser.for('javascript/dynamic').tap(NAME, codeAnalyzer)
|
// hooks.parser.for('javascript/dynamic').tap(NAME, codeAnalyzer)
|
||||||
hooks.parser.for('javascript/esm').tap(NAME, codeAnalyzer)
|
// hooks.parser.for('javascript/esm').tap(NAME, codeAnalyzer)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract all metadata for the entry points in a Map object.
|
* Extract all metadata for the entry points in a Map object.
|
||||||
|
|
|
@ -677,6 +677,7 @@ export class TraceEntryPointsPlugin implements webpack.WebpackPluginInstance {
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(compiler: webpack.Compiler) {
|
apply(compiler: webpack.Compiler) {
|
||||||
|
return;
|
||||||
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
||||||
const readlink = async (path: string): Promise<string | null> => {
|
const readlink = async (path: string): Promise<string | null> => {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -63,7 +63,7 @@ export class ProfilingPlugin {
|
||||||
} = {}
|
} = {}
|
||||||
) {
|
) {
|
||||||
let span: Span | undefined
|
let span: Span | undefined
|
||||||
startHook.tap(
|
startHook?.tap(
|
||||||
{ name: pluginName, stage: -Infinity },
|
{ name: pluginName, stage: -Infinity },
|
||||||
(...params: any[]) => {
|
(...params: any[]) => {
|
||||||
const name = typeof spanName === 'function' ? spanName() : spanName
|
const name = typeof spanName === 'function' ? spanName() : spanName
|
||||||
|
@ -75,7 +75,7 @@ export class ProfilingPlugin {
|
||||||
if (onStart) onStart(span, ...params)
|
if (onStart) onStart(span, ...params)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
stopHook.tap({ name: pluginName, stage: Infinity }, (...params: any[]) => {
|
stopHook?.tap({ name: pluginName, stage: Infinity }, (...params: any[]) => {
|
||||||
// `stopHook` may be triggered when `startHook` has not in cases
|
// `stopHook` may be triggered when `startHook` has not in cases
|
||||||
// where `stopHook` is used as the terminating event for more
|
// where `stopHook` is used as the terminating event for more
|
||||||
// than one pair of hooks.
|
// than one pair of hooks.
|
||||||
|
@ -149,54 +149,54 @@ export class ProfilingPlugin {
|
||||||
compiler.hooks.compilation.tap(
|
compiler.hooks.compilation.tap(
|
||||||
{ name: pluginName, stage: -Infinity },
|
{ name: pluginName, stage: -Infinity },
|
||||||
(compilation: any) => {
|
(compilation: any) => {
|
||||||
compilation.hooks.buildModule.tap(pluginName, (module: any) => {
|
// compilation.hooks.buildModule.tap(pluginName, (module: any) => {
|
||||||
const moduleType = (() => {
|
// const moduleType = (() => {
|
||||||
const r = module.userRequest
|
// const r = module.userRequest
|
||||||
if (!r || r.endsWith('!')) {
|
// if (!r || r.endsWith('!')) {
|
||||||
return ''
|
// return ''
|
||||||
} else {
|
// } else {
|
||||||
const resource = r.split('!').pop()
|
// const resource = r.split('!').pop()
|
||||||
const match = /^[^?]+\.([^?]+)$/.exec(resource)
|
// const match = /^[^?]+\.([^?]+)$/.exec(resource)
|
||||||
return match ? match[1] : ''
|
// return match ? match[1] : ''
|
||||||
}
|
// }
|
||||||
})()
|
// })()
|
||||||
|
|
||||||
const issuerModule = compilation?.moduleGraph?.getIssuer(module)
|
// const issuerModule = compilation?.moduleGraph?.getIssuer(module)
|
||||||
|
|
||||||
let span: Span
|
// let span: Span
|
||||||
|
|
||||||
const moduleSpans = moduleSpansByCompilation.get(compilation)
|
// const moduleSpans = moduleSpansByCompilation.get(compilation)
|
||||||
const spanName = `build-module${moduleType ? `-${moduleType}` : ''}`
|
// const spanName = `build-module${moduleType ? `-${moduleType}` : ''}`
|
||||||
const issuerSpan: Span | undefined =
|
// const issuerSpan: Span | undefined =
|
||||||
issuerModule && moduleSpans?.get(issuerModule)
|
// issuerModule && moduleSpans?.get(issuerModule)
|
||||||
if (issuerSpan) {
|
// if (issuerSpan) {
|
||||||
span = issuerSpan.traceChild(spanName)
|
// span = issuerSpan.traceChild(spanName)
|
||||||
} else {
|
// } else {
|
||||||
let parentSpan: Span | undefined
|
// let parentSpan: Span | undefined
|
||||||
for (const incomingConnection of compilation.moduleGraph.getIncomingConnections(
|
// for (const incomingConnection of compilation.moduleGraph?.getIncomingConnections(
|
||||||
module
|
// module
|
||||||
)) {
|
// )) {
|
||||||
const entrySpan = spans.get(incomingConnection.dependency)
|
// const entrySpan = spans.get(incomingConnection.dependency)
|
||||||
if (entrySpan) {
|
// if (entrySpan) {
|
||||||
parentSpan = entrySpan
|
// parentSpan = entrySpan
|
||||||
break
|
// break
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (!parentSpan) {
|
// if (!parentSpan) {
|
||||||
const compilationSpan = spans.get(compilation)
|
// const compilationSpan = spans.get(compilation)
|
||||||
if (!compilationSpan) {
|
// if (!compilationSpan) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
parentSpan = compilationSpan
|
// parentSpan = compilationSpan
|
||||||
}
|
// }
|
||||||
span = parentSpan.traceChild(spanName)
|
// span = parentSpan.traceChild(spanName)
|
||||||
}
|
// }
|
||||||
span.setAttribute('name', module.userRequest)
|
// span.setAttribute('name', module.userRequest)
|
||||||
span.setAttribute('layer', module.layer)
|
// span.setAttribute('layer', module.layer)
|
||||||
moduleSpans!.set(module, span)
|
// moduleSpans!.set(module, span)
|
||||||
})
|
// })
|
||||||
|
|
||||||
const moduleHooks = NormalModule.getCompilationHooks(compilation)
|
const moduleHooks = NormalModule.getCompilationHooks(compilation)
|
||||||
moduleHooks.readResource.for(undefined).intercept({
|
moduleHooks.readResource.for(undefined).intercept({
|
||||||
|
@ -214,17 +214,41 @@ export class ProfilingPlugin {
|
||||||
moduleHooks.loader.tap(
|
moduleHooks.loader.tap(
|
||||||
pluginName,
|
pluginName,
|
||||||
(loaderContext: any, module: any) => {
|
(loaderContext: any, module: any) => {
|
||||||
const moduleSpan = moduleSpansByCompilation
|
// const moduleSpan = moduleSpansByCompilation
|
||||||
.get(compilation)
|
// .get(compilation)
|
||||||
?.get(module)
|
// ?.get(module)
|
||||||
|
const moduleSpan = {
|
||||||
|
traceChild() {
|
||||||
|
return {
|
||||||
|
traceFn(fn: any) {
|
||||||
|
return fn();
|
||||||
|
},
|
||||||
|
traceAsyncFn(fn:any){
|
||||||
|
return fn();
|
||||||
|
},
|
||||||
|
setAttribute() {},
|
||||||
|
traceChild(){
|
||||||
|
return {
|
||||||
|
traceFn(fn: any) {
|
||||||
|
return fn();
|
||||||
|
},
|
||||||
|
traceAsyncFn(fn:any){
|
||||||
|
return fn();
|
||||||
|
},
|
||||||
|
setAttribute() {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
loaderContext.currentTraceSpan = moduleSpan
|
loaderContext.currentTraceSpan = moduleSpan
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
compilation.hooks.succeedModule.tap(pluginName, (module: any) => {
|
compilation.hooks.succeedModule?.tap(pluginName, (module: any) => {
|
||||||
moduleSpansByCompilation?.get(compilation)?.get(module)?.stop()
|
moduleSpansByCompilation?.get(compilation)?.get(module)?.stop()
|
||||||
})
|
})
|
||||||
compilation.hooks.failedModule.tap(pluginName, (module: any) => {
|
compilation.hooks.failedModule?.tap(pluginName, (module: any) => {
|
||||||
moduleSpansByCompilation?.get(compilation)?.get(module)?.stop()
|
moduleSpansByCompilation?.get(compilation)?.get(module)?.stop()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -243,7 +267,7 @@ export class ProfilingPlugin {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
compilation.hooks.addEntry.tap(pluginName, (entry: any) => {
|
compilation.hooks.addEntry?.tap(pluginName, (entry: any) => {
|
||||||
const parentSpan =
|
const parentSpan =
|
||||||
makeSpanByCompilation.get(compilation) || spans.get(compilation)
|
makeSpanByCompilation.get(compilation) || spans.get(compilation)
|
||||||
if (!parentSpan) {
|
if (!parentSpan) {
|
||||||
|
@ -254,11 +278,11 @@ export class ProfilingPlugin {
|
||||||
spans.set(entry, addEntrySpan)
|
spans.set(entry, addEntrySpan)
|
||||||
})
|
})
|
||||||
|
|
||||||
compilation.hooks.succeedEntry.tap(pluginName, (entry: any) => {
|
compilation.hooks.succeedEntry?.tap(pluginName, (entry: any) => {
|
||||||
spans.get(entry)?.stop()
|
spans.get(entry)?.stop()
|
||||||
spans.delete(entry)
|
spans.delete(entry)
|
||||||
})
|
})
|
||||||
compilation.hooks.failedEntry.tap(pluginName, (entry: any) => {
|
compilation.hooks.failedEntry?.tap(pluginName, (entry: any) => {
|
||||||
spans.get(entry)?.stop()
|
spans.get(entry)?.stop()
|
||||||
spans.delete(entry)
|
spans.delete(entry)
|
||||||
})
|
})
|
||||||
|
@ -355,31 +379,31 @@ export class ProfilingPlugin {
|
||||||
)
|
)
|
||||||
|
|
||||||
const logs = new Map()
|
const logs = new Map()
|
||||||
const originalTime = compilation.logger.time
|
const originalTime = compilation.logger?.time
|
||||||
const originalTimeEnd = compilation.logger.timeEnd
|
const originalTimeEnd = compilation.logger?.timeEnd
|
||||||
|
|
||||||
compilation.logger.time = (label: string) => {
|
// compilation.logger.time = (label: string) => {
|
||||||
if (!inTraceLabelsSeal(label)) {
|
// if (!inTraceLabelsSeal(label)) {
|
||||||
return originalTime.call(compilation.logger, label)
|
// return originalTime.call(compilation.logger, label)
|
||||||
}
|
// }
|
||||||
const span = sealSpanByCompilation.get(compilation)
|
// const span = sealSpanByCompilation.get(compilation)
|
||||||
if (span) {
|
// if (span) {
|
||||||
logs.set(label, span.traceChild(label.replace(/ /g, '-')))
|
// logs.set(label, span.traceChild(label.replace(/ /g, '-')))
|
||||||
}
|
// }
|
||||||
return originalTime.call(compilation.logger, label)
|
// return originalTime.call(compilation.logger, label)
|
||||||
}
|
// }
|
||||||
compilation.logger.timeEnd = (label: string) => {
|
// compilation.logger.timeEnd = (label: string) => {
|
||||||
if (!inTraceLabelsSeal(label)) {
|
// if (!inTraceLabelsSeal(label)) {
|
||||||
return originalTimeEnd.call(compilation.logger, label)
|
// return originalTimeEnd.call(compilation.logger, label)
|
||||||
}
|
// }
|
||||||
|
|
||||||
const span = logs.get(label)
|
// const span = logs.get(label)
|
||||||
if (span) {
|
// if (span) {
|
||||||
span.stop()
|
// span.stop()
|
||||||
logs.delete(label)
|
// logs.delete(label)
|
||||||
}
|
// }
|
||||||
return originalTimeEnd.call(compilation.logger, label)
|
// return originalTimeEnd.call(compilation.logger, label)
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,9 +134,9 @@ function buildManifest(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const module of compilation.modules) {
|
// for (const module of compilation.modules) {
|
||||||
module.blocks.forEach(handleBlock)
|
// module.blocks.forEach(handleBlock)
|
||||||
}
|
// }
|
||||||
|
|
||||||
manifest = Object.keys(manifest)
|
manifest = Object.keys(manifest)
|
||||||
.sort()
|
.sort()
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
require('source-map-support').install();
|
||||||
|
|
||||||
import '../server/lib/cpu-profile'
|
import '../server/lib/cpu-profile'
|
||||||
import { existsSync } from 'fs'
|
import { existsSync } from 'fs'
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
require('source-map-support').install();
|
||||||
|
|
||||||
import '../server/lib/cpu-profile'
|
import '../server/lib/cpu-profile'
|
||||||
import type { StartServerOptions } from '../server/lib/start-server'
|
import type { StartServerOptions } from '../server/lib/start-server'
|
||||||
|
|
|
@ -21,6 +21,7 @@ exports.init = function () {
|
||||||
webpack: require('webpack'),
|
webpack: require('webpack'),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Object.assign(exports, require('./bundle5')())
|
console.log('load rspack');
|
||||||
|
Object.assign(exports, require('@rspack/core'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -791,7 +791,7 @@ export default class NextNodeServer extends BaseServer<
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getFontManifest(): FontManifest {
|
protected getFontManifest(): FontManifest {
|
||||||
return requireFontManifest(this.distDir)
|
return requireFontManifest(this.distDir) as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getNextFontManifest(): NextFontManifest | undefined {
|
protected getNextFontManifest(): NextFontManifest | undefined {
|
||||||
|
|
|
@ -133,6 +133,7 @@ export async function requirePage(
|
||||||
|
|
||||||
export function requireFontManifest(distDir: string) {
|
export function requireFontManifest(distDir: string) {
|
||||||
const serverBuildPath = path.join(distDir, SERVER_DIRECTORY)
|
const serverBuildPath = path.join(distDir, SERVER_DIRECTORY)
|
||||||
|
return {} as FontManifest;
|
||||||
const fontManifest = loadManifest(
|
const fontManifest = loadManifest(
|
||||||
path.join(serverBuildPath, AUTOMATIC_FONT_OPTIMIZATION_MANIFEST)
|
path.join(serverBuildPath, AUTOMATIC_FONT_OPTIMIZATION_MANIFEST)
|
||||||
) as FontManifest
|
) as FontManifest
|
||||||
|
|
1277
pnpm-lock.yaml
1277
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -2,3 +2,5 @@ packages:
|
||||||
- 'packages/*'
|
- 'packages/*'
|
||||||
- 'bench/*'
|
- 'bench/*'
|
||||||
- 'packages/next-swc/crates/next-core/js'
|
- 'packages/next-swc/crates/next-core/js'
|
||||||
|
- 'examples/next-css'
|
||||||
|
- 'examples/federation-single-app'
|
||||||
|
|
Loading…
Reference in a new issue