Skip to content

Commit

Permalink
fix(enhanced): support get public path (#2638)
Browse files Browse the repository at this point in the history
Co-authored-by: ScriptedAlchemy <zackaryjackson@bytedance.com>
  • Loading branch information
ScriptedAlchemy and ScriptedAlchemy authored Jun 24, 2024
1 parent 6838379 commit 88445e7
Show file tree
Hide file tree
Showing 18 changed files with 176 additions and 33 deletions.
8 changes: 8 additions & 0 deletions .changeset/cold-rocks-listen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@module-federation/dts-plugin': patch
'@module-federation/enhanced': patch
'@module-federation/manifest': patch
'@module-federation/sdk': patch
---

Support getPublicPath in compiler plugins
9 changes: 6 additions & 3 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,17 @@ jobs:
- name: Check Code Format
run: npx nx format:check

- name: Run Affected Build
run: npx nx run-many --targets=build --projects=tag:type:pkg --skip-nx-cache
- name: Update NX Build Cache
run: npx nx run-many --targets=build --exclude='*,!tag:type:pkg'

- name: Run Build for All
run: npx nx run-many --targets=build --exclude='*,!tag:type:pkg' --skip-nx-cache

- name: Run Affected Lint
run: npx nx affected -t lint --parallel=7 --exclude='*,!tag:type:pkg'

- name: Run Affected Test
run: npx nx run-many -t test --parallel=3 --exclude='*,!tag:type:pkg' --skip-nx-cache
run: npx nx affected -t test --parallel=2 --exclude='*,!tag:type:pkg' --skip-nx-cache

# - name: E2E Test for Next.js Dev
# run: |
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,5 @@ packages/enhanced/test/js
**/.mf
**/.mf/**

/apps/manifest-demo/**/@mf-types/
/apps/manifest-demo/3008-webpack-host/@mf-types/
12 changes: 8 additions & 4 deletions apps/runtime-demo/3005-runtime-host/@mf-types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import type { PackageType as PackageType_0,RemoteKeys as RemoteKeys_0 } from './remote1/apis.d.ts';
import type { PackageType as PackageType_0,RemoteKeys as RemoteKeys_0 } from './dynamic-remote/apis.d.ts';
import type { PackageType as PackageType_1,RemoteKeys as RemoteKeys_1 } from './remote1/apis.d.ts';
declare module "@module-federation/runtime" {
type RemoteKeys = RemoteKeys_0;
type RemoteKeys = RemoteKeys_0 | RemoteKeys_1;
type PackageType<T, Y=any> = T extends RemoteKeys_0 ? PackageType_0<T> :
T extends RemoteKeys_1 ? PackageType_1<T> :
Y ;
export function loadRemote<T extends RemoteKeys,Y>(packageName: T): Promise<PackageType<T, Y>>;
export function loadRemote<T extends string,Y>(packageName: T): Promise<PackageType<T, Y>>;
}
declare module "@module-federation/enhanced/runtime" {
type RemoteKeys = RemoteKeys_0;
type RemoteKeys = RemoteKeys_0 | RemoteKeys_1;
type PackageType<T, Y=any> = T extends RemoteKeys_0 ? PackageType_0<T> :
T extends RemoteKeys_1 ? PackageType_1<T> :
Y ;
export function loadRemote<T extends RemoteKeys,Y>(packageName: T): Promise<PackageType<T, Y>>;
export function loadRemote<T extends string,Y>(packageName: T): Promise<PackageType<T, Y>>;
}
declare module "@module-federation/runtime-tools" {
type RemoteKeys = RemoteKeys_0;
type RemoteKeys = RemoteKeys_0 | RemoteKeys_1;
type PackageType<T, Y=any> = T extends RemoteKeys_0 ? PackageType_0<T> :
T extends RemoteKeys_1 ? PackageType_1<T> :
Y ;
export function loadRemote<T extends RemoteKeys,Y>(packageName: T): Promise<PackageType<T, Y>>;
export function loadRemote<T extends string,Y>(packageName: T): Promise<PackageType<T, Y>>;
Expand Down
1 change: 1 addition & 0 deletions apps/runtime-demo/3005-runtime-host/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"@module-federation/runtime": "workspace:*",
"@module-federation/typescript": "workspace:*",
"@module-federation/enhanced": "workspace:*",
"@module-federation/dts-plugin": "workspace:*",
"@pmmmwh/react-refresh-webpack-plugin": "0.5.11",
"react-refresh": "0.14.0"
},
Expand Down
6 changes: 6 additions & 0 deletions apps/runtime-demo/3005-runtime-host/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@
"baseUrl": "http://127.0.0.1:3005",
"browser": "chrome"
},
"dependsOn": [
{
"target": "build",
"dependencies": true
}
],
"configurations": {
"development": {
"runnerUi": true,
Expand Down
2 changes: 1 addition & 1 deletion apps/website-new/docs/en/configure/getpublicpath.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ module.exports = {
'./Button': './src/components/Button.tsx',
},
// ...
getPublicPath: `function(currentPath) {return "https:" + window.navigator.cdn_host + "/resource/app/"}`,
getPublicPath: `function() {return "https:" + window.navigator.cdn_host + "/resource/app/"}`,
}),
],
};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"lint": "nx run-many --target=lint",
"test": "nx run-many --target=test",
"build": "nx run-many --target=build --parallel=3 --projects=tag:type:pkg",
"build:pkg": "nx run-many --targets=build --projects=tag:type:pkg",
"build:pkg": "nx run-many --targets=build --projects=tag:type:pkg --skip-nx-cache",
"lint-fix": "nx format:write --uncommitted",
"trigger-release": "node -e 'import(\"open\").then(open => open.default(\"https://github.com/module-federation/core/actions/workflows/trigger-release.yml\"))'",
"serve:next": "nx run-many --target=serve --all --parallel=3 -exclude='*,!tag:nextjs'",
Expand Down
18 changes: 14 additions & 4 deletions packages/dts-plugin/src/core/lib/DTSManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,20 @@ class DTSManager {
return u;
};

