Skip to content

Commit

Permalink
Release v3.28.0
Browse files Browse the repository at this point in the history
Co-authored-by: Drapeza Oleg <[email protected]>
GitOrigin-RevId: 8e3669f14da3a576c03d20b7366d91b57970e489
  • Loading branch information
tramvaijsorg and Drapeza Oleg committed Jan 23, 2024
1 parent ae447fb commit 599672c
Show file tree
Hide file tree
Showing 42 changed files with 650 additions and 184 deletions.
22 changes: 22 additions & 0 deletions docs/03-features/015-child-app/03-ui-component.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,25 @@ const Page = () => {
);
}
```

## How to

### Code splitting

[@tramvai/react `lazy`](references/tramvai/react.md#lazy) is supported in Child Apps:

```tsx title="components/root.tsx"
import { lazy } from '@tramvai/react';

const LazyFooCmp = lazy(() => import('./heavy-components/foo'));
const LazyBarCmp = lazy(() => import('./heavy-components/bar'));

export const RootCmp = (props) => {
return (
<div>
<h1>Child App</h1>
{props.condition ? <LazyFooCmp /> : <LazyBarCmp />}
</div>
);
};
```
23 changes: 23 additions & 0 deletions examples/child-app/child-apps/loadable/component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { lazy, useDi } from '@tramvai/react';
import { useState } from 'react';
import { CHILD_APP_BASE_TOKEN } from './tokens';

const Lazy = lazy(() => import('./lazy-cmp'));

const LazyUnused = lazy(() => import('./lazy-cmp-unused'));

export const LoadableCmp = ({ fromRoot }: { fromRoot: string }) => {
const [visible, setVisible] = useState(false);
const val = useDi(CHILD_APP_BASE_TOKEN);

return (
<>
<Lazy />
<div id="loadable">Child App: {val}</div>
<button id="loadable-toggle" type="button" onClick={() => setVisible((prev) => !prev)}>
toggle unused component
</button>
{visible && <LazyUnused />}
</>
);
};
40 changes: 40 additions & 0 deletions examples/child-app/child-apps/loadable/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { createChildApp } from '@tramvai/child-app-core';
import { createAction, provide } from '@tramvai/core';
import { CommonChildAppModule } from '@tramvai/module-common';
import { LoadableCmp } from './component';
import { CHILD_APP_BASE_TOKEN } from './tokens';

declare global {
interface Window {
TRAMVAI_TEST_CHILD_APP_NOT_PRELOADED_ACTION_CALL_NUMBER: number;
}
}

if (typeof window !== 'undefined') {
window.TRAMVAI_TEST_CHILD_APP_NOT_PRELOADED_ACTION_CALL_NUMBER = 0;
}

const action = createAction({
name: 'action',
fn() {
window.TRAMVAI_TEST_CHILD_APP_NOT_PRELOADED_ACTION_CALL_NUMBER++;
},
conditions: {
always: true,
onlyBrowser: true,
},
});

// eslint-disable-next-line import/no-default-export
export default createChildApp({
name: 'base',
render: LoadableCmp,
modules: [CommonChildAppModule],
actions: [action],
providers: [
provide({
provide: CHILD_APP_BASE_TOKEN,
useValue: "I'm little child app",
}),
],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.LazyCmp {
color: green;
}
14 changes: 14 additions & 0 deletions examples/child-app/child-apps/loadable/lazy-cmp-unused.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as dateFns from 'date-fns';
import cn from './lazy-cmp-unused.module.css';

console.log(dateFns);

export const LazyCmp = () => {
return (
<>
<h2 className={cn.LazyCmp}>Lazy Unused</h2>
</>
);
};

export default LazyCmp;
3 changes: 3 additions & 0 deletions examples/child-app/child-apps/loadable/lazy-cmp.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.LazyCmp {
color: red;
}
14 changes: 14 additions & 0 deletions examples/child-app/child-apps/loadable/lazy-cmp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as dateFns from 'date-fns';
import cn from './lazy-cmp.module.css';

console.log(dateFns);

export const LazyCmp = () => {
return (
<>
<h2 className={cn.LazyCmp}>Lazy</h2>
</>
);
};

export default LazyCmp;
3 changes: 3 additions & 0 deletions examples/child-app/child-apps/loadable/tokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { createToken } from '@tinkoff/dippy';

export const CHILD_APP_BASE_TOKEN = createToken<string>('children base token');
3 changes: 2 additions & 1 deletion examples/child-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"@tramvai/react-query": "0.0.0-stub",
"@tramvai/state": "0.0.0-stub",
"@tramvai/tokens-child-app": "0.0.0-stub",
"@tramvai/tokens-common": "0.0.0-stub"
"@tramvai/tokens-common": "0.0.0-stub",
"date-fns": "^2.11.0"
},
"peerDependencies": {
"react": ">=16.14.0",
Expand Down
9 changes: 9 additions & 0 deletions examples/child-app/root-app/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ createApp({
'react-query': () => import(/* webpackChunkName: "react-query" */ './bundles/react-query'),
router: () => import(/* webpackChunkName: "router" */ './bundles/router'),
state: () => import(/* webpackChunkName: "state" */ './bundles/state'),
loadable: () => import(/* webpackChunkName: "loadable" */ './bundles/loadable'),
},
modules: [
CommonModule,
Expand Down Expand Up @@ -160,6 +161,14 @@ createApp({
},
},
},
{
name: 'loadable',
byTag: {
latest: {
version: '0.0.0-stub',
},
},
},
],
}),
],
Expand Down
22 changes: 22 additions & 0 deletions examples/child-app/root-app/bundles/loadable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { PageComponent } from '@tramvai/react';
import { createBundle } from '@tramvai/core';
import { ChildApp } from '@tramvai/module-child-app';

const Cmp: PageComponent = () => {
return (
<>
<div>Content from root</div>
<ChildApp name="loadable" />
</>
);
};

Cmp.childApps = [{ name: 'loadable' }];

// eslint-disable-next-line import/no-default-export
export default createBundle({
name: 'loadable',
components: {
pageDefault: Cmp,
},
});
7 changes: 7 additions & 0 deletions examples/child-app/root-app/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,11 @@ export const routes: ExtractTokenType<typeof ROUTES_TOKEN> & any[] = [
bundle: 'state',
},
},
{
name: 'loadable',
path: '/loadable',
config: {
bundle: 'loadable',
},
},
];
1 change: 1 addition & 0 deletions examples/child-app/shared/serverResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const portMapping = {
'react-query': 4046,
router: 4047,
state: 4048,
loadable: 4049,
};

const cliStarts: Array<ReturnType<typeof start>> = [];
Expand Down
5 changes: 5 additions & 0 deletions examples/child-app/tramvai.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@
"name": "state",
"root": "child-apps/state",
"type": "child-app"
},
"loadable": {
"name": "loadable",
"root": "child-apps/loadable",
"type": "child-app"
}
}
}
2 changes: 1 addition & 1 deletion packages-versions.json
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@

{"@tramvai/cli":"3.27.5","@tramvai/swc-integration":"3.27.5","@tinkoff/browser-timings":"0.11.1","@tinkoff/browserslist-config":"0.3.2","@tinkoff/browser-cookies":"3.0.1","@tinkoff/dippy":"0.9.2","@tinkoff/env-validators":"0.2.1","@tinkoff/error-handlers":"0.6.1","@tinkoff/errors":"0.4.2","@tinkoff/eslint-plugin-tramvai":"0.7.3","@tinkoff/hook-runner":"0.5.1","@tramvai/http-client":"0.3.1","@tinkoff/is-modern-lib":"3.0.3","@tramvai/react-lazy-hydration-render":"0.3.1","@tinkoff/logger":"0.10.170","@tinkoff/pack-polyfills":"0.5.1","@tinkoff/measure-express-requests":"3.0.1","@tinkoff/measure-fastify-requests":"0.2.1","@tinkoff/meta-tags-generate":"0.6.1","@tinkoff/metrics-noop":"3.0.1","@tinkoff/minicss-class-generator":"0.3.1","@tinkoff/mocker":"3.0.1","@tinkoff/module-loader-client":"0.5.1","@tinkoff/module-loader-server":"0.6.2","@tinkoff/monkeypatch":"3.0.1","@tinkoff/package-manager-wrapper":"0.2.2","@tinkoff/htmlpagebuilder":"0.6.1","prettier-config-tinkoff":"0.3.1","@tinkoff/pubsub":"0.6.1","@tinkoff/react-hooks":"0.2.1","@tinkoff/router":"0.3.52","@tramvai/safe-strings":"0.6.2","@tinkoff/terminus":"0.2.1","@tinkoff/layout-factory":"0.4.1","@tramvai/tinkoff-request-http-client-adapter":"0.10.72","@tinkoff/url":"0.9.2","@tinkoff/user-agent":"0.5.72","@tinkoff/webpack-dedupe-plugin":"2.0.2","@tramvai/module-autoscroll":"3.27.5","@tramvai/module-cache-warmup":"3.27.5","@tramvai/module-child-app":"3.27.5","@tramvai/module-client-hints":"3.27.5","@tramvai/module-common":"3.27.5","@tramvai/module-cookie":"3.27.5","@tramvai/module-deps-graph":"3.27.5","@tramvai/module-dns-cache":"3.27.5","@tramvai/module-environment":"3.27.5","@tramvai/module-error-interceptor":"3.27.5","@tramvai/module-http-client":"3.27.5","@tramvai/module-http-proxy-agent":"3.27.5","@tramvai/module-log":"3.27.5","@tramvai/module-metrics":"3.27.5","@tramvai/module-micro-sentry":"3.27.5","@tramvai/module-mocker":"3.27.5","@tramvai/module-page-render-mode":"3.27.5","@tramvai/module-progressive-web-app":"3.27.5","@tramvai/module-react-query":"3.27.5","@tramvai/module-render":"3.27.5","@tramvai/module-request-limiter":"3.27.5","@tramvai/module-router":"3.27.5","@tramvai/module-sentry":"3.27.5","@tramvai/module-seo":"3.27.5","@tramvai/module-server":"3.27.5","@tramvai/tokens-child-app":"3.27.5","@tramvai/tokens-common":"3.27.5","@tramvai/tokens-cookie":"3.27.5","@tramvai/tokens-core":"3.27.5","@tramvai/tokens-core-private":"3.27.5","@tramvai/tokens-http-client":"3.27.5","@tramvai/tokens-metrics":"3.27.5","@tramvai/tokens-react-query":"3.27.5","@tramvai/tokens-render":"3.27.5","@tramvai/tokens-router":"3.27.5","@tramvai/tokens-server":"3.27.5","@tramvai/tokens-server-private":"3.27.5","@tramvai/child-app-core":"3.27.5","@tramvai/core":"3.27.5","@tramvai/experiments":"3.27.5","@tramvai/papi":"3.27.5","@tramvai/pwa-recipes":"3.27.5","@tramvai/react":"3.27.5","@tramvai/react-query":"3.27.5","@tramvai/state":"3.27.5","@tramvai/storybook-addon":"3.27.5","@tramvai/types-actions-state-context":"3.27.5","@tramvai/test-child-app":"3.27.5","@tramvai/test-helpers":"3.27.5","@tramvai/test-integration":"3.27.5","@tramvai/test-integration-jest":"3.27.5","@tramvai/test-jsdom":"3.27.5","@tramvai/test-mocks":"3.27.5","@tramvai/test-pw":"3.27.5","@tramvai/test-puppeteer":"3.27.5","@tramvai/test-react":"3.27.5","@tramvai/test-unit":"3.27.5","@tramvai/test-unit-jest":"3.27.5","@tramvai/build":"4.1.1","@tramvai/tools-check-versions":"0.5.3","@tramvai/create":"3.27.5","@tramvai/tools-generate-schema":"0.2.1","@tramvai/tools-migrate":"0.7.3","@tinkoff-monorepo/depscheck":"3.0.2","@tinkoff-monorepo/fix-ts-references":"3.0.2","@tinkoff-monorepo/pkgs-collector":"3.0.2","@tinkoff-monorepo/pkgs-collector-dir":"3.0.2","@tinkoff-monorepo/pkgs-collector-workspaces":"3.0.2"}
{"@tramvai/cli":"3.28.0","@tramvai/swc-integration":"3.28.0","@tinkoff/browser-timings":"0.11.1","@tinkoff/browserslist-config":"0.3.2","@tinkoff/browser-cookies":"3.0.1","@tinkoff/dippy":"0.9.2","@tinkoff/env-validators":"0.2.1","@tinkoff/error-handlers":"0.6.1","@tinkoff/errors":"0.4.2","@tinkoff/eslint-plugin-tramvai":"0.7.3","@tinkoff/hook-runner":"0.5.1","@tramvai/http-client":"0.3.1","@tinkoff/is-modern-lib":"3.0.3","@tramvai/react-lazy-hydration-render":"0.3.1","@tinkoff/logger":"0.10.170","@tinkoff/pack-polyfills":"0.5.1","@tinkoff/measure-express-requests":"3.0.1","@tinkoff/measure-fastify-requests":"0.2.1","@tinkoff/meta-tags-generate":"0.6.1","@tinkoff/metrics-noop":"3.0.1","@tinkoff/minicss-class-generator":"0.3.1","@tinkoff/mocker":"3.0.1","@tinkoff/module-loader-client":"0.5.1","@tinkoff/module-loader-server":"0.6.3","@tinkoff/monkeypatch":"3.0.1","@tinkoff/package-manager-wrapper":"0.2.2","@tinkoff/htmlpagebuilder":"0.6.1","prettier-config-tinkoff":"0.3.1","@tinkoff/pubsub":"0.6.1","@tinkoff/react-hooks":"0.2.1","@tinkoff/router":"0.3.53","@tramvai/safe-strings":"0.6.2","@tinkoff/terminus":"0.2.1","@tinkoff/layout-factory":"0.4.1","@tramvai/tinkoff-request-http-client-adapter":"0.10.73","@tinkoff/url":"0.9.2","@tinkoff/user-agent":"0.5.73","@tinkoff/webpack-dedupe-plugin":"2.0.2","@tramvai/module-autoscroll":"3.28.0","@tramvai/module-cache-warmup":"3.28.0","@tramvai/module-child-app":"3.28.0","@tramvai/module-client-hints":"3.28.0","@tramvai/module-common":"3.28.0","@tramvai/module-cookie":"3.28.0","@tramvai/module-deps-graph":"3.28.0","@tramvai/module-dns-cache":"3.28.0","@tramvai/module-environment":"3.28.0","@tramvai/module-error-interceptor":"3.28.0","@tramvai/module-http-client":"3.28.0","@tramvai/module-http-proxy-agent":"3.28.0","@tramvai/module-log":"3.28.0","@tramvai/module-metrics":"3.28.0","@tramvai/module-micro-sentry":"3.28.0","@tramvai/module-mocker":"3.28.0","@tramvai/module-page-render-mode":"3.28.0","@tramvai/module-progressive-web-app":"3.28.0","@tramvai/module-react-query":"3.28.0","@tramvai/module-render":"3.28.0","@tramvai/module-request-limiter":"3.28.0","@tramvai/module-router":"3.28.0","@tramvai/module-sentry":"3.28.0","@tramvai/module-seo":"3.28.0","@tramvai/module-server":"3.28.0","@tramvai/tokens-child-app":"3.28.0","@tramvai/tokens-common":"3.28.0","@tramvai/tokens-cookie":"3.28.0","@tramvai/tokens-core":"3.28.0","@tramvai/tokens-core-private":"3.28.0","@tramvai/tokens-http-client":"3.28.0","@tramvai/tokens-metrics":"3.28.0","@tramvai/tokens-react-query":"3.28.0","@tramvai/tokens-render":"3.28.0","@tramvai/tokens-router":"3.28.0","@tramvai/tokens-server":"3.28.0","@tramvai/tokens-server-private":"3.28.0","@tramvai/child-app-core":"3.28.0","@tramvai/core":"3.28.0","@tramvai/experiments":"3.28.0","@tramvai/papi":"3.28.0","@tramvai/pwa-recipes":"3.28.0","@tramvai/react":"3.28.0","@tramvai/react-query":"3.28.0","@tramvai/state":"3.28.0","@tramvai/storybook-addon":"3.28.0","@tramvai/types-actions-state-context":"3.28.0","@tramvai/test-child-app":"3.28.0","@tramvai/test-helpers":"3.28.0","@tramvai/test-integration":"3.28.0","@tramvai/test-integration-jest":"3.28.0","@tramvai/test-jsdom":"3.28.0","@tramvai/test-mocks":"3.28.0","@tramvai/test-pw":"3.28.0","@tramvai/test-puppeteer":"3.28.0","@tramvai/test-react":"3.28.0","@tramvai/test-unit":"3.28.0","@tramvai/test-unit-jest":"3.28.0","@tramvai/build":"4.1.1","@tramvai/tools-check-versions":"0.5.3","@tramvai/create":"3.28.0","@tramvai/tools-generate-schema":"0.2.1","@tramvai/tools-migrate":"0.7.3","@tinkoff-monorepo/depscheck":"3.0.2","@tinkoff-monorepo/fix-ts-references":"3.0.2","@tinkoff-monorepo/pkgs-collector":"3.0.2","@tinkoff-monorepo/pkgs-collector-dir":"3.0.2","@tinkoff-monorepo/pkgs-collector-workspaces":"3.0.2"}
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"@discoveryjs/json-ext": "^0.5.7",
"@fastify/compress": "^6.2.0",
"@fastify/static": "^6.9.0",
"@loadable/webpack-plugin": "^5.15.0",
"@module-federation/node": "^0.15.1",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
"@sentry/node": "^6.2.5",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { ApplicationConfigEntry } from '../../../../../../typings/configEnt
import type { SplitChunksOptions } from '../../../../types/webpack';

// based on [nextjs code](https://github.com/vercel/next.js/blob/aaeb349ce3e8c4c3435a43a29af4379266818e7b/packages/next/build/webpack-config.ts#L707)
const resolveFrameworksPaths = (rootDir: string, frameworksList: string[]) => {
export const resolveFrameworksPaths = (rootDir: string, frameworksList: string[]) => {
const topLevelFrameworkPaths: string[] = [];
const visitedFrameworkPackages = new Set<string>();

Expand Down
8 changes: 8 additions & 0 deletions packages/cli/src/library/webpack/child-app/client/common.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type Config from 'webpack-chain';
import { ChunkCorrelationPlugin } from '@module-federation/node';
import LoadablePlugin from '@loadable/webpack-plugin';

import type { ConfigManager } from '../../../../config/configManager';

Expand Down Expand Up @@ -33,5 +34,12 @@ export default (configManager: ConfigManager<ChildAppConfigEntry>) => (config: C
},
]);

config.plugin('loadable-stats-plugin').use(LoadablePlugin, [
{
writeToDisk: true,
filename: `${name}_stats_loadable@${version}.json`,
},
]);

config.batch(files(configManager)).batch(nodeClient(configManager));
};
72 changes: 66 additions & 6 deletions packages/cli/src/library/webpack/child-app/common.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type Config from 'webpack-chain';
import type webpack from 'webpack';
import path from 'path';
import crypto from 'crypto';
import { UniversalFederationPlugin } from '@module-federation/node';
import common from '../common/main';

Expand All @@ -9,23 +11,28 @@ import ts from '../blocks/ts';
import js from '../blocks/js';
import css from '../blocks/css';
import nodeClient from '../blocks/nodeClient';
import type { UniversalFederationPluginOptions } from '../types/webpack';
import type { SplitChunksOptions, UniversalFederationPluginOptions } from '../types/webpack';
import { getSharedModules } from './moduleFederationShared';
import { configToEnv } from '../blocks/configToEnv';
import sourcemaps from '../blocks/sourcemaps';
import type { ChildAppConfigEntry } from '../../../typings/configEntry/child-app';
import { extractCssPluginFactory } from '../blocks/extractCssPlugin';
import type { ModuleFederationFixRangeOptions } from '../plugins/ModuleFederationFixRange';
import { ModuleFederationFixRange } from '../plugins/ModuleFederationFixRange';
import { resolveFrameworksPaths } from '../application/client/prod/optimization/splitChunks';

// eslint-disable-next-line max-statements
export default (configManager: ConfigManager<ChildAppConfigEntry>) => (config: Config) => {
const { name, root, sourceMap, buildType, shared } = configManager;
const { name, root, rootDir, sourceMap, buildType, shared, env, hotRefresh, target } =
configManager;

const cssLocalIdentName =
configManager.env === 'production'
? `${name}__[minicss]`
: `${name}__[name]__[local]_[hash:base64:5]`;
const entry = path.resolve(configManager.rootDir, root);
const entry = path.resolve(configManager.rootDir, root, 'index.ts');

const sharedModules = getSharedModules(configManager);

// use empty module instead of original one as I haven't figured out how to prevent webpack from initializing entry module on loading
// it should be initialized only as remote in ModuleFederation and not as standalone module
Expand Down Expand Up @@ -60,7 +67,7 @@ export default (configManager: ConfigManager<ChildAppConfigEntry>) => (config: C
config.optimization.set('chunkIds', 'named');

// define split chunks to put all of the css into single entry file
config.optimization.splitChunks({
const webpackSplitChunks: SplitChunksOptions = {
cacheGroups: {
default: false,
defaultVendors: false,
Expand All @@ -69,9 +76,62 @@ export default (configManager: ConfigManager<ChildAppConfigEntry>) => (config: C
type: 'css/mini-extract',
chunks: 'async',
enforce: true,
priority: 50,
},
},
});
};

// granular code splitting only for client builds
if (target !== 'node') {
// get resolved paths for shared modules and their dependencies
const sharedModulesPaths = resolveFrameworksPaths(
path.resolve(rootDir, root),
Object.keys(sharedModules)
);

const granular: Record<string, any> = {
// we don't want to include MF shared deps
test(mod: webpack.Module) {
const resource = mod.nameForCondition && mod.nameForCondition();

if (!resource) {
return false;
}

return sharedModulesPaths.every((packagePath) => !resource.startsWith(packagePath));
},
chunks: 'async',
// in some cases this group has priority over styles group, idk why, so decide to specify modules type explicitly
type: 'javascript/auto',
minChunks: 2,
minSize: 20000,
reuseExistingChunk: true,
maxInitialRequests: 10,
maxAsyncRequests: 20,
priority: 20,
};

// too slow for development, default names is fast, but have one problem -
// we can find shared chunk filenames only in `chunks` stats property, not in `assetsByChunkName`
// https://github.com/webpack/webpack/issues/14433#issuecomment-938468513
if (env === 'production') {
granular.name = (module: webpack.Module, chunks: webpack.Chunk[] = []) => {
return crypto
.createHash('sha1')
.update(
chunks.reduce((acc: string, chunk: webpack.Chunk) => {
return acc + chunk.name;
}, '')
)
.digest('hex')
.substring(0, 16);
};
}

webpackSplitChunks.cacheGroups.granular = granular;
}

config.optimization.splitChunks(webpackSplitChunks);

config.plugin('module-federation').use(UniversalFederationPlugin, [
{
Expand Down Expand Up @@ -100,7 +160,7 @@ export default (configManager: ConfigManager<ChildAppConfigEntry>) => (config: C
.split(path.win32.sep)
.join(path.posix.sep),
},
shared: getSharedModules(configManager),
shared: sharedModules,
} as UniversalFederationPluginOptions,
]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ export class ModuleFederationFixRange implements webpack.WebpackPluginInstance {
if (requiredVersion && this.flexibleTramvaiVersions) {
const isTramvai = isUnifiedVersion(name) || isDependantLib(name);

if (isTramvai && requiredVersion[0] > 2) {
// exclude local stub versions, because `^0.0.0-stub` will have lowest priority and unexpected versions can be used
if (isTramvai && requiredVersion[0] > 2 && resolvedVersion !== '0.0.0-stub') {
// 1 is used for `^` range modifier
// see https://github.com/webpack/webpack/blob/56363993156e06a1230c9759eba277a22e6b6604/lib/util/semver.js#LL235C20-L235C20
requiredVersion[0] = 1;
Expand Down
Loading

0 comments on commit 599672c

Please sign in to comment.