@umijs/mfsu 4.0.0-beta.9 → 4.0.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/babelPlugins/awaitImport/checkMatch.d.ts +2 -1
- package/dist/babelPlugins/awaitImport/checkMatch.js +10 -4
- package/dist/dep/dep.js +3 -3
- package/dist/depBuilder/depBuilder.js +3 -6
- package/dist/depBuilder/getESBuildEntry.js +2 -5
- package/dist/depInfo.js +2 -0
- package/dist/esbuildHandlers/autoCssModules.d.ts +2 -0
- package/dist/esbuildHandlers/autoCssModules.js +24 -0
- package/dist/esbuildHandlers/autoExport.d.ts +6 -0
- package/dist/esbuildHandlers/autoExport.js +9 -0
- package/dist/esbuildHandlers/awaitImport/index.d.ts +12 -0
- package/dist/esbuildHandlers/awaitImport/index.js +44 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/loader/esbuild.d.ts +5 -0
- package/dist/loader/esbuild.js +54 -0
- package/dist/mfsu.d.ts +8 -3
- package/dist/mfsu.js +180 -84
- package/dist/moduleGraph.d.ts +1 -0
- package/dist/moduleGraph.js +9 -1
- package/dist/types.d.ts +12 -0
- package/package.json +6 -6
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import * as Babel from '@umijs/bundler-utils/compiled/babel/core';
|
|
2
2
|
import type { IOpts } from './awaitImport';
|
|
3
|
-
export declare function checkMatch({ value, path, opts, isExportAll, depth, cache, }: {
|
|
3
|
+
export declare function checkMatch({ value, path, opts, isExportAll, depth, cache, filename, }: {
|
|
4
4
|
value: string;
|
|
5
5
|
path?: Babel.NodePath;
|
|
6
6
|
opts?: IOpts;
|
|
7
7
|
isExportAll?: boolean;
|
|
8
8
|
depth?: number;
|
|
9
9
|
cache?: Map<string, any>;
|
|
10
|
+
filename?: string;
|
|
10
11
|
}): {
|
|
11
12
|
isMatch: boolean;
|
|
12
13
|
replaceValue: string;
|
|
@@ -12,7 +12,10 @@ const isExternals_1 = require("./isExternals");
|
|
|
12
12
|
// const UNMATCH_LIBS = ['umi', 'dumi', '@alipay/bigfish'];
|
|
13
13
|
const RE_NODE_MODULES = /node_modules/;
|
|
14
14
|
const RE_UMI_LOCAL_DEV = /umi(-next)?\/packages\//;
|
|
15
|
-
function
|
|
15
|
+
function isUmiLocalDev(path) {
|
|
16
|
+
return RE_UMI_LOCAL_DEV.test((0, utils_1.winPath)(path));
|
|
17
|
+
}
|
|
18
|
+
function checkMatch({ value, path, opts, isExportAll, depth, cache, filename, }) {
|
|
16
19
|
var _a, _b;
|
|
17
20
|
let isMatch;
|
|
18
21
|
let replaceValue = '';
|
|
@@ -20,6 +23,8 @@ function checkMatch({ value, path, opts, isExportAll, depth, cache, }) {
|
|
|
20
23
|
(0, assert_1.default)(depth <= 10, `endless loop detected in checkMatch, please check your alias config.`);
|
|
21
24
|
opts = opts || {};
|
|
22
25
|
const remoteName = opts.remoteName || 'mf';
|
|
26
|
+
// FIXME: hard code for vite mode
|
|
27
|
+
value = value.replace(/^@fs\//, '/');
|
|
23
28
|
if (
|
|
24
29
|
// unMatch specified libs
|
|
25
30
|
((_a = opts.unMatchLibs) === null || _a === void 0 ? void 0 : _a.includes(value)) ||
|
|
@@ -38,7 +43,7 @@ function checkMatch({ value, path, opts, isExportAll, depth, cache, }) {
|
|
|
38
43
|
isMatch = false;
|
|
39
44
|
}
|
|
40
45
|
else if ((0, path_1.isAbsolute)(value)) {
|
|
41
|
-
isMatch = RE_NODE_MODULES.test(value) ||
|
|
46
|
+
isMatch = RE_NODE_MODULES.test(value) || isUmiLocalDev(value);
|
|
42
47
|
}
|
|
43
48
|
else {
|
|
44
49
|
const aliasedPath = (0, getAliasedPath_1.getAliasedPath)({
|
|
@@ -53,6 +58,7 @@ function checkMatch({ value, path, opts, isExportAll, depth, cache, }) {
|
|
|
53
58
|
isExportAll,
|
|
54
59
|
depth: depth + 1,
|
|
55
60
|
cache,
|
|
61
|
+
filename,
|
|
56
62
|
});
|
|
57
63
|
}
|
|
58
64
|
else {
|
|
@@ -63,10 +69,10 @@ function checkMatch({ value, path, opts, isExportAll, depth, cache, }) {
|
|
|
63
69
|
isMatch = !!(opts.exportAllMembers && value in opts.exportAllMembers);
|
|
64
70
|
}
|
|
65
71
|
if (isMatch) {
|
|
66
|
-
replaceValue = `${remoteName}/${value}`;
|
|
72
|
+
replaceValue = `${remoteName}/${(0, utils_1.winPath)(value)}`;
|
|
67
73
|
}
|
|
68
74
|
// @ts-ignore
|
|
69
|
-
const file = path === null || path === void 0 ? void 0 : path.hub.file.opts.filename;
|
|
75
|
+
const file = (path === null || path === void 0 ? void 0 : path.hub.file.opts.filename) || filename;
|
|
70
76
|
(_b = opts.onTransformDeps) === null || _b === void 0 ? void 0 : _b.call(opts, {
|
|
71
77
|
sourceValue: value,
|
|
72
78
|
replaceValue,
|
package/dist/dep/dep.js
CHANGED
|
@@ -37,10 +37,10 @@ function resolve(context, path) {
|
|
|
37
37
|
}
|
|
38
38
|
class Dep {
|
|
39
39
|
constructor(opts) {
|
|
40
|
-
this.file = opts.file;
|
|
40
|
+
this.file = (0, utils_1.winPath)(opts.file);
|
|
41
41
|
this.version = opts.version;
|
|
42
42
|
this.cwd = opts.cwd;
|
|
43
|
-
this.shortFile = this.file
|
|
43
|
+
this.shortFile = this.file;
|
|
44
44
|
this.normalizedFile = this.shortFile.replace(/\//g, '_').replace(/:/g, '_');
|
|
45
45
|
this.filePath = `${constants_1.MF_VA_PREFIX}${this.normalizedFile}.js`;
|
|
46
46
|
this.mfsu = opts.mfsu;
|
|
@@ -98,7 +98,7 @@ export * from '${this.file}';
|
|
|
98
98
|
const dep = (0, path_1.isAbsolute)(opts.dep)
|
|
99
99
|
? opts.dep
|
|
100
100
|
: (0, path_1.join)(opts.cwd, 'node_modules', opts.dep);
|
|
101
|
-
const pkg = utils_1.pkgUp.
|
|
101
|
+
const pkg = utils_1.pkgUp.pkgUpSync({
|
|
102
102
|
cwd: dep,
|
|
103
103
|
});
|
|
104
104
|
(0, assert_1.default)(pkg, `package.json not found for ${opts.dep}`);
|
|
@@ -63,11 +63,7 @@ class DepBuilder {
|
|
|
63
63
|
entry: {
|
|
64
64
|
[`${constants_1.MF_VA_PREFIX}remoteEntry`]: entryPath,
|
|
65
65
|
},
|
|
66
|
-
config: {
|
|
67
|
-
outputPath: tmpDir,
|
|
68
|
-
alias: this.opts.mfsu.alias,
|
|
69
|
-
externals: this.opts.mfsu.externals,
|
|
70
|
-
},
|
|
66
|
+
config: Object.assign(Object.assign({}, this.opts.mfsu.opts.depBuildConfig), { outputPath: tmpDir, alias: this.opts.mfsu.alias, externals: this.opts.mfsu.externals }),
|
|
71
67
|
inlineStyle: true,
|
|
72
68
|
});
|
|
73
69
|
utils_1.logger.event(`[mfsu] compiled with esbuild successfully in ${+new Date() - date} ms`);
|
|
@@ -102,6 +98,7 @@ class DepBuilder {
|
|
|
102
98
|
writeMFFiles(opts) {
|
|
103
99
|
return __awaiter(this, void 0, void 0, function* () {
|
|
104
100
|
const tmpBase = this.opts.mfsu.opts.tmpBase;
|
|
101
|
+
utils_1.fsExtra.mkdirpSync(tmpBase);
|
|
105
102
|
// expose files
|
|
106
103
|
for (const dep of opts.deps) {
|
|
107
104
|
const content = yield dep.buildExposeContent();
|
|
@@ -148,7 +145,7 @@ class DepBuilder {
|
|
|
148
145
|
webpack: this.opts.mfsu.opts.implementor,
|
|
149
146
|
}));
|
|
150
147
|
const exposes = opts.deps.reduce((memo, dep) => {
|
|
151
|
-
memo[`./${dep.
|
|
148
|
+
memo[`./${dep.file}`] = (0, path_1.join)(this.opts.mfsu.opts.tmpBase, dep.filePath);
|
|
152
149
|
return memo;
|
|
153
150
|
}, {});
|
|
154
151
|
depConfig.plugins.push(new this.opts.mfsu.opts.implementor.container.ModuleFederationPlugin({
|
|
@@ -299,15 +299,12 @@ ${opts.deps.map(getDepModuleStr).join(',\n')}
|
|
|
299
299
|
`;
|
|
300
300
|
}
|
|
301
301
|
exports.getESBuildEntry = getESBuildEntry;
|
|
302
|
-
function normalizeFile(file) {
|
|
303
|
-
return file.replace(/\//g, '_');
|
|
304
|
-
}
|
|
305
302
|
function getDepModuleStr(dep) {
|
|
306
303
|
return `
|
|
307
304
|
"./${dep.file}": function() {
|
|
308
305
|
return new Promise(resolve => {
|
|
309
|
-
import('./${constants_1.MF_VA_PREFIX}${
|
|
310
|
-
resolve(() => module);
|
|
306
|
+
import('./${constants_1.MF_VA_PREFIX}${dep.normalizedFile}.js').then(module => {
|
|
307
|
+
resolve(() => module.default || module);
|
|
311
308
|
});
|
|
312
309
|
})
|
|
313
310
|
}
|
package/dist/depInfo.js
CHANGED
|
@@ -27,6 +27,7 @@ class DepInfo {
|
|
|
27
27
|
}
|
|
28
28
|
loadCache() {
|
|
29
29
|
if ((0, fs_1.existsSync)(this.cacheFilePath)) {
|
|
30
|
+
utils_1.logger.info('MFSU restore cache');
|
|
30
31
|
const { cacheDependency, moduleGraph } = JSON.parse((0, fs_1.readFileSync)(this.cacheFilePath, 'utf-8'));
|
|
31
32
|
this.cacheDependency = cacheDependency;
|
|
32
33
|
this.moduleGraph.restore(moduleGraph);
|
|
@@ -34,6 +35,7 @@ class DepInfo {
|
|
|
34
35
|
}
|
|
35
36
|
writeCache() {
|
|
36
37
|
utils_1.fsExtra.mkdirpSync((0, path_1.dirname)(this.cacheFilePath));
|
|
38
|
+
utils_1.logger.info('MFSU write cache');
|
|
37
39
|
(0, fs_1.writeFileSync)(this.cacheFilePath, JSON.stringify({
|
|
38
40
|
cacheDependency: this.cacheDependency,
|
|
39
41
|
moduleGraph: this.moduleGraph.toJSON(),
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.autoCssModulesHandler = void 0;
|
|
4
|
+
const utils_1 = require("@umijs/utils");
|
|
5
|
+
const CSS_MODULES_QUERY = '?modules';
|
|
6
|
+
const QUERY_LENGTH = CSS_MODULES_QUERY.length;
|
|
7
|
+
function autoCssModulesHandler(opts) {
|
|
8
|
+
let { code } = opts;
|
|
9
|
+
let offset = 0;
|
|
10
|
+
opts.imports.forEach((i) => {
|
|
11
|
+
if (i.d < 0 && (0, utils_1.isStyleFile)({ filename: i.n })) {
|
|
12
|
+
// import x from './index.less'
|
|
13
|
+
// => import x from '
|
|
14
|
+
const importSegment = code.substring(i.ss + offset, i.s + offset);
|
|
15
|
+
// is css module
|
|
16
|
+
if (~importSegment.indexOf(' from')) {
|
|
17
|
+
code = `${code.substring(0, i.e + offset)}${CSS_MODULES_QUERY}${code.substring(i.e + offset)}`;
|
|
18
|
+
offset += QUERY_LENGTH;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
return code;
|
|
23
|
+
}
|
|
24
|
+
exports.autoCssModulesHandler = autoCssModulesHandler;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ImportSpecifier } from '@umijs/bundler-utils/compiled/es-module-lexer';
|
|
2
|
+
interface IParams {
|
|
3
|
+
cache: Map<string, any>;
|
|
4
|
+
opts: any;
|
|
5
|
+
}
|
|
6
|
+
interface IOpts {
|
|
7
|
+
code: string;
|
|
8
|
+
imports: ImportSpecifier[];
|
|
9
|
+
filePath: string;
|
|
10
|
+
}
|
|
11
|
+
export default function getAwaitImportHandler(params: IParams): (opts: IOpts) => string;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const checkMatch_1 = require("../../babelPlugins/awaitImport/checkMatch");
|
|
4
|
+
function getAwaitImportHandler(params) {
|
|
5
|
+
return function awaitImportHandler(opts) {
|
|
6
|
+
var _a, _b;
|
|
7
|
+
let offset = 0;
|
|
8
|
+
let { code } = opts;
|
|
9
|
+
const { filePath, imports } = opts;
|
|
10
|
+
imports.forEach((i) => {
|
|
11
|
+
if (!i.n)
|
|
12
|
+
return;
|
|
13
|
+
const isLazyImport = i.d > 0;
|
|
14
|
+
const from = i.n;
|
|
15
|
+
const { isMatch, replaceValue } = (0, checkMatch_1.checkMatch)({
|
|
16
|
+
cache: params.cache,
|
|
17
|
+
value: from,
|
|
18
|
+
opts: params.opts,
|
|
19
|
+
filename: filePath,
|
|
20
|
+
});
|
|
21
|
+
if (isMatch) {
|
|
22
|
+
// case: import x from './index.ts';
|
|
23
|
+
// import('./index.ts');
|
|
24
|
+
// import x from '
|
|
25
|
+
// import(
|
|
26
|
+
const preSeg = code.substring(0, i.s + offset);
|
|
27
|
+
// ';
|
|
28
|
+
// );
|
|
29
|
+
const tailSeg = code.substring(i.e + offset);
|
|
30
|
+
const quote = isLazyImport ? '"' : '';
|
|
31
|
+
code = `${preSeg}${quote}${replaceValue}${quote}${tailSeg}`;
|
|
32
|
+
offset += replaceValue.length - from.length;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
if (params.cache.has(filePath)) {
|
|
36
|
+
(_b = (_a = params.opts).onCollect) === null || _b === void 0 ? void 0 : _b.call(_a, {
|
|
37
|
+
file: filePath,
|
|
38
|
+
data: params.cache.get(filePath),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return code;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
exports.default = getAwaitImportHandler;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -10,5 +10,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
10
10
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.esbuildLoader = void 0;
|
|
13
14
|
__exportStar(require("./constants"), exports);
|
|
15
|
+
__exportStar(require("./esbuildHandlers/autoCssModules"), exports);
|
|
16
|
+
// for independent use `esbuild-loader`
|
|
17
|
+
var esbuild_1 = require("./loader/esbuild");
|
|
18
|
+
Object.defineProperty(exports, "esbuildLoader", { enumerable: true, get: function () { return esbuild_1.esbuildLoader; } });
|
|
14
19
|
__exportStar(require("./mfsu"), exports);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { LoaderContext } from 'webpack';
|
|
2
|
+
import type { IEsbuildLoaderOpts } from '../types';
|
|
3
|
+
declare function esbuildTranspiler(this: LoaderContext<IEsbuildLoaderOpts>, source: string): Promise<void>;
|
|
4
|
+
export default esbuildTranspiler;
|
|
5
|
+
export declare const esbuildLoader: string;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
12
|
+
var t = {};
|
|
13
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
14
|
+
t[p] = s[p];
|
|
15
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
16
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
17
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
18
|
+
t[p[i]] = s[p[i]];
|
|
19
|
+
}
|
|
20
|
+
return t;
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.esbuildLoader = void 0;
|
|
24
|
+
const es_module_lexer_1 = require("@umijs/bundler-utils/compiled/es-module-lexer");
|
|
25
|
+
const esbuild_1 = require("@umijs/bundler-utils/compiled/esbuild");
|
|
26
|
+
const path_1 = require("path");
|
|
27
|
+
function esbuildTranspiler(source) {
|
|
28
|
+
var _a;
|
|
29
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
const done = this.async();
|
|
31
|
+
const options = this.getOptions();
|
|
32
|
+
const { handler = [], implementation } = options, otherOptions = __rest(options, ["handler", "implementation"]);
|
|
33
|
+
const transform = (implementation === null || implementation === void 0 ? void 0 : implementation.transform) || esbuild_1.transform;
|
|
34
|
+
const filePath = this.resourcePath;
|
|
35
|
+
const ext = (0, path_1.extname)(filePath).slice(1);
|
|
36
|
+
const transformOptions = Object.assign(Object.assign({}, otherOptions), { target: (_a = options.target) !== null && _a !== void 0 ? _a : 'es2015', loader: ext !== null && ext !== void 0 ? ext : 'js', sourcemap: this.sourceMap, sourcefile: filePath });
|
|
37
|
+
try {
|
|
38
|
+
let { code, map } = yield transform(source, transformOptions);
|
|
39
|
+
if (handler.length) {
|
|
40
|
+
yield es_module_lexer_1.init;
|
|
41
|
+
handler.forEach((handle) => {
|
|
42
|
+
const [imports, exports] = (0, es_module_lexer_1.parse)(code);
|
|
43
|
+
code = handle({ code, imports, exports, filePath });
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
done(null, code, map && JSON.parse(map));
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
done(error);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
exports.default = esbuildTranspiler;
|
|
54
|
+
exports.esbuildLoader = __filename;
|
package/dist/mfsu.d.ts
CHANGED
|
@@ -14,8 +14,10 @@ interface IOpts {
|
|
|
14
14
|
mode?: Mode;
|
|
15
15
|
tmpBase?: string;
|
|
16
16
|
unMatchLibs?: string[];
|
|
17
|
+
runtimePublicPath?: boolean | string;
|
|
17
18
|
implementor: typeof webpack;
|
|
18
19
|
buildDepWithESBuild?: boolean;
|
|
20
|
+
depBuildConfig: any;
|
|
19
21
|
}
|
|
20
22
|
export declare class MFSU {
|
|
21
23
|
opts: IOpts;
|
|
@@ -25,13 +27,15 @@ export declare class MFSU {
|
|
|
25
27
|
depBuilder: DepBuilder;
|
|
26
28
|
depConfig: Configuration | null;
|
|
27
29
|
constructor(opts: IOpts);
|
|
30
|
+
asyncImport(content: string): string;
|
|
28
31
|
setWebpackConfig(opts: {
|
|
29
32
|
config: Configuration;
|
|
30
33
|
depConfig: Configuration;
|
|
31
|
-
}): void
|
|
34
|
+
}): Promise<void>;
|
|
32
35
|
buildDeps(): Promise<void>;
|
|
33
36
|
getMiddlewares(): ((req: Request, res: Response, next: NextFunction) => void)[];
|
|
34
|
-
|
|
37
|
+
private getAwaitImportCollectOpts;
|
|
38
|
+
getBabelPlugins(): (typeof autoExport | ({
|
|
35
39
|
onTransformDeps: () => void;
|
|
36
40
|
onCollect: ({ file, data, }: {
|
|
37
41
|
file: string;
|
|
@@ -49,6 +53,7 @@ export declare class MFSU {
|
|
|
49
53
|
remoteName: string | undefined;
|
|
50
54
|
alias: Record<string, string>;
|
|
51
55
|
externals: (Function | Record<string, string>)[];
|
|
52
|
-
})[])[];
|
|
56
|
+
} | typeof awaitImport)[])[];
|
|
57
|
+
getEsbuildLoaderHandler(): any[];
|
|
53
58
|
}
|
|
54
59
|
export {};
|
package/dist/mfsu.js
CHANGED
|
@@ -13,7 +13,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.MFSU = void 0;
|
|
16
|
+
const bundler_utils_1 = require("@umijs/bundler-utils");
|
|
16
17
|
const utils_1 = require("@umijs/utils");
|
|
18
|
+
const assert_1 = __importDefault(require("assert"));
|
|
17
19
|
const fs_1 = require("fs");
|
|
18
20
|
const path_1 = require("path");
|
|
19
21
|
const mrmime_1 = require("../compiled/mrmime");
|
|
@@ -26,6 +28,8 @@ const constants_1 = require("./constants");
|
|
|
26
28
|
const dep_1 = require("./dep/dep");
|
|
27
29
|
const depBuilder_1 = require("./depBuilder/depBuilder");
|
|
28
30
|
const depInfo_1 = require("./depInfo");
|
|
31
|
+
const autoExport_2 = __importDefault(require("./esbuildHandlers/autoExport"));
|
|
32
|
+
const awaitImport_2 = __importDefault(require("./esbuildHandlers/awaitImport"));
|
|
29
33
|
const types_1 = require("./types");
|
|
30
34
|
const makeArray_1 = require("./utils/makeArray");
|
|
31
35
|
const buildDepPlugin_1 = require("./webpackPlugins/buildDepPlugin");
|
|
@@ -46,67 +50,151 @@ class MFSU {
|
|
|
46
50
|
this.depBuilder = new depBuilder_1.DepBuilder({ mfsu: this });
|
|
47
51
|
this.depInfo.loadCache();
|
|
48
52
|
}
|
|
53
|
+
// swc don't support top-level await
|
|
54
|
+
// ref: https://github.com/vercel/next.js/issues/31054
|
|
55
|
+
asyncImport(content) {
|
|
56
|
+
return `await import('${(0, utils_1.winPath)(content)}');`;
|
|
57
|
+
// return `(async () => await import('${content}'))();`;
|
|
58
|
+
}
|
|
49
59
|
setWebpackConfig(opts) {
|
|
50
60
|
var _a;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
opts.config
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
const { mfName } = this.opts;
|
|
63
|
+
/**
|
|
64
|
+
* config
|
|
65
|
+
*/
|
|
66
|
+
// set alias and externals with reference for babel plugin
|
|
67
|
+
Object.assign(this.alias, ((_a = opts.config.resolve) === null || _a === void 0 ? void 0 : _a.alias) || {});
|
|
68
|
+
this.externals.push(...(0, makeArray_1.makeArray)(opts.config.externals || []));
|
|
69
|
+
// entry
|
|
70
|
+
const entry = {};
|
|
71
|
+
const virtualModules = {};
|
|
72
|
+
// ensure entry object type
|
|
73
|
+
const entryObject = utils_1.lodash.isString(opts.config.entry)
|
|
74
|
+
? { default: [opts.config.entry] }
|
|
75
|
+
: opts.config.entry;
|
|
76
|
+
(0, assert_1.default)(utils_1.lodash.isPlainObject(entryObject), `webpack config 'entry' value must be a string or an object.`);
|
|
77
|
+
for (const key of Object.keys(entryObject)) {
|
|
78
|
+
const virtualPath = `./mfsu-virtual-entry/${key}.js`;
|
|
79
|
+
const virtualContent = [];
|
|
80
|
+
let index = 1;
|
|
81
|
+
let hasDefaultExport = false;
|
|
82
|
+
const entryFiles = utils_1.lodash.isArray(entryObject[key])
|
|
83
|
+
? entryObject[key]
|
|
84
|
+
: [entryObject[key]];
|
|
85
|
+
for (let entry of entryFiles) {
|
|
86
|
+
// ensure entry is a file
|
|
87
|
+
if ((0, fs_1.statSync)(entry).isDirectory()) {
|
|
88
|
+
const realEntry = (0, utils_1.tryPaths)([
|
|
89
|
+
(0, path_1.join)(entry, 'index.tsx'),
|
|
90
|
+
(0, path_1.join)(entry, 'index.ts'),
|
|
91
|
+
]);
|
|
92
|
+
(0, assert_1.default)(realEntry, `entry file not found, please configure the specific entry path. (e.g. 'src/index.tsx')`);
|
|
93
|
+
entry = realEntry;
|
|
94
|
+
}
|
|
95
|
+
const content = (0, fs_1.readFileSync)(entry, 'utf-8');
|
|
96
|
+
const [_imports, exports] = yield (0, bundler_utils_1.parseModule)({ content, path: entry });
|
|
97
|
+
if (exports.length) {
|
|
98
|
+
virtualContent.push(`const k${index} = ${this.asyncImport(entry)}`);
|
|
99
|
+
for (const exportName of exports) {
|
|
100
|
+
if (exportName === 'default') {
|
|
101
|
+
hasDefaultExport = true;
|
|
102
|
+
virtualContent.push(`export default k${index}.${exportName}`);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
virtualContent.push(`export const ${exportName} = k${index}.${exportName}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
virtualContent.push(this.asyncImport(entry));
|
|
111
|
+
}
|
|
112
|
+
index += 1;
|
|
113
|
+
}
|
|
114
|
+
if (!hasDefaultExport) {
|
|
115
|
+
virtualContent.push(`export default 1;`);
|
|
116
|
+
}
|
|
117
|
+
virtualModules[virtualPath] = virtualContent.join('\n');
|
|
118
|
+
entry[key] = virtualPath;
|
|
119
|
+
}
|
|
120
|
+
opts.config.entry = entry;
|
|
121
|
+
// plugins
|
|
122
|
+
opts.config.plugins = opts.config.plugins || [];
|
|
123
|
+
// support publicPath auto
|
|
124
|
+
let publicPath = opts.config.output.publicPath;
|
|
125
|
+
if (publicPath === 'auto') {
|
|
126
|
+
publicPath = '/';
|
|
127
|
+
}
|
|
128
|
+
opts.config.plugins.push(...[
|
|
129
|
+
new webpack_virtual_modules_1.default(virtualModules),
|
|
130
|
+
new this.opts.implementor.container.ModuleFederationPlugin({
|
|
131
|
+
name: '__',
|
|
132
|
+
remotes: {
|
|
133
|
+
[mfName]: this.opts.runtimePublicPath
|
|
134
|
+
? // ref:
|
|
135
|
+
// https://webpack.js.org/concepts/module-federation/#promise-based-dynamic-remotes
|
|
136
|
+
`
|
|
137
|
+
promise new Promise(resolve => {
|
|
138
|
+
const remoteUrlWithVersion = window.publicPath + '${constants_1.REMOTE_FILE_FULL}';
|
|
139
|
+
const script = document.createElement('script');
|
|
140
|
+
script.src = remoteUrlWithVersion;
|
|
141
|
+
script.onload = () => {
|
|
142
|
+
// the injected script has loaded and is available on window
|
|
143
|
+
// we can now resolve this Promise
|
|
144
|
+
const proxy = {
|
|
145
|
+
get: (request) => window['${mfName}'].get(request),
|
|
146
|
+
init: (arg) => {
|
|
147
|
+
try {
|
|
148
|
+
return window['${mfName}'].init(arg);
|
|
149
|
+
} catch(e) {
|
|
150
|
+
console.log('remote container already initialized');
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
resolve(proxy);
|
|
155
|
+
}
|
|
156
|
+
// inject this script with the src set to the versioned remoteEntry.js
|
|
157
|
+
document.head.appendChild(script);
|
|
158
|
+
})
|
|
159
|
+
`.trimLeft()
|
|
160
|
+
: `${mfName}@${publicPath}${constants_1.REMOTE_FILE_FULL}`,
|
|
161
|
+
},
|
|
162
|
+
}),
|
|
163
|
+
new buildDepPlugin_1.BuildDepPlugin({
|
|
164
|
+
onCompileDone: () => {
|
|
165
|
+
this.buildDeps().catch((e) => {
|
|
166
|
+
utils_1.logger.error(e);
|
|
167
|
+
});
|
|
168
|
+
},
|
|
169
|
+
}),
|
|
170
|
+
new writeCachePlugin_1.WriteCachePlugin({
|
|
171
|
+
onWriteCache: utils_1.lodash.debounce(() => {
|
|
172
|
+
this.depInfo.writeCache();
|
|
173
|
+
}, 300),
|
|
174
|
+
}),
|
|
175
|
+
]);
|
|
176
|
+
// ensure topLevelAwait enabled
|
|
177
|
+
utils_1.lodash.set(opts.config, 'experiments.topLevelAwait', true);
|
|
178
|
+
/**
|
|
179
|
+
* depConfig
|
|
180
|
+
*/
|
|
181
|
+
this.depConfig = opts.depConfig;
|
|
69
182
|
});
|
|
70
|
-
opts.config.entry = entry;
|
|
71
|
-
// plugins
|
|
72
|
-
opts.config.plugins = opts.config.plugins || [];
|
|
73
|
-
opts.config.plugins.push(...[
|
|
74
|
-
new webpack_virtual_modules_1.default(virtualModules),
|
|
75
|
-
new this.opts.implementor.container.ModuleFederationPlugin({
|
|
76
|
-
name: '__',
|
|
77
|
-
remotes: {
|
|
78
|
-
// TODO: support runtime public path
|
|
79
|
-
[mfName]: `${mfName}@${opts.config.output.publicPath}${constants_1.REMOTE_FILE_FULL}`,
|
|
80
|
-
},
|
|
81
|
-
}),
|
|
82
|
-
new buildDepPlugin_1.BuildDepPlugin({
|
|
83
|
-
onCompileDone: () => {
|
|
84
|
-
this.buildDeps().catch((e) => {
|
|
85
|
-
utils_1.logger.error(e);
|
|
86
|
-
});
|
|
87
|
-
},
|
|
88
|
-
}),
|
|
89
|
-
new writeCachePlugin_1.WriteCachePlugin({
|
|
90
|
-
onWriteCache: () => {
|
|
91
|
-
this.depInfo.writeCache();
|
|
92
|
-
},
|
|
93
|
-
}),
|
|
94
|
-
]);
|
|
95
|
-
/**
|
|
96
|
-
* depConfig
|
|
97
|
-
*/
|
|
98
|
-
this.depConfig = opts.depConfig;
|
|
99
183
|
}
|
|
100
184
|
buildDeps() {
|
|
101
185
|
return __awaiter(this, void 0, void 0, function* () {
|
|
102
|
-
if (!this.depInfo.shouldBuild())
|
|
186
|
+
if (!this.depInfo.shouldBuild()) {
|
|
187
|
+
utils_1.logger.info('MFSU skip buildDeps');
|
|
103
188
|
return;
|
|
189
|
+
}
|
|
104
190
|
this.depInfo.snapshot();
|
|
105
191
|
const deps = dep_1.Dep.buildDeps({
|
|
106
192
|
deps: this.depInfo.moduleGraph.depSnapshotModules,
|
|
107
193
|
cwd: this.opts.cwd,
|
|
108
194
|
mfsu: this,
|
|
109
195
|
});
|
|
196
|
+
utils_1.logger.info('MFSU buildDeps');
|
|
197
|
+
utils_1.logger.debug(deps.map((dep) => dep.file).join(', '));
|
|
110
198
|
yield this.depBuilder.build({
|
|
111
199
|
deps,
|
|
112
200
|
});
|
|
@@ -126,7 +214,7 @@ class MFSU {
|
|
|
126
214
|
}
|
|
127
215
|
res.setHeader('content-type', (0, mrmime_1.lookup)((0, path_1.extname)(req.path)) || 'text/plain');
|
|
128
216
|
const relativePath = req.path.replace(new RegExp(`^${publicPath}`), '/');
|
|
129
|
-
const content = (0, fs_1.readFileSync)((0, path_1.join)(this.opts.tmpBase, relativePath)
|
|
217
|
+
const content = (0, fs_1.readFileSync)((0, path_1.join)(this.opts.tmpBase, relativePath));
|
|
130
218
|
res.send(content);
|
|
131
219
|
});
|
|
132
220
|
}
|
|
@@ -136,43 +224,51 @@ class MFSU {
|
|
|
136
224
|
},
|
|
137
225
|
];
|
|
138
226
|
}
|
|
227
|
+
getAwaitImportCollectOpts() {
|
|
228
|
+
return {
|
|
229
|
+
onTransformDeps: () => { },
|
|
230
|
+
onCollect: ({ file, data, }) => {
|
|
231
|
+
this.depInfo.moduleGraph.onFileChange({
|
|
232
|
+
file,
|
|
233
|
+
// @ts-ignore
|
|
234
|
+
deps: [
|
|
235
|
+
...Array.from(data.matched).map((item) => ({
|
|
236
|
+
file: item.sourceValue,
|
|
237
|
+
isDependency: true,
|
|
238
|
+
version: dep_1.Dep.getDepVersion({
|
|
239
|
+
dep: item.sourceValue,
|
|
240
|
+
cwd: this.opts.cwd,
|
|
241
|
+
}),
|
|
242
|
+
})),
|
|
243
|
+
...Array.from(data.unMatched).map((item) => ({
|
|
244
|
+
file: (0, getRealPath_1.getRealPath)({
|
|
245
|
+
file,
|
|
246
|
+
dep: item.sourceValue,
|
|
247
|
+
}),
|
|
248
|
+
isDependency: false,
|
|
249
|
+
})),
|
|
250
|
+
],
|
|
251
|
+
});
|
|
252
|
+
},
|
|
253
|
+
exportAllMembers: this.opts.exportAllMembers,
|
|
254
|
+
unMatchLibs: this.opts.unMatchLibs,
|
|
255
|
+
remoteName: this.opts.mfName,
|
|
256
|
+
alias: this.alias,
|
|
257
|
+
externals: this.externals,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
139
260
|
getBabelPlugins() {
|
|
261
|
+
return [autoExport_1.default, [awaitImport_1.default, this.getAwaitImportCollectOpts()]];
|
|
262
|
+
}
|
|
263
|
+
getEsbuildLoaderHandler() {
|
|
264
|
+
const cache = new Map();
|
|
265
|
+
const checkOpts = this.getAwaitImportCollectOpts();
|
|
140
266
|
return [
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
onCollect: ({ file, data, }) => {
|
|
147
|
-
this.depInfo.moduleGraph.onFileChange({
|
|
148
|
-
file,
|
|
149
|
-
// @ts-ignore
|
|
150
|
-
deps: [
|
|
151
|
-
...Array.from(data.matched).map((item) => ({
|
|
152
|
-
file: item.sourceValue,
|
|
153
|
-
isDependency: true,
|
|
154
|
-
version: dep_1.Dep.getDepVersion({
|
|
155
|
-
dep: item.sourceValue,
|
|
156
|
-
cwd: this.opts.cwd,
|
|
157
|
-
}),
|
|
158
|
-
})),
|
|
159
|
-
...Array.from(data.unMatched).map((item) => ({
|
|
160
|
-
file: (0, getRealPath_1.getRealPath)({
|
|
161
|
-
file,
|
|
162
|
-
dep: item.sourceValue,
|
|
163
|
-
}),
|
|
164
|
-
isDependency: false,
|
|
165
|
-
})),
|
|
166
|
-
],
|
|
167
|
-
});
|
|
168
|
-
},
|
|
169
|
-
exportAllMembers: this.opts.exportAllMembers,
|
|
170
|
-
unMatchLibs: this.opts.unMatchLibs,
|
|
171
|
-
remoteName: this.opts.mfName,
|
|
172
|
-
alias: this.alias,
|
|
173
|
-
externals: this.externals,
|
|
174
|
-
},
|
|
175
|
-
],
|
|
267
|
+
autoExport_2.default,
|
|
268
|
+
(0, awaitImport_2.default)({
|
|
269
|
+
cache,
|
|
270
|
+
opts: checkOpts,
|
|
271
|
+
}),
|
|
176
272
|
];
|
|
177
273
|
}
|
|
178
274
|
}
|
package/dist/moduleGraph.d.ts
CHANGED
package/dist/moduleGraph.js
CHANGED
|
@@ -20,7 +20,12 @@ class ModuleGraph {
|
|
|
20
20
|
this.rootModules = new Set();
|
|
21
21
|
}
|
|
22
22
|
restore(data) {
|
|
23
|
+
let fileMap = new Map();
|
|
23
24
|
const addNode = ({ file, importer }) => {
|
|
25
|
+
// fix circular dependency
|
|
26
|
+
if (fileMap.has(file))
|
|
27
|
+
return;
|
|
28
|
+
fileMap.set(file, true);
|
|
24
29
|
const mod = new ModuleNode(file);
|
|
25
30
|
let isDependency = false;
|
|
26
31
|
let info;
|
|
@@ -33,8 +38,10 @@ class ModuleGraph {
|
|
|
33
38
|
}
|
|
34
39
|
if (info.isRoot)
|
|
35
40
|
mod.isRoot = true;
|
|
36
|
-
if (importer)
|
|
41
|
+
if (importer) {
|
|
37
42
|
mod.importers.add(importer);
|
|
43
|
+
importer.importedModules.add(mod);
|
|
44
|
+
}
|
|
38
45
|
mod.isDependency = isDependency;
|
|
39
46
|
if (info.version !== undefined) {
|
|
40
47
|
mod.version = info.version;
|
|
@@ -68,6 +75,7 @@ class ModuleGraph {
|
|
|
68
75
|
importedModules: Array.from(value.importedModules).map((item) => item.file),
|
|
69
76
|
};
|
|
70
77
|
if (value.isRoot) {
|
|
78
|
+
fileModules[key].isRoot = true;
|
|
71
79
|
roots.push(key);
|
|
72
80
|
}
|
|
73
81
|
});
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
+
import type { ImportSpecifier } from '@umijs/bundler-utils/compiled/es-module-lexer';
|
|
2
|
+
import type { TransformOptions } from '@umijs/bundler-utils/compiled/esbuild';
|
|
1
3
|
export declare enum Mode {
|
|
2
4
|
development = "development",
|
|
3
5
|
production = "production"
|
|
4
6
|
}
|
|
7
|
+
export interface IEsbuildLoaderHandlerParams {
|
|
8
|
+
code: string;
|
|
9
|
+
filePath: string;
|
|
10
|
+
imports: readonly ImportSpecifier[];
|
|
11
|
+
exports: readonly string[];
|
|
12
|
+
}
|
|
13
|
+
export interface IEsbuildLoaderOpts extends Partial<TransformOptions> {
|
|
14
|
+
handler?: Array<(opts: IEsbuildLoaderHandlerParams) => string>;
|
|
15
|
+
implementation?: typeof import('@umijs/bundler-utils/compiled/esbuild');
|
|
16
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umijs/mfsu",
|
|
3
|
-
"version": "4.0.0-
|
|
3
|
+
"version": "4.0.0-rc.3",
|
|
4
4
|
"description": "@umijs/mfsu",
|
|
5
5
|
"homepage": "https://github.com/umijs/umi-next/tree/master/packages/mfsu#readme",
|
|
6
6
|
"bugs": "https://github.com/umijs/umi-next/issues",
|
|
@@ -21,15 +21,15 @@
|
|
|
21
21
|
"dev": "pnpm build -- --watch"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@umijs/bundler-esbuild": "4.0.0-
|
|
25
|
-
"@umijs/bundler-utils": "4.0.0-
|
|
26
|
-
"@umijs/utils": "4.0.0-
|
|
24
|
+
"@umijs/bundler-esbuild": "4.0.0-rc.3",
|
|
25
|
+
"@umijs/bundler-utils": "4.0.0-rc.3",
|
|
26
|
+
"@umijs/utils": "4.0.0-rc.3",
|
|
27
|
+
"enhanced-resolve": "5.9.0"
|
|
27
28
|
},
|
|
28
29
|
"devDependencies": {
|
|
29
30
|
"@types/express": "4.17.13",
|
|
30
|
-
"enhanced-resolve": "5.8.3",
|
|
31
31
|
"mrmime": "1.0.0",
|
|
32
|
-
"webpack": "5.
|
|
32
|
+
"webpack": "5.69.1",
|
|
33
33
|
"webpack-virtual-modules": "0.4.3"
|
|
34
34
|
},
|
|
35
35
|
"publishConfig": {
|