@flatjs/evolve 2.1.0-next.3 → 2.1.0-next.5
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/constants.js +26 -1
- package/dist/create-webpack/create-externals.js +6 -1
- package/dist/create-webpack/create-optimization.js +41 -1
- package/dist/create-webpack/create-output.js +35 -1
- package/dist/create-webpack/create-performance.js +7 -1
- package/dist/create-webpack/create-plugins.js +77 -1
- package/dist/create-webpack/create-resolve.js +37 -1
- package/dist/create-webpack/create-rule-sets.js +19 -1
- package/dist/create-webpack/load-webpack-config.js +56 -1
- package/dist/create-webpack/resolve-public-path.js +15 -1
- package/dist/create-webpack/rule-sets/constants.js +3 -1
- package/dist/create-webpack/rule-sets/rule-assets.js +50 -1
- package/dist/create-webpack/rule-sets/rule-css.js +101 -1
- package/dist/create-webpack/rule-sets/rule-less.js +44 -1
- package/dist/create-webpack/rule-sets/rule-scripts.js +34 -1
- package/dist/create-webpack/rule-sets/rule-svg-icon.js +25 -1
- package/dist/create-webpack/rule-sets/rule-utils.js +10 -1
- package/dist/create-webpack/types.js +1 -1
- package/dist/default-options.js +84 -1
- package/dist/define-config/define-config.js +4 -1
- package/dist/define-config/index.js +1 -1
- package/dist/dev-server/add-compiler-to-dev-server.js +58 -1
- package/dist/dev-server/create-app-page-route.js +13 -1
- package/dist/dev-server/create-dev-server-compiler-tasks.js +52 -1
- package/dist/dev-server/create-dev-server-entries.js +27 -1
- package/dist/dev-server/create-dev-server.js +24 -1
- package/dist/dev-server/index.js +6 -1
- package/dist/dev-server/middlewares/create-page-middleware.js +33 -1
- package/dist/dev-server/middlewares/create-public-assets-middleware.js +25 -1
- package/dist/dev-server/middlewares/get-all-sorted-modules.js +24 -1
- package/dist/dev-server/middlewares/get-bundle-asset.js +7 -1
- package/dist/dev-server/middlewares/get-dev-server-host-uri.js +5 -1
- package/dist/dev-server/middlewares/get-hmr-runtime-chunks.js +14 -1
- package/dist/dev-server/middlewares/get-normalized-entry-name.js +14 -1
- package/dist/dev-server/middlewares/get-page-main-html.js +42 -1
- package/dist/dev-server/middlewares/get-page-module-html.js +120 -1
- package/dist/dev-server/middlewares/get-project-virtual-path.js +3 -1
- package/dist/dev-server/middlewares/get-runtime-manifest.js +25 -1
- package/dist/dev-server/middlewares/index.js +2 -1
- package/dist/dev-server/middlewares/types.js +1 -1
- package/dist/errors/evolve-build-error.js +10 -1
- package/dist/helpers/allow-px2rem-for-module.js +6 -1
- package/dist/helpers/assert-only-single-entry-item.js +23 -1
- package/dist/helpers/chunk-entry-map.js +21 -1
- package/dist/helpers/enable-bundle-hashname-for-module.js +6 -1
- package/dist/helpers/filter-actived-entries.js +42 -1
- package/dist/helpers/get-bundle-file-name.js +23 -1
- package/dist/helpers/get-git-root.js +4 -1
- package/dist/helpers/get-html-plugin-config.js +47 -1
- package/dist/helpers/get-max-process-tasks.js +7 -1
- package/dist/helpers/get-pacakge-dir.js +13 -1
- package/dist/helpers/index.js +17 -1
- package/dist/helpers/json-serializer.js +52 -1
- package/dist/helpers/merge-babel-options.js +45 -1
- package/dist/helpers/normalize-entry-map.js +38 -1
- package/dist/helpers/normalize-page-proxy.js +9 -1
- package/dist/helpers/normalize-resolve-alias.js +7 -1
- package/dist/helpers/open-page.js +15 -1
- package/dist/helpers/print-log.js +49 -1
- package/dist/helpers/refresh-evolve-mock-options.js +34 -1
- package/dist/helpers/resolve-entry-map-input-files.js +20 -1
- package/dist/helpers/script-injects.js +39 -1
- package/dist/helpers/should-enable-react-fast-refresh.js +10 -1
- package/dist/helpers/split-to-multi-compiler.js +32 -1
- package/dist/index.js +5 -1
- package/dist/load-config/index.js +1 -1
- package/dist/load-config/load-evolve-config.js +41 -1
- package/dist/load-config/types.js +1 -1
- package/dist/main/create-thread-worker.js +42 -1
- package/dist/main/env-verify.js +21 -1
- package/dist/main/get-worker-path.js +5 -1
- package/dist/main/index.js +4 -1
- package/dist/main/prepare-build.js +38 -1
- package/dist/main/prepare-serve.js +45 -1
- package/dist/main/prepare-static.js +30 -1
- package/dist/main/start-build-dynamic.js +157 -1
- package/dist/main/start-build-worker.js +46 -1
- package/dist/main/start-build.js +53 -1
- package/dist/main/start-one-entry-build.js +35 -1
- package/dist/main/start-serve.js +34 -1
- package/dist/main/start-static.js +19 -1
- package/dist/minimizer/create-minimizers.js +25 -1
- package/dist/minimizer/default-options.js +14 -1
- package/dist/minimizer/image-minimizer.js +65 -1
- package/dist/minimizer/index.js +1 -1
- package/dist/minimizer/terser-minimizer.js +15 -3
- package/dist/minimizer/types.js +1 -1
- package/dist/plugins/circular-dependency/circular-dependency-plugin.js +119 -1
- package/dist/plugins/circular-dependency/index.js +15 -1
- package/dist/plugins/clean-webpack/clean-webpack-plugin.js +173 -1
- package/dist/plugins/clean-webpack/index.js +22 -1
- package/dist/plugins/define-variable/define-variable-plugin.js +28 -1
- package/dist/plugins/define-variable/index.js +1 -1
- package/dist/plugins/html-inject-scripts/plugin-html-inject-script.js +27 -1
- package/dist/plugins/module-federation/external-template-remotes.js +92 -1
- package/dist/plugins/module-federation/index.js +1 -1
- package/dist/plugins/module-federation/module-federation.js +98 -1
- package/dist/plugins/multi-html/index.js +15 -1
- package/dist/plugins/multi-html/multi-html-cdn-plugin.js +84 -1
- package/dist/plugins/multi-html/multi-html-plugin.js +70 -1
- package/dist/plugins/ts-checker/index.d.ts +1 -0
- package/dist/plugins/ts-checker/index.js +1 -0
- package/dist/plugins/ts-checker/ts-checker-plugin.d.ts +4 -0
- package/dist/plugins/ts-checker/ts-checker-plugin.js +18 -0
- package/dist/types/index.js +8 -1
- package/dist/types/types-ci.js +1 -1
- package/dist/types/types-dev-server.js +1 -1
- package/dist/types/types-entry-map.js +1 -1
- package/dist/types/types-federation.js +1 -1
- package/dist/types/types-loader-options.js +1 -1
- package/dist/types/types-modular-import.js +1 -1
- package/dist/types/types-multi-html.js +1 -1
- package/dist/types/types-options.js +1 -1
- package/dist/types/types-plugin-options.js +1 -1
- package/dist/types/types-webpack.js +1 -1
- package/package.json +5 -5
|
@@ -1 +1,25 @@
|
|
|
1
|
-
import{getSortedModules}from
|
|
1
|
+
import { getSortedModules } from './get-all-sorted-modules.js';
|
|
2
|
+
import { getBundleAsset } from './get-bundle-asset.js';
|
|
3
|
+
import { getHmrRuntimeChunks } from './get-hmr-runtime-chunks.js';
|
|
4
|
+
export const getRuntimeManifest = async (servedDevServerEntries, devHostUri, evolveOptions) => {
|
|
5
|
+
const sortedModules = getSortedModules(evolveOptions, servedDevServerEntries, devHostUri);
|
|
6
|
+
const runtimeManifest = {};
|
|
7
|
+
for (const moduleItem of sortedModules) {
|
|
8
|
+
const { entryName, isServedEntry, entryContent, devServerHostUri, normalizedEntryName, } = moduleItem;
|
|
9
|
+
const bundleScripts = [
|
|
10
|
+
getBundleAsset(devServerHostUri, normalizedEntryName, '.js'),
|
|
11
|
+
];
|
|
12
|
+
const bundleStyles = [
|
|
13
|
+
getBundleAsset(devServerHostUri, normalizedEntryName, '.css'),
|
|
14
|
+
];
|
|
15
|
+
const hmrRuntimeChunks = getHmrRuntimeChunks(servedDevServerEntries, entryName, normalizedEntryName, entryContent, evolveOptions, devServerHostUri);
|
|
16
|
+
runtimeManifest[normalizedEntryName] = {
|
|
17
|
+
entryName,
|
|
18
|
+
styles: bundleStyles,
|
|
19
|
+
scripts: bundleScripts,
|
|
20
|
+
isServed: isServedEntry,
|
|
21
|
+
runtimeChunks: hmrRuntimeChunks,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return runtimeManifest;
|
|
25
|
+
};
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export*from
|
|
1
|
+
export * from './create-page-middleware.js';
|
|
2
|
+
export * from './create-public-assets-middleware.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{};
|
|
1
|
+
export {};
|
|
@@ -1 +1,10 @@
|
|
|
1
|
-
export class EvolveBuildError extends Error{
|
|
1
|
+
export class EvolveBuildError extends Error {
|
|
2
|
+
constructor(code, messages) {
|
|
3
|
+
let message = code;
|
|
4
|
+
if (messages) {
|
|
5
|
+
message += ': ' + JSON.stringify(messages);
|
|
6
|
+
}
|
|
7
|
+
super(message);
|
|
8
|
+
this.code = code;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -1 +1,6 @@
|
|
|
1
|
-
export const allowPx2remForModule=(
|
|
1
|
+
export const allowPx2remForModule = (entryItem, evolveOptions) => {
|
|
2
|
+
// Global settings for `AllowPx2Rem`
|
|
3
|
+
const globalAllowPx2Rem = evolveOptions?.loaderOptions?.pixelOptions;
|
|
4
|
+
const currItemPx2Rem = (entryItem && entryItem[1]?.options?.allowPx2rem) ?? globalAllowPx2Rem;
|
|
5
|
+
return !!currItemPx2Rem;
|
|
6
|
+
};
|
|
@@ -1 +1,23 @@
|
|
|
1
|
-
import{normalizeEvolveEntryName}from
|
|
1
|
+
import { normalizeEvolveEntryName } from './normalize-entry-map.js';
|
|
2
|
+
/**
|
|
3
|
+
* Only fetch single one entry map once `serve`,`build` recycle.
|
|
4
|
+
* @returns
|
|
5
|
+
*/
|
|
6
|
+
export const assertOnlySingleEntryItem = (entryMap, evolveOptions) => {
|
|
7
|
+
if (Object.keys(entryMap).length > 1) {
|
|
8
|
+
throw new Error('Only single one entry map support right now for `serve`, `build`!');
|
|
9
|
+
}
|
|
10
|
+
let result = undefined;
|
|
11
|
+
for (const [entryChunkName, entryItem] of Object.entries(entryMap)) {
|
|
12
|
+
result = [entryChunkName, entryItem];
|
|
13
|
+
break;
|
|
14
|
+
}
|
|
15
|
+
if (!result) {
|
|
16
|
+
throw new Error(`No entry map found while "serve", "build" process!`);
|
|
17
|
+
}
|
|
18
|
+
const [entryName, entryConfig] = result;
|
|
19
|
+
// Make sure that we have correct `virtualPath` for each webpack `entry`
|
|
20
|
+
const normalizedEntryName = normalizeEvolveEntryName(entryName, evolveOptions.projectVirtualPath);
|
|
21
|
+
`entry`;
|
|
22
|
+
return [normalizedEntryName, entryConfig];
|
|
23
|
+
};
|
|
@@ -1 +1,21 @@
|
|
|
1
|
-
import{arrayChunk}from
|
|
1
|
+
import { arrayChunk } from '@flatjs/common';
|
|
2
|
+
/**
|
|
3
|
+
* Split entryMap into multi entryMap with a `size`
|
|
4
|
+
* @param entryMap
|
|
5
|
+
* @param size
|
|
6
|
+
*/
|
|
7
|
+
export const chunkEntryMap = (entryMap, size = 2) => {
|
|
8
|
+
const keys = Object.keys(entryMap);
|
|
9
|
+
const entryKeyChunks = arrayChunk(keys, size);
|
|
10
|
+
const finalEntryMaps = [];
|
|
11
|
+
for (const keys of entryKeyChunks) {
|
|
12
|
+
const chunkMap = keys.reduce((prev, curr) => {
|
|
13
|
+
return {
|
|
14
|
+
...prev,
|
|
15
|
+
[curr]: entryMap[curr],
|
|
16
|
+
};
|
|
17
|
+
}, {});
|
|
18
|
+
finalEntryMaps.push(chunkMap);
|
|
19
|
+
}
|
|
20
|
+
return finalEntryMaps;
|
|
21
|
+
};
|
|
@@ -1 +1,6 @@
|
|
|
1
|
-
export const enableBundleHashNameForModule=(
|
|
1
|
+
export const enableBundleHashNameForModule = (evolveOptions, entryItemOption) => {
|
|
2
|
+
// Global settings for `enableBundleHashName`
|
|
3
|
+
const globalEnabledStatus = evolveOptions.webpack?.enableBundleHashName;
|
|
4
|
+
const bundleHashNameEnabled = entryItemOption?.enableBundleHashName ?? globalEnabledStatus;
|
|
5
|
+
return !!bundleHashNameEnabled;
|
|
6
|
+
};
|
|
@@ -1 +1,42 @@
|
|
|
1
|
-
import{arraysIntersect,normalizeSemicolonFilterParts}from
|
|
1
|
+
import { arraysIntersect, normalizeSemicolonFilterParts } from '@flatjs/common';
|
|
2
|
+
import { resolveEntryMapInputFiles } from './resolve-entry-map-input-files.js';
|
|
3
|
+
/**
|
|
4
|
+
* Filter to find actived entry input by entry name filter.
|
|
5
|
+
* @param definedEntries
|
|
6
|
+
* @param modules `home;mine;`
|
|
7
|
+
* @returns activedEntries
|
|
8
|
+
*/
|
|
9
|
+
export const filterActivedEntriesByModule = (definedEntries, modules) => {
|
|
10
|
+
const patterns = normalizeSemicolonFilterParts(modules);
|
|
11
|
+
const newActivedEntries = {};
|
|
12
|
+
for (const [entryKey, itemConfig] of Object.entries(definedEntries)) {
|
|
13
|
+
const matched = patterns.find((m) => {
|
|
14
|
+
// Also need to support `numeric` named module.
|
|
15
|
+
const testRegExp = typeof m === 'string' || typeof m === 'number' ? new RegExp(`${m}`) : m;
|
|
16
|
+
return testRegExp.test(entryKey);
|
|
17
|
+
});
|
|
18
|
+
if (matched) {
|
|
19
|
+
newActivedEntries[entryKey] = itemConfig;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return newActivedEntries;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Filter to find actived entry input by absolute entry filepath
|
|
26
|
+
* @param projectCwd
|
|
27
|
+
* @param definedEntries
|
|
28
|
+
* @param entryInputs [`/xxxx/x/xxxx/src/home/index.tsx`]
|
|
29
|
+
* @returns activedEntries
|
|
30
|
+
*/
|
|
31
|
+
export const filterActivedEntriesByEntryInputs = async (projectCwd, definedEntries, entryInputs) => {
|
|
32
|
+
const newActivedEntries = {};
|
|
33
|
+
for (const [entryKey, itemConfig] of Object.entries(definedEntries)) {
|
|
34
|
+
const entryAbsFiles = await resolveEntryMapInputFiles(projectCwd, {
|
|
35
|
+
[entryKey]: itemConfig,
|
|
36
|
+
});
|
|
37
|
+
if (arraysIntersect(entryAbsFiles, entryInputs)) {
|
|
38
|
+
newActivedEntries[entryKey] = itemConfig;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return newActivedEntries;
|
|
42
|
+
};
|
|
@@ -1 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Get current timestramp as `string`
|
|
3
|
+
*/
|
|
4
|
+
export const currNow = () => Date.now().toString();
|
|
5
|
+
/**
|
|
6
|
+
* Generate bundle file name from rules
|
|
7
|
+
* 1. if `serveMode`, always return `bundle
|
|
8
|
+
* 2. else if `enableBundleHashName` always return `bundle[contenthash].{css,js}`
|
|
9
|
+
* 3. otherwise return `bundle.{css,js}?${currNow}`
|
|
10
|
+
* @param type `js` | `css`
|
|
11
|
+
* @param serveMode If we are run `serve` mode
|
|
12
|
+
* @param enableBundleHashName If we need to generate bundle file name with `[contenthash]`
|
|
13
|
+
*/
|
|
14
|
+
export const getBundleFileName = (type, serveMode, enableBundleHashName = true) => {
|
|
15
|
+
const fileEndFix = type === 'js' ? '.js' : '.css';
|
|
16
|
+
if (serveMode) {
|
|
17
|
+
return `bundle${fileEndFix}`;
|
|
18
|
+
}
|
|
19
|
+
if (enableBundleHashName) {
|
|
20
|
+
return `bundle[contenthash]${fileEndFix}`;
|
|
21
|
+
}
|
|
22
|
+
return `bundle${fileEndFix}?${currNow()}`;
|
|
23
|
+
};
|
|
@@ -1 +1,47 @@
|
|
|
1
|
-
import{polyfill,viewportScripts}from
|
|
1
|
+
import { polyfill, viewportScripts } from '../constants.js';
|
|
2
|
+
import { getPackageDir } from './get-pacakge-dir.js';
|
|
3
|
+
export const defaultHtmlPluginConfig = {
|
|
4
|
+
// The page title
|
|
5
|
+
title: '',
|
|
6
|
+
// The page favicon url地址
|
|
7
|
+
favicon: '',
|
|
8
|
+
// The customized html tags should be inject to `<header />`
|
|
9
|
+
headBeforeHtmlTags: [],
|
|
10
|
+
// Allow us customized inline scripts into compiled html template.
|
|
11
|
+
inlineScripts: [],
|
|
12
|
+
// The ordered styles will be injected start of html head.
|
|
13
|
+
headBeforeStyles: [],
|
|
14
|
+
// The ordered scripts will be injected before html head.
|
|
15
|
+
headBeforeScripts: [...polyfill],
|
|
16
|
+
// The ordered scripts will be injected end of html body.
|
|
17
|
+
bodyAfterScripts: [],
|
|
18
|
+
// `allowPx2rem` default is true
|
|
19
|
+
viewport: viewportScripts,
|
|
20
|
+
// avoid use cdn `me`, `dev`, `ntv`
|
|
21
|
+
excludeCdnEnvs: ['me', 'dev', 'ntv'],
|
|
22
|
+
// `minify` is true, `dev` always don't minify.
|
|
23
|
+
htmlMinify: true,
|
|
24
|
+
// Default use It must be an absolute path.
|
|
25
|
+
templatePath: getPackageDir('templates/html-plugin/index-{0}.html'),
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* 获取html plugin 模版相关定义字段.
|
|
29
|
+
* @param preferredValue 用户首选的值, 如果返回为undefined, 将使用默认值
|
|
30
|
+
* @returns
|
|
31
|
+
*/
|
|
32
|
+
export const getHtmlPluginConfig = (key, configData, preferredValue) => {
|
|
33
|
+
let userValue;
|
|
34
|
+
if (typeof preferredValue !== 'undefined') {
|
|
35
|
+
userValue =
|
|
36
|
+
typeof preferredValue === 'function'
|
|
37
|
+
? preferredValue(configData)
|
|
38
|
+
: preferredValue;
|
|
39
|
+
}
|
|
40
|
+
if (typeof userValue === 'undefined') {
|
|
41
|
+
const defaultValue = defaultHtmlPluginConfig[key];
|
|
42
|
+
return typeof defaultValue === 'function'
|
|
43
|
+
? defaultValue(configData)
|
|
44
|
+
: defaultValue;
|
|
45
|
+
}
|
|
46
|
+
return userValue;
|
|
47
|
+
};
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
import{cpus}from
|
|
1
|
+
import { cpus } from 'node:os';
|
|
2
|
+
export const getMaxProcessTasks = (totalTasks, maxProcesses) => {
|
|
3
|
+
const maxCpu = Math.max(1, typeof maxProcesses === 'string' && maxProcesses.endsWith('%')
|
|
4
|
+
? Math.round((cpus().length * Number(maxProcesses.slice(0, -1))) / 100)
|
|
5
|
+
: Number(maxProcesses));
|
|
6
|
+
return totalTasks > maxCpu ? maxCpu : Math.max(1, totalTasks);
|
|
7
|
+
};
|
|
@@ -1 +1,13 @@
|
|
|
1
|
-
import{join}from
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { getDirname } from '@armit/file-utility';
|
|
3
|
+
import { searchPackageDir } from '@armit/package';
|
|
4
|
+
export const getPackageDir = (...paths) => {
|
|
5
|
+
const dir = getDirname(import.meta.url);
|
|
6
|
+
const packageDir = searchPackageDir({
|
|
7
|
+
cwd: dir,
|
|
8
|
+
});
|
|
9
|
+
if (!packageDir) {
|
|
10
|
+
throw new Error('Could not resolve package root for `flatjs/evolve`');
|
|
11
|
+
}
|
|
12
|
+
return join(packageDir, ...paths);
|
|
13
|
+
};
|
package/dist/helpers/index.js
CHANGED
|
@@ -1 +1,17 @@
|
|
|
1
|
-
export*from
|
|
1
|
+
export * from './allow-px2rem-for-module.js';
|
|
2
|
+
export * from './assert-only-single-entry-item.js';
|
|
3
|
+
export * from './chunk-entry-map.js';
|
|
4
|
+
export * from './enable-bundle-hashname-for-module.js';
|
|
5
|
+
export * from './get-bundle-file-name.js';
|
|
6
|
+
export * from './get-html-plugin-config.js';
|
|
7
|
+
export * from './get-pacakge-dir.js';
|
|
8
|
+
export * from './merge-babel-options.js';
|
|
9
|
+
export * from './normalize-entry-map.js';
|
|
10
|
+
export * from './open-page.js';
|
|
11
|
+
export * from './print-log.js';
|
|
12
|
+
export * from './refresh-evolve-mock-options.js';
|
|
13
|
+
export * from './script-injects.js';
|
|
14
|
+
export * from './should-enable-react-fast-refresh.js';
|
|
15
|
+
export * from './split-to-multi-compiler.js';
|
|
16
|
+
export * from './json-serializer.js';
|
|
17
|
+
export * from './normalize-resolve-alias.js';
|
|
@@ -1 +1,52 @@
|
|
|
1
|
-
function stringifyWithFns(
|
|
1
|
+
function stringifyWithFns(obj) {
|
|
2
|
+
return JSON.stringify(obj, function (key, value) {
|
|
3
|
+
if (typeof value === 'function') {
|
|
4
|
+
// handle property function
|
|
5
|
+
try {
|
|
6
|
+
// try test if it is a property function string
|
|
7
|
+
// e.g. var x = { inlineScripts () { console.log('Hello, world!'); } }
|
|
8
|
+
// eval(x.inlineScripts) will throw error
|
|
9
|
+
makeFunctionFromString(value);
|
|
10
|
+
return value.toString();
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
// fix: ` inlineScripts () { console.log('Hello, world!'); }` to `function inlineScripts () { console.log('Hello, world!'); }`
|
|
14
|
+
return `function ${value.toString()}`;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return value;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function looksLikeAFunctionString(value) {
|
|
21
|
+
const funPattern = [
|
|
22
|
+
/^function[^(]*\(([^()]*)\)\s*\{[\s\S]*\}$/m,
|
|
23
|
+
// eslint-disable-next-line regexp/no-super-linear-backtracking
|
|
24
|
+
/^(\s*async\s*)?(\w*\s*)\(([^)]*)\)\s*=>\s*(.*)$/m,
|
|
25
|
+
// 仅包含一个参数的箭头
|
|
26
|
+
/^\s*\w+\s*=>/m,
|
|
27
|
+
];
|
|
28
|
+
const matchFn = funPattern.find((s) => s.test(value));
|
|
29
|
+
return !!matchFn;
|
|
30
|
+
}
|
|
31
|
+
function makeFunctionFromString(funcString) {
|
|
32
|
+
return eval('(' + funcString + ')');
|
|
33
|
+
}
|
|
34
|
+
function parseWithFns(json) {
|
|
35
|
+
try {
|
|
36
|
+
return JSON.parse(json, function (key, value) {
|
|
37
|
+
if (looksLikeAFunctionString(value)) {
|
|
38
|
+
return makeFunctionFromString(value);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
return {};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export const jsonSerializer = {
|
|
50
|
+
stringify: stringifyWithFns,
|
|
51
|
+
parse: parseWithFns,
|
|
52
|
+
};
|
|
@@ -1 +1,45 @@
|
|
|
1
|
-
import{babelMerge}from
|
|
1
|
+
import { babelMerge } from '@armit/babel-merge';
|
|
2
|
+
import babelPluginImport from '@flatjs/babel-plugin-import';
|
|
3
|
+
import { logger } from '@flatjs/common';
|
|
4
|
+
import { reactBabelPreset, vueBabelPreset } from '@flatjs/evolve-preset-babel';
|
|
5
|
+
import { moduleName } from '../constants.js';
|
|
6
|
+
export const mergeBabelOption = (modularImports = [], options = { usePreset: 'react' }) => {
|
|
7
|
+
const babelImports = modularImports.map((importItem) => {
|
|
8
|
+
return [
|
|
9
|
+
babelPluginImport,
|
|
10
|
+
{
|
|
11
|
+
transformToDefaultImport: false,
|
|
12
|
+
libraryDirectory: 'dist',
|
|
13
|
+
...importItem,
|
|
14
|
+
},
|
|
15
|
+
importItem.libraryName,
|
|
16
|
+
];
|
|
17
|
+
});
|
|
18
|
+
const { usePreset = 'react', ...overrideBabelOption } = options;
|
|
19
|
+
const baseBabelOption = usePreset === 'react'
|
|
20
|
+
? reactBabelPreset()
|
|
21
|
+
: usePreset === 'vue'
|
|
22
|
+
? vueBabelPreset()
|
|
23
|
+
: reactBabelPreset();
|
|
24
|
+
let mergedBabelOption = {};
|
|
25
|
+
try {
|
|
26
|
+
mergedBabelOption = babelMerge(baseBabelOption, overrideBabelOption);
|
|
27
|
+
// babelMerge only the last one will be retained, since there are multiple `@flatjs/babel-plugin-import` plugins with the same plugin id.
|
|
28
|
+
if (mergedBabelOption.plugins) {
|
|
29
|
+
mergedBabelOption.plugins.unshift(...babelImports);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
mergedBabelOption.plugins = babelImports;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
logger.error(err, moduleName);
|
|
37
|
+
}
|
|
38
|
+
const finalBabelOptions = {
|
|
39
|
+
...mergedBabelOption,
|
|
40
|
+
babelrc: false,
|
|
41
|
+
// Turns out the compact option is set to auto by default which removes "superfluous whitespace characters and line terminators [...] on input sizes >100KB".
|
|
42
|
+
compact: false,
|
|
43
|
+
};
|
|
44
|
+
return finalBabelOptions;
|
|
45
|
+
};
|
|
@@ -1 +1,38 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import _ from 'lodash';
|
|
3
|
+
/**
|
|
4
|
+
* Make sure that we have correct `virtualPath` for each webpack `entry`
|
|
5
|
+
* @param entryName the entryName defined via `flatjs-evolve.config.ts`.
|
|
6
|
+
* @param evolveOptions
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
export const normalizeEvolveEntryName = (entryName, projectVirtualPath) => {
|
|
10
|
+
const servedEntryName = entryName.replace(/^\//, '');
|
|
11
|
+
const virtualPath = projectVirtualPath.replace(/^\//, '');
|
|
12
|
+
const withVirtualPath = servedEntryName.startsWith(virtualPath);
|
|
13
|
+
// Make sure that we have correct `virtualPath` for each webpack `entry`
|
|
14
|
+
const finalEntryName = withVirtualPath
|
|
15
|
+
? servedEntryName
|
|
16
|
+
: join(virtualPath, servedEntryName);
|
|
17
|
+
return finalEntryName.replace(/\/$/, '');
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Normalize flatjs.evolve entry map definition data.
|
|
21
|
+
* Merge default entry item configuration values.
|
|
22
|
+
* @param activedEntryMap actived entries
|
|
23
|
+
* @param definedEntryMap defined entries in flatjs.evolve.js
|
|
24
|
+
*/
|
|
25
|
+
export const normalizeEvolveEntryMap = (activedEntryMap = {}, definedEntryMap = {}) => {
|
|
26
|
+
const newActivedEntries = {};
|
|
27
|
+
for (const [entryKey, itemConfig] of Object.entries(definedEntryMap)) {
|
|
28
|
+
// Setup default entry options.
|
|
29
|
+
const defaultEntryItemConfig = {
|
|
30
|
+
options: {},
|
|
31
|
+
};
|
|
32
|
+
if (activedEntryMap[entryKey]) {
|
|
33
|
+
newActivedEntries[entryKey] = _.merge({}, defaultEntryItemConfig, itemConfig, activedEntryMap[entryKey]);
|
|
34
|
+
}
|
|
35
|
+
_.merge(itemConfig, defaultEntryItemConfig);
|
|
36
|
+
}
|
|
37
|
+
return newActivedEntries;
|
|
38
|
+
};
|
|
@@ -1 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* We need to normalize the page proxy to make sure that we have prefix slash.
|
|
3
|
+
* @param pageProxy `/pages`
|
|
4
|
+
* @returns The normalized page proxy
|
|
5
|
+
*/
|
|
6
|
+
export const normalizePageProxy = (pageProxy = '/pages') => {
|
|
7
|
+
const proxy = pageProxy.replace(/^\//, '').replace(/\/$/, '');
|
|
8
|
+
return `/` + (proxy || 'pages');
|
|
9
|
+
};
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
import{resolve}from
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
export const normalizeResolveAlias = (projectCwd, alias = {}) => {
|
|
3
|
+
for (const [symbol, path] of Object.entries(alias)) {
|
|
4
|
+
alias[symbol] = resolve(projectCwd, path);
|
|
5
|
+
}
|
|
6
|
+
return alias;
|
|
7
|
+
};
|
|
@@ -1 +1,15 @@
|
|
|
1
|
-
import opn from
|
|
1
|
+
import opn from 'better-opn';
|
|
2
|
+
/**
|
|
3
|
+
* A better opn. Reuse the same tab on Chrome for
|
|
4
|
+
* @example
|
|
5
|
+
* `http://xxx.domain.com:3001/pages`
|
|
6
|
+
* @param openUrl the page url try to open.
|
|
7
|
+
*/
|
|
8
|
+
export const openPage = (openUrl) => {
|
|
9
|
+
try {
|
|
10
|
+
opn(openUrl);
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
console.warn(`Unable to open browser. If you are running in a headless environment\n`);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
@@ -1 +1,49 @@
|
|
|
1
|
-
import{logger}from
|
|
1
|
+
import { logger } from '@flatjs/common';
|
|
2
|
+
import { moduleName } from '../constants.js';
|
|
3
|
+
export const printInfo = (message, silent = false) => {
|
|
4
|
+
if (!silent) {
|
|
5
|
+
logger.info(message, moduleName);
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
export const printError = (message) => {
|
|
9
|
+
logger.error(message, moduleName);
|
|
10
|
+
};
|
|
11
|
+
const formatCompilerError = (errors, formattedMessages = []) => {
|
|
12
|
+
if (!errors) {
|
|
13
|
+
return formattedMessages;
|
|
14
|
+
}
|
|
15
|
+
if (typeof errors === 'string') {
|
|
16
|
+
formattedMessages.push(errors);
|
|
17
|
+
}
|
|
18
|
+
else if (Array.isArray(errors)) {
|
|
19
|
+
for (const error of errors) {
|
|
20
|
+
formatCompilerError(error, formattedMessages);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
else if (typeof errors === 'object') {
|
|
24
|
+
// Only need to show `stack` or `message`
|
|
25
|
+
const onlyOneMsg = errors.stack || errors.message;
|
|
26
|
+
delete errors.stack;
|
|
27
|
+
delete errors.message;
|
|
28
|
+
const newErrors = {
|
|
29
|
+
...errors,
|
|
30
|
+
_newMsg: onlyOneMsg,
|
|
31
|
+
};
|
|
32
|
+
for (const [, value] of Object.entries(newErrors)) {
|
|
33
|
+
formatCompilerError(value, formattedMessages);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return formattedMessages;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Do not use `logger` to print webpack compiler error, cause of it may have it's message formatting.
|
|
40
|
+
* @param errors
|
|
41
|
+
* @returns
|
|
42
|
+
*/
|
|
43
|
+
export const printCompilerError = (errors) => {
|
|
44
|
+
const newErrors = formatCompilerError(errors, []);
|
|
45
|
+
for (const message of newErrors) {
|
|
46
|
+
console.log(message);
|
|
47
|
+
}
|
|
48
|
+
return newErrors;
|
|
49
|
+
};
|
|
@@ -1 +1,34 @@
|
|
|
1
|
-
import{requireResolve}
|
|
1
|
+
import { requireResolve } from '@flatjs/common';
|
|
2
|
+
import { loadMockConfig, getMockCwd, } from '@flatjs/mock';
|
|
3
|
+
import _ from 'lodash';
|
|
4
|
+
export const refreshEvolveMockOptions = async (projectCwd, evolveOptions, configLoaderOptions) => {
|
|
5
|
+
const devServer = evolveOptions.devServer;
|
|
6
|
+
const esmLoaderOptions = configLoaderOptions?.esmLoaderOptions;
|
|
7
|
+
const externals = esmLoaderOptions?.externals || [];
|
|
8
|
+
const command = {
|
|
9
|
+
projectCwd,
|
|
10
|
+
resolve: requireResolve,
|
|
11
|
+
};
|
|
12
|
+
// Try to load mock configuration from `flatjs-mock.config.ts`
|
|
13
|
+
const newMockOptions = await loadMockConfig(command, projectCwd, (devServer?.mockOptions || {}), _.merge({}, configLoaderOptions, {
|
|
14
|
+
configFile: 'flatjs-mock',
|
|
15
|
+
esmLoaderOptions: {
|
|
16
|
+
// load `flatjs-mock.config.ts` it will always import { defineConfig } from `@flatjs/mock`
|
|
17
|
+
externals: [...externals, '@flatjs/mock'],
|
|
18
|
+
},
|
|
19
|
+
}));
|
|
20
|
+
// we always has `devServer` config node.
|
|
21
|
+
if (devServer) {
|
|
22
|
+
devServer.mockOptions = newMockOptions || {};
|
|
23
|
+
if (devServer.mockOptions && !devServer.mockOptions.https) {
|
|
24
|
+
devServer.mockOptions.https = devServer?.https;
|
|
25
|
+
}
|
|
26
|
+
// Dynamic resolve mock work root directory
|
|
27
|
+
const mockCwd = getMockCwd(newMockOptions);
|
|
28
|
+
// always push mockCwd into watchOptions ignored.
|
|
29
|
+
if (Array.isArray(devServer?.watchOptions?.ignored)) {
|
|
30
|
+
devServer?.watchOptions?.ignored.push(mockCwd);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return evolveOptions;
|
|
34
|
+
};
|
|
@@ -1 +1,20 @@
|
|
|
1
|
-
import{fileWalk}from
|
|
1
|
+
import { fileWalk } from '@armit/file-utility';
|
|
2
|
+
import { arrayUnique } from '@flatjs/common';
|
|
3
|
+
/**
|
|
4
|
+
* Transform all entry files via `entryMap`
|
|
5
|
+
* @param projectCwd The project root directory
|
|
6
|
+
* @param entryMap The evolve entryMap definition
|
|
7
|
+
* @returns The absolute entry input files.
|
|
8
|
+
*/
|
|
9
|
+
export const resolveEntryMapInputFiles = async (projectCwd, entryMap) => {
|
|
10
|
+
const pattern = [];
|
|
11
|
+
for (const [, config] of Object.entries(entryMap)) {
|
|
12
|
+
const entries = config.entry.map((s) => s.replace(/.(?:js|jsx|tsx|ts)$/, '') + '.*');
|
|
13
|
+
pattern.push(...entries);
|
|
14
|
+
}
|
|
15
|
+
const walkPattern = arrayUnique(pattern);
|
|
16
|
+
return await fileWalk(walkPattern, {
|
|
17
|
+
cwd: projectCwd,
|
|
18
|
+
absolute: true,
|
|
19
|
+
});
|
|
20
|
+
};
|
|
@@ -1 +1,39 @@
|
|
|
1
|
-
export function httpUrlJoin(
|
|
1
|
+
export function httpUrlJoin(first = '', second = '') {
|
|
2
|
+
return first.replace(/\/$/, '') + '/' + second.replace(/^\//, '');
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* To extract the best matched CDN configuration url address, either use URL `query.env` or customize the `envRresolver`
|
|
6
|
+
* @param cdnConfig List of pre-configured cdn urls for each environment
|
|
7
|
+
* @param envResolver Get the specific environment variable by the currently requested host url address.
|
|
8
|
+
* @returns Returns the best matching address with a suffix (`/`)
|
|
9
|
+
*/
|
|
10
|
+
export function cdnFinder(cdnConfig, envResolver) {
|
|
11
|
+
// eslint-disable-next-line regexp/no-unused-capturing-group
|
|
12
|
+
const regex = /[?&]env(=([^&#]*)|&|#|$)/;
|
|
13
|
+
const locationHref = window.location.href;
|
|
14
|
+
const results = regex.exec(locationHref);
|
|
15
|
+
let env = results && results[2]
|
|
16
|
+
? decodeURIComponent(results[2].replace(/\+/g, ' '))
|
|
17
|
+
: 'prod';
|
|
18
|
+
// If we have customized cdn resolver using it first.
|
|
19
|
+
env = (envResolver && envResolver(locationHref)) || env;
|
|
20
|
+
const matchedCdnList = cdnConfig[env] || cdnConfig['prod'] || [];
|
|
21
|
+
const matchedCdn = matchedCdnList[Math.floor(Math.random() * matchedCdnList.length)];
|
|
22
|
+
// ensure has endfix slash
|
|
23
|
+
return matchedCdn.replace(/\/$/, '') + '/';
|
|
24
|
+
}
|
|
25
|
+
export function findEnvCdn(cdnConfig = {}, env = 'prod') {
|
|
26
|
+
const matchedCdnList = cdnConfig[env] || cdnConfig['prod'] || [];
|
|
27
|
+
return matchedCdnList[Math.floor(Math.random() * matchedCdnList.length)];
|
|
28
|
+
}
|
|
29
|
+
export function injectFederationScripts(cdnConfig, cdnResolver = function cdnResolver() {
|
|
30
|
+
return undefined;
|
|
31
|
+
}) {
|
|
32
|
+
return `window.evolveFetchMicroWidgets = function () {
|
|
33
|
+
var cdnConfig = ${JSON.stringify(cdnConfig)};
|
|
34
|
+
var cdnResolver = ${cdnResolver.toString()};
|
|
35
|
+
var cdnFinder = ${cdnFinder.toString()};
|
|
36
|
+
return (cdnFinder(cdnConfig, cdnResolver) || '').replace(/\\/$/, '');
|
|
37
|
+
}
|
|
38
|
+
`;
|
|
39
|
+
}
|
|
@@ -1 +1,10 @@
|
|
|
1
|
-
export const shouldEnableReactFastRefresh=(
|
|
1
|
+
export const shouldEnableReactFastRefresh = (serveMode, entryMapItem, evolveOptions) => {
|
|
2
|
+
const entryItemOption = entryMapItem[1];
|
|
3
|
+
const hasModuleFederation = !!entryItemOption.options?.moduleFederation;
|
|
4
|
+
// Inject `react-refresh` if we are using preset `react`
|
|
5
|
+
return (serveMode &&
|
|
6
|
+
evolveOptions.loaderOptions.babelOptions?.usePreset === 'react' &&
|
|
7
|
+
!hasModuleFederation &&
|
|
8
|
+
// No specificed `liveReload` config
|
|
9
|
+
evolveOptions.devServer?.liveReload !== true);
|
|
10
|
+
};
|