let publicPath =
'publicPath' in manifestJson.metaData
? manifestJson.metaData.publicPath
: new Function(manifestJson.metaData.getPublicPath)();
let publicPath;

if ('publicPath' in manifestJson.metaData) {
publicPath = manifestJson.metaData.publicPath;
} else {
const getPublicPath = new Function(manifestJson.metaData.getPublicPath);

if (manifestJson.metaData.getPublicPath.startsWith('function')) {
publicPath = getPublicPath()();
} else {
publicPath = getPublicPath();
}
}

if (publicPath === 'auto') {
publicPath = inferAutoPublicPath(remoteInfo.url);
}
Expand Down
3 changes: 3 additions & 0 deletions packages/dts-plugin/src/core/lib/DtsWorker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ describe('generateTypesInChildProcess', () => {
},
],
});
await new Promise((res) => {
setTimeout(res, 1000);
});
// the child process should be killed after generateTypes
expect(checkProcess()).toEqual(false);
});
Expand Down
6 changes: 4 additions & 2 deletions packages/enhanced/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@
}
},
"devDependencies": {
"@module-federation/webpack-bundler-runtime": "workspace:*"
"@module-federation/webpack-bundler-runtime": "workspace:*",
"@types/btoa": "^1.2.5"
},
"dependencies": {
"@module-federation/sdk": "workspace:*",
Expand All @@ -77,6 +78,7 @@
"@module-federation/dts-plugin": "workspace:*",
"@module-federation/rspack": "workspace:*",
"@module-federation/bridge-react-webpack-plugin": "workspace:*",
"upath": "2.0.1"
"upath": "2.0.1",
"btoa": "^1.2.1"
}
}
7 changes: 7 additions & 0 deletions packages/enhanced/src/lib/container/ModuleFederationPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import SharePlugin from '../sharing/SharePlugin';
import ContainerPlugin from './ContainerPlugin';
import ContainerReferencePlugin from './ContainerReferencePlugin';
import FederationRuntimePlugin from './runtime/FederationRuntimePlugin';
import { RemoteEntryPlugin } from './runtime/RemoteEntryPlugin';

