Skip to content

Commit

Permalink
feat: add withModuleFederationPlugin to simplify the generated
Browse files Browse the repository at this point in the history
webpack.config.js files.

This method takes a superset of a ModuleFederationConfig and adds some
default values, e. g. if not stated otherwise, all npm packages and
local mapped paths are shared and the filename defaults to
remoteEntry.js

**BREAKING CHANGE**
shareAll uses the DEFAULT_SKIP_LIST by default.
  • Loading branch information
manfredsteyer committed May 27, 2022
1 parent aaa7c49 commit ca26aeb
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 8 deletions.
31 changes: 25 additions & 6 deletions libs/mf/src/utils/share-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import callsite = require('callsite');
import path = require('path');
import fs = require('fs');
import { SharedConfig } from './webpack.types';
import { cwd } from 'process';

let inferVersion = false;

Expand All @@ -14,10 +15,26 @@ export const DEFAULT_SKIP_LIST = [

type VersionMap = Record<string, string>;
type IncludeSecondariesOptions = { skip: string | string[] } | boolean;
type CustomSharedConfig = SharedConfig & { includeSecondaries: IncludeSecondariesOptions };
type CustomSharedConfig = SharedConfig & { includeSecondaries?: IncludeSecondariesOptions };
type ConfigObject = Record<string, CustomSharedConfig>;
type Config = (string | ConfigObject)[] | ConfigObject;

export function findRootTsConfigJson(): string {
const packageJson = findPackageJson(cwd());
const projectRoot = path.dirname(packageJson);
const tsConfigBaseJson = path.join(projectRoot, 'tsconfig.base.json');
const tsConfigJson = path.join(projectRoot, 'tsconfig.json');

if (fs.existsSync(tsConfigBaseJson)) {
return tsConfigBaseJson;
}
else if (fs.existsSync(tsConfigJson)) {
return tsConfigJson;
}

throw new Error('Neither a tsconfig.json nor a tsconfig.base.json was found');
}

function findPackageJson(folder: string): string {
while (
!fs.existsSync(path.join(folder, 'package.json'))
Expand Down Expand Up @@ -112,11 +129,10 @@ function addSecondaries(secondaries: string[], result: Config, shareObject: Conf
}
}

export function shareAll(config: Config = {}, skip: string[] = [], packageJsonPath = ''): Config {
export function shareAll(config: CustomSharedConfig = {}, skip: string[] = DEFAULT_SKIP_LIST, packageJsonPath = ''): Config {

if (!packageJsonPath) {
const stack = callsite();
packageJsonPath = path.dirname(stack[1].getFileName());
packageJsonPath = cwd();
}

const packagePath = findPackageJson(packageJsonPath);
Expand Down Expand Up @@ -144,8 +160,7 @@ export function setInferVersion(infer: boolean): void {
export function share(shareObjects: Config, packageJsonPath = ''): Config {

if (!packageJsonPath) {
const stack = callsite();
packageJsonPath = path.dirname(stack[1].getFileName());
packageJsonPath = cwd();
}

const packagePath = findPackageJson(packageJsonPath);
Expand All @@ -162,6 +177,10 @@ export function share(shareObjects: Config, packageJsonPath = ''): Config {
shareObject.requiredVersion = lookupVersion(key, versions);
}

if (typeof shareObject.includeSecondaries === 'undefined') {
shareObject.includeSecondaries = true;
}

if (shareObject.includeSecondaries) {
includeSecondaries = shareObject.includeSecondaries;
delete shareObject.includeSecondaries;
Expand Down
8 changes: 7 additions & 1 deletion libs/mf/src/utils/shared-mappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ export class SharedMappings {
);
}

const shareAll = !shared;

if (!shared) {
shared = [];
}

const tsConfig = JSON5.parse(
fs.readFileSync(tsConfigPath, { encoding: 'utf-8' })
);
Expand All @@ -36,7 +42,7 @@ export class SharedMappings {
const libPath = path.normalize(path.join(rootPath, mappings[key][0]));
const version = this.getPackageVersion(libPath);

if (shared && shared.includes(key)) {
if (shared.includes(key) || shareAll) {
this.mappings.push({
key,
path: libPath,
Expand Down
67 changes: 67 additions & 0 deletions libs/mf/src/utils/with-mf-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { findRootTsConfigJson, shareAll } from './share-utils';
import { SharedMappings } from './shared-mappings';

const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

export function withModuleFederationPlugin(config: unknown) {

const sharedMappings = config['sharedMappings'];
delete config['sharedMappings'];

const mappings = new SharedMappings();
mappings.register(findRootTsConfigJson(), sharedMappings);

if (!config['library']) {
config['library'] = {
type: 'module'
}
}

if (!config['filename']) {
config['filename'] = 'remoteEntry.js';
}

if (!config['shared']) {
config['shared'] = shareAll(
{ singleton: true, strictVersion: true, requiredVersion: 'auto'});
}

if (typeof config['shared'] === 'object') {
config['shared'] = {
...config['shared'],
...mappings.getDescriptors()
}
}

if (Array.isArray(config['shared'])) {
config['shared'] = [
...config['shared'],
mappings.getDescriptors()
]
}

const isModule = config['library']?.['type'] === 'module';

return {
output: {
publicPath: "auto"
},
optimization: {
runtimeChunk: false
},
resolve: {
alias: {
...mappings.getAliases(),
}
},
...(isModule) ? {
experiments: {
outputModule: true
}
} : {},
plugins: [
new ModuleFederationPlugin(config),
mappings.getPlugin()
],
};
}
3 changes: 2 additions & 1 deletion libs/mf/src/webpack.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './utils/shared-mappings';
export * from './utils/share-utils';
export * from './utils/share-utils';
export * from './utils/with-mf-plugin';

0 comments on commit ca26aeb

Please sign in to comment.