Skip to content

Commit

Permalink
feat: added support for templated remote origin URLs
Browse files Browse the repository at this point in the history
  • Loading branch information
steven-pribilinskiy committed Jul 19, 2022
1 parent 1cea392 commit 00cbad0
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 28 deletions.
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ Inspired by several existing solutions:
- [@module-federation/typescript](https://app.privjs.com/buy/packageDetail?pkg=@module-federation/typescript)
from the creator of Webpack Module Federation, Zack Jackson (aka [ScriptAlchemy](https://twitter.com/ScriptedAlchemy))

Zack
Jackson [was asked several questions](https://github.com/module-federation/module-federation-examples/issues/20#issuecomment-1153131082)
around his plugin hoping that he can suggest some solutions to the exposed problems to no avail.
After a month of waiting this package was built
Zack Jackson was asked for help with
[several issues](https://github.com/module-federation/module-federation-examples/issues/20#issuecomment-1153131082)
around his plugin. There was a hope that he can suggest some solutions to the exposed problems, to no avail.
After a month of waiting this package was built.

## Feature comparison tables

Expand All @@ -41,7 +41,8 @@ After a month of waiting this package was built
| @module-federation/typescript | + | - | + | - | - |
| @cloudbeds/wmf-types-plugin | + | + | + | + | - |

* _Runtime microapp imports_ refers to the [module-federation/external-remotes-plugin](https://github.com/module-federation/external-remotes-plugin)
*_Runtime microapp imports_ refers to templated remote URLs that are resolved in runtime using
[module-federation/external-remotes-plugin](https://github.com/module-federation/external-remotes-plugin)

| Package | Webpack aliases | Exposed aliases | Synchronization/[compile hooks](https://webpack.js.org/api/compiler-hooks/) |
|------------------------------------|-----------------|-----------------|------------------------------------------------------------------------------------------|
Expand Down Expand Up @@ -189,6 +190,7 @@ This way downloaded types will always correspond to the latest compatible versio

## Plugin Options

| Option | Description |
|-----------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `syncTypesIntervalInSeconds` | Synchronize types continusouly with a specified value in seconds. To disable continuous synchronization this should be set to `0`. To completely disable the plugin this should be set to `-1` |
| Option | Value | Description |
|-----------------------------:|:-------------------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `syncTypesIntervalInSeconds` | `number`, `0`, `-1` | Synchronize types continusouly with a specified value in seconds. <br><br> `0` - disables continuous synchronization. <br> `-1` - disables the plugin |
| `externalTemplatedRemotes` | `object` | URLs to the external remotes that are substituted in runtime. <br><br> _Example:_ for a remote entry <br> `{ mfdCommon: 'mfdCommon@[mfdCommon]/remoteEntry.js' }`, <br> the `[mfdCommon]` placeholder (that refers to `window.mfdCommon` in runtime) and `remoteEntry.js` are replaced by value from: <br> `{ externalTemplatedRemotes: { mfdCommon: 'https://localhost:9082/remoteEntry.js' } }` <br> and then the origin `https://localhost:9082` is used to fetch the types from |
12 changes: 0 additions & 12 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,6 @@ export function assertRunningFromRoot(): void {
}
}

export function isValidUrl(value: string): boolean {
let url;

try {
url = new URL(value);
} catch (err) {
return false;
}

return ['http:', 'https:'].includes(url.protocol);
}

export function getFederationConfig(customConfigPath?: string): FederationConfig {
const federationConfigPath = path.resolve(customConfigPath || FEDERATION_CONFIG_FILE);
if (!federationConfigPath) {
Expand Down
19 changes: 11 additions & 8 deletions src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ import path from 'path';
import { Compiler, container, WebpackPluginInstance } from 'webpack';

import { DEFAULT_SYNC_TYPES_INTERVAL_IN_SECONDS, DIR_DOWNLOADED, DIR_EMITTED } from './constants';
import { compile, isValidUrl, rewritePathsWithExposedFederatedModules } from './helpers';
import { compile, rewritePathsWithExposedFederatedModules } from './helpers';
import { FederationConfig } from './types';

type ModuleFederationPluginOptions = ConstructorParameters<typeof container.ModuleFederationPlugin>[0];

type MFTypesPluginOptions = {
type ModuleFederationTypesPluginOptions = {
externalTemplatedRemotes?: Record<string, string>,
syncTypesIntervalInSeconds?: number;
}

export class ModuleFederationTypesPlugin implements WebpackPluginInstance {
constructor(public options?: MFTypesPluginOptions) {}
constructor(public options?: ModuleFederationTypesPluginOptions) {}

apply(compiler: Compiler): void {
if (this.options?.syncTypesIntervalInSeconds === -1) {
Expand All @@ -33,25 +34,27 @@ export class ModuleFederationTypesPlugin implements WebpackPluginInstance {
const outFile = path.join(distPath, DIR_EMITTED, `${name}.d.ts`);

// Create types for exposed modules
function emitTypes() {
const emitTypes = () => {
if (!exposes) { return; }

const { isSuccess, fileContent } = compile(exposes as string[], outFile);
if (isSuccess) {
rewritePathsWithExposedFederatedModules(federationPluginOptions as FederationConfig, outFile, fileContent);
}
}
};

// Import types from remote modules
function downloadTypes() {
const downloadTypes = () => {
if (!remotes) { return; }

Object.values(remotes).map(async remote => {
const remoteName = remote.split('@')[0]
const remoteLocation = remote.split('@')[1]
let remoteDistUrl: string = '';

if (isValidUrl(remoteLocation)) {
if (this.options?.externalTemplatedRemotes?.[remoteName]) {
remoteDistUrl = new URL(this.options.externalTemplatedRemotes[remoteName]).origin;
} else {
remoteDistUrl = new URL(remoteLocation).origin;
}

Expand All @@ -62,7 +65,7 @@ export class ModuleFederationTypesPlugin implements WebpackPluginInstance {
console.error(remote, 'is not a valid remote federated module URL');
}
});
}
};

let recompileIntervalId: ReturnType<typeof setInterval>;
const shouldRecompileOnInterval = (compiler.options.mode === 'development')
Expand Down

0 comments on commit 00cbad0

Please sign in to comment.