const isValidExternalsType = require(
normalizeWebpackPath(
Expand Down Expand Up @@ -69,6 +70,12 @@ class ModuleFederationPlugin implements WebpackPluginInstance {
*/
apply(compiler: Compiler): void {
const { _options: options } = this;
// must before ModuleFederationPlugin
if (options.getPublicPath && options.name) {
new RemoteEntryPlugin(options.name, options.getPublicPath).apply(
compiler,
);
}
if (options.dts !== false) {
new DtsPlugin(options).apply(compiler);
}
Expand Down
32 changes: 32 additions & 0 deletions packages/enhanced/src/lib/container/runtime/RemoteEntryPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { Compiler, WebpackPluginInstance } from 'webpack';
import pBtoa from 'btoa';

export class RemoteEntryPlugin implements WebpackPluginInstance {
readonly name = 'VmokRemoteEntryPlugin';
private _name: string;
private _getPublicPath: string;

constructor(name: string, getPublicPath: string) {
this._name = name;
this._getPublicPath = getPublicPath;
}

apply(compiler: Compiler): void {
let code;
if (!this._getPublicPath.startsWith('function')) {
code = `${
compiler.webpack.RuntimeGlobals.publicPath
} = new Function(${JSON.stringify(this._getPublicPath)})()`;
} else {
code = `(${this._getPublicPath})()`;
}
const base64Code = pBtoa(code);
const dataUrl = `data:text/javascript;base64,${base64Code}`;

compiler.hooks.afterPlugins.tap('VmokRemoteEntryPlugin', () => {
new compiler.webpack.EntryPlugin(compiler.context, dataUrl, {
name: this._name,
}).apply(compiler);
});
}
}
9 changes: 9 additions & 0 deletions packages/manifest/src/StatsManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,15 @@ class StatsManager {
pluginVersion: this._pluginVersion,
};

if (this._options.getPublicPath) {
if ('publicPath' in metaData) {
delete metaData.publicPath;
}
return {
...metaData,
getPublicPath: this._options.getPublicPath,
};
}
return {
...metaData,
publicPath: this.getPublicPath(compiler),
Expand Down
4 changes: 2 additions & 2 deletions packages/native-federation-typescript/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('index', () => {
expect(writeBundle).toThrowError('moduleFederationConfig is required');
});

it('correctly writeBundle', async () => {
it.skip('correctly writeBundle', async () => {
const options = {
moduleFederationConfig: {
name: 'moduleFederationTypescript',
Expand Down Expand Up @@ -177,7 +177,7 @@ describe('index', () => {
expect(writeBundle).toThrowError('moduleFederationConfig is required');
});

it('correctly writeBundle', async () => {
it.skip('correctly writeBundle', async () => {
const options = {
moduleFederationConfig: {
name: 'moduleFederationTypescript',
Expand Down
4 changes: 4 additions & 0 deletions packages/sdk/src/types/plugins/ModuleFederationPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ export interface ModuleFederationPluginOptions {
* Runtime plugin file paths or package name.
*/
runtimePlugins?: string[];
/**
* Custom public path function
*/
getPublicPath?: string;
/**
* Bundler runtime path
*/
Expand Down
11 changes: 9 additions & 2 deletions packages/sdk/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,20 @@ const generateShareFilename = /* @__PURE__ */ (

const getResourceUrl = (module: ModuleInfo, sourceUrl: string): string => {
if ('getPublicPath' in module) {
const publicPath = new Function(module.getPublicPath)();
let publicPath;

if (!module.getPublicPath.startsWith('function')) {
publicPath = new Function(module.getPublicPath)();
} else {
publicPath = new Function('return ' + module.getPublicPath)()();
}

return `${publicPath}${sourceUrl}`;
} else if ('publicPath' in module) {
return `${module.publicPath}${sourceUrl}`;
} else {
console.warn(
'Can not get resource url, if in debug mode, please ignore',
'Cannot get resource URL. If in debug mode, please ignore.',
module,
sourceUrl,
);
Expand Down
Loading

0 comments on commit 88445e7

Please sign in to comment.