@flatjs/evolve 2.1.0-next.11 → 2.1.0-next.12
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/constants.js +36 -1
- package/dist/create-webpack/create-externals.js +6 -1
- package/dist/create-webpack/create-optimization.js +43 -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 +78 -1
- package/dist/create-webpack/create-resolve.js +37 -1
- package/dist/create-webpack/create-rule-sets.js +20 -1
- package/dist/create-webpack/load-webpack-config.js +57 -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 +52 -1
- package/dist/create-webpack/rule-sets/rule-css.js +111 -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 +83 -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-task.js +55 -1
- package/dist/dev-server/create-dev-server-entries.js +25 -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 +49 -1
- package/dist/dev-server/middlewares/get-page-module-html.js +123 -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-group-entry-item.js +19 -1
- package/dist/helpers/assert-single-compiler.js +45 -1
- package/dist/helpers/chunk-entry-map.js +21 -1
- package/dist/helpers/delete-object-keys.js +20 -1
- package/dist/helpers/enable-bundle-hashname-for-module.js +6 -1
- package/dist/helpers/filter-actived-entries.js +42 -1
- package/dist/helpers/flat-entry-map.js +11 -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/get-runtime-cdn-base.js +21 -1
- package/dist/helpers/index.js +27 -1
- package/dist/helpers/is-deep-equal.js +67 -1
- package/dist/helpers/json-serializer.js +52 -1
- package/dist/helpers/merge-babel-options.js +45 -1
- package/dist/helpers/normalize-check-entry-options.js +28 -1
- package/dist/helpers/normalize-entry-map.js +59 -1
- package/dist/helpers/normalize-group-name.js +16 -1
- package/dist/helpers/normalize-page-proxy.js +9 -1
- package/dist/helpers/normalize-resolve-alias.js +7 -1
- package/dist/helpers/normalize-template-inject-tokens.js +22 -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 +14 -1
- package/dist/helpers/split-to-entry-group.js +139 -1
- package/dist/helpers/verify-group-entry-options.js +21 -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 +51 -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 +39 -1
- package/dist/main/prepare-serve.js +69 -1
- package/dist/main/prepare-static.js +30 -1
- package/dist/main/start-build-dynamic.js +171 -1
- package/dist/main/start-build-worker.js +44 -1
- package/dist/main/start-build.js +69 -1
- package/dist/main/start-group-entry-build.js +32 -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 +100 -1
- package/dist/plugins/multi-html/index.js +16 -1
- package/dist/plugins/multi-html/multi-html-cdn-plugin.js +83 -1
- package/dist/plugins/multi-html/multi-html-plugin.js +65 -1
- package/dist/plugins/ts-checker/index.js +1 -1
- package/dist/plugins/ts-checker/ts-checker-plugin.js +24 -1
- 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.d.ts +30 -3
- 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-threads-options.js +1 -1
- package/dist/types/types-webpack.js +1 -1
- package/package.json +2 -2
@@ -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,28 @@
|
|
1
|
-
import{urlJoin}from
|
1
|
+
import { urlJoin } from '@flatjs/common';
|
2
|
+
import { ignoreEntryOptionKeys } from '../constants.js';
|
3
|
+
import { deleteObjectKeys } from './delete-object-keys.js';
|
4
|
+
import { normalizeTemplateInjectTokens } from './normalize-template-inject-tokens.js';
|
5
|
+
/**
|
6
|
+
* Normalizes the check entry options.
|
7
|
+
*
|
8
|
+
* @param serveMode - A boolean indicating whether the serve mode is enabled.
|
9
|
+
* @param currEntryOption - The current entry option.
|
10
|
+
* @param ignoreOptionKeys - An array of keys to ignore in the entry option.
|
11
|
+
* @returns The normalized entry options.
|
12
|
+
*/
|
13
|
+
export const normalizeCheckEntryOptions = (serveMode, currEntryOption, ignoreOptionKeys = ignoreEntryOptionKeys) => {
|
14
|
+
const mode = serveMode ? 'development' : 'production';
|
15
|
+
const envCdnDomain = serveMode
|
16
|
+
? 'http://dev.flatjs.com'
|
17
|
+
: 'https://file.40017.cn/jinfu';
|
18
|
+
const configData = {
|
19
|
+
mode: mode,
|
20
|
+
envCdn: urlJoin(envCdnDomain, ['public']),
|
21
|
+
};
|
22
|
+
const normalizeEntryOption = normalizeTemplateInjectTokens(configData, currEntryOption);
|
23
|
+
const normalizedEntryOptions = {
|
24
|
+
...currEntryOption,
|
25
|
+
...normalizeEntryOption,
|
26
|
+
};
|
27
|
+
return deleteObjectKeys(normalizedEntryOptions, ignoreOptionKeys);
|
28
|
+
};
|
@@ -1 +1,59 @@
|
|
1
|
-
import
|
1
|
+
import { join } from 'node:path';
|
2
|
+
import _ from 'lodash';
|
3
|
+
/**
|
4
|
+
* Normalizes the entry group options based on the provided entry map content.
|
5
|
+
* If the entry map content has a group name, the grouping source will be set to 'manual'.
|
6
|
+
* Otherwise, the grouping source will be set to 'auto'.
|
7
|
+
*
|
8
|
+
* @param entryMapContent - The entry map content to normalize.
|
9
|
+
* @returns The normalized entry group options containing the group name and grouping source.
|
10
|
+
*/
|
11
|
+
const normalizeEntryGroupOptions = (entryMapContent) => {
|
12
|
+
if (entryMapContent && entryMapContent.groupName) {
|
13
|
+
return {
|
14
|
+
groupName: entryMapContent.groupName,
|
15
|
+
groupingSource: 'manual',
|
16
|
+
};
|
17
|
+
}
|
18
|
+
return {
|
19
|
+
groupingSource: 'auto',
|
20
|
+
};
|
21
|
+
};
|
22
|
+
/**
|
23
|
+
* Make sure that we have correct `virtualPath` for each webpack `entry`
|
24
|
+
* @param entryName the entryName defined via `flatjs-evolve.config.ts`.
|
25
|
+
* @param evolveOptions
|
26
|
+
* @returns
|
27
|
+
*/
|
28
|
+
export const normalizeEvolveEntryName = (entryName, projectVirtualPath) => {
|
29
|
+
const servedEntryName = entryName.replace(/^\//, '');
|
30
|
+
const virtualPath = projectVirtualPath.replace(/^\//, '');
|
31
|
+
const withVirtualPath = servedEntryName.startsWith(virtualPath);
|
32
|
+
// Make sure that we have correct `virtualPath` for each webpack `entry`
|
33
|
+
const finalEntryName = withVirtualPath
|
34
|
+
? servedEntryName
|
35
|
+
: join(virtualPath, servedEntryName);
|
36
|
+
return finalEntryName.replace(/\/$/, '');
|
37
|
+
};
|
38
|
+
/**
|
39
|
+
* Normalize flatjs.evolve entry map definition data.
|
40
|
+
* Merge default entry item configuration values.
|
41
|
+
* @param activedEntryMap actived entries
|
42
|
+
* @param definedEntryMap defined entries in flatjs.evolve.js
|
43
|
+
* @param projectVirtualPath virtual path for current `project`
|
44
|
+
*/
|
45
|
+
export const normalizeEvolveEntryMap = (activedEntryMap = {}, definedEntryMap = {}) => {
|
46
|
+
const newActivedEntries = {};
|
47
|
+
for (const [entryKey, itemConfig] of Object.entries(definedEntryMap)) {
|
48
|
+
// Setup default entry options.
|
49
|
+
const defaultEntryItemConfig = {
|
50
|
+
options: {},
|
51
|
+
};
|
52
|
+
if (activedEntryMap[entryKey]) {
|
53
|
+
// Perfect entry group option
|
54
|
+
const entryItemGroupConfig = normalizeEntryGroupOptions(itemConfig);
|
55
|
+
newActivedEntries[entryKey] = _.merge({}, defaultEntryItemConfig, itemConfig, activedEntryMap[entryKey], entryItemGroupConfig);
|
56
|
+
}
|
57
|
+
}
|
58
|
+
return newActivedEntries;
|
59
|
+
};
|
@@ -1 +1,16 @@
|
|
1
|
-
import{normalizeEvolveEntryName}from
|
1
|
+
import { normalizeEvolveEntryName } from './normalize-entry-map.js';
|
2
|
+
/**
|
3
|
+
* Normalizes the group name based on the project virtual path and index.
|
4
|
+
*
|
5
|
+
* @param projectVirtualPath - The virtual path of the project.
|
6
|
+
* @param index - The index used to generate the group name.
|
7
|
+
* @returns The normalized group name.
|
8
|
+
*/
|
9
|
+
export const normalizeGroupName = (projectVirtualPath, index) => {
|
10
|
+
const upperCase = Array.from({ length: 26 }, (_, i) => String.fromCharCode(65 + i));
|
11
|
+
const lowerCase = Array.from({ length: 26 }, (_, i) => String.fromCharCode(97 + i));
|
12
|
+
const alphabetArray = [...lowerCase, ...upperCase];
|
13
|
+
const time = Math.floor(index / 52);
|
14
|
+
const alphabetCode = alphabetArray[index % 52];
|
15
|
+
return normalizeEvolveEntryName(`${alphabetCode}${time || ''}`, projectVirtualPath);
|
16
|
+
};
|
@@ -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,22 @@
|
|
1
|
-
import{getHtmlPluginConfig}from
|
1
|
+
import { getHtmlPluginConfig, } from './get-html-plugin-config.js';
|
2
|
+
/**
|
3
|
+
* Normalizes the template inject tokens based on the provided configuration data and entry options.
|
4
|
+
*
|
5
|
+
* @param configData - The configuration data for the HTML plugin.
|
6
|
+
* @param currEntryOption - The current entry option for the evolve item.
|
7
|
+
* @returns An object containing the normalized template inject tokens.
|
8
|
+
*/
|
9
|
+
export const normalizeTemplateInjectTokens = (configData, currEntryOption) => {
|
10
|
+
return {
|
11
|
+
// The customized html tags should be inject to <header />
|
12
|
+
headBeforeHtmlTags: getHtmlPluginConfig('headBeforeHtmlTags', configData, currEntryOption?.headBeforeHtmlTags),
|
13
|
+
// Allow us customized inline scripts into compiled html template.
|
14
|
+
inlineScripts: getHtmlPluginConfig('inlineScripts', configData, currEntryOption?.inlineScripts),
|
15
|
+
// The ordered styles will be injected start of html head.
|
16
|
+
headBeforeStyles: getHtmlPluginConfig('headBeforeStyles', configData, currEntryOption?.headBeforeStyles),
|
17
|
+
// The ordered scripts will be injected before html head.
|
18
|
+
headBeforeScripts: getHtmlPluginConfig('headBeforeScripts', configData, currEntryOption?.headBeforeScripts),
|
19
|
+
// The ordered scripts will be injected end of html body.
|
20
|
+
bodyAfterScripts: getHtmlPluginConfig('bodyAfterScripts', configData, currEntryOption?.bodyAfterScripts),
|
21
|
+
};
|
22
|
+
};
|
@@ -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,14 @@
|
|
1
|
-
export const shouldEnableReactFastRefresh=(
|
1
|
+
export const shouldEnableReactFastRefresh = (serveMode, entryMapItem, evolveOptions) => {
|
2
|
+
const entryItemOption = entryMapItem[1];
|
3
|
+
// Check if the entry item has module federation
|
4
|
+
const hasModuleFederation = !!entryItemOption.options?.moduleFederation;
|
5
|
+
// Check if the entry item is a library, The library module can not run in the browser individually.
|
6
|
+
const isEntryItemLibrary = !!entryItemOption.options?.output?.library;
|
7
|
+
// Inject `react-refresh` if we are using preset `react`
|
8
|
+
return (serveMode &&
|
9
|
+
evolveOptions.loaderOptions.babelOptions?.usePreset === 'react' &&
|
10
|
+
!hasModuleFederation &&
|
11
|
+
!isEntryItemLibrary &&
|
12
|
+
// No specificed `liveReload` config
|
13
|
+
evolveOptions.devServer?.liveReload !== true);
|
14
|
+
};
|
@@ -1 +1,139 @@
|
|
1
|
-
import _ from
|
1
|
+
import _ from 'lodash';
|
2
|
+
import { ignoreEntryOptionKeys, maxEntryGroupSize } from '../constants.js';
|
3
|
+
import { isDeepEqual } from './is-deep-equal.js';
|
4
|
+
import { normalizeCheckEntryOptions } from './normalize-check-entry-options.js';
|
5
|
+
import { normalizeGroupName } from './normalize-group-name.js';
|
6
|
+
/**
|
7
|
+
* Groups the manual entries based on their group names.
|
8
|
+
* @param manualEntries - The map of manual entries.
|
9
|
+
* @returns An array of grouped manual entries.
|
10
|
+
*/
|
11
|
+
export const manualGrouping = (manualEntries) => {
|
12
|
+
const manualGroupEntryMap = _.groupBy(manualEntries, (entry) => {
|
13
|
+
return entry['groupName'];
|
14
|
+
});
|
15
|
+
const evolveEntryMapList = [];
|
16
|
+
for (const [, groupItem] of Object.entries(manualGroupEntryMap)) {
|
17
|
+
const evolveEntryMapItem = groupItem.reduce((prev, curr) => {
|
18
|
+
prev[curr.entryName] = _.omitBy(curr, 'entryName');
|
19
|
+
return prev;
|
20
|
+
}, {});
|
21
|
+
evolveEntryMapList.push(evolveEntryMapItem);
|
22
|
+
}
|
23
|
+
return evolveEntryMapList;
|
24
|
+
};
|
25
|
+
/**
|
26
|
+
* Reduces an array of autoEntries into groups based on their options.
|
27
|
+
* Each group is represented by a groupKey and contains an EvolveEntryMap.
|
28
|
+
*
|
29
|
+
* @param evolveOptions - The FlatEvolveOptions object.
|
30
|
+
* @param autoEntries - An array of EvolveEntryMapContent objects with an additional entryName property.
|
31
|
+
* @param ignoreOptionKeys - An array of keys to ignore when comparing entry options.
|
32
|
+
* @param serveMode - A boolean indicating whether the function is running in serve mode.
|
33
|
+
* @returns An object where each key represents a groupKey and its value is an EvolveEntryMap.
|
34
|
+
*/
|
35
|
+
export const autoGroupingReduce = (autoEntries, ignoreOptionKeys = [], serveMode) => {
|
36
|
+
return _.reduce(autoEntries, (prev, curr, index) => {
|
37
|
+
let lastGroupingKey = `auto_grouping_reduce-${index}`;
|
38
|
+
const currEntryOptions = normalizeCheckEntryOptions(serveMode, curr.options, ignoreOptionKeys);
|
39
|
+
for (const [groupingKey, groupEntryMap] of Object.entries(prev)) {
|
40
|
+
const firsEntryMap = Object.values(groupEntryMap)[0];
|
41
|
+
const firstEntryOptions = normalizeCheckEntryOptions(serveMode, firsEntryMap.options, ignoreOptionKeys);
|
42
|
+
if (isDeepEqual(currEntryOptions, firstEntryOptions)) {
|
43
|
+
lastGroupingKey = groupingKey;
|
44
|
+
break;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
prev[lastGroupingKey] = _.merge(prev[lastGroupingKey], {
|
48
|
+
[curr.entryName]: _.omitBy(curr, 'entryName'),
|
49
|
+
});
|
50
|
+
return prev;
|
51
|
+
}, {});
|
52
|
+
};
|
53
|
+
/**
|
54
|
+
* Assigns a group name to each entry in the evolveEntryMapList based on the projectVirtualPath.
|
55
|
+
*
|
56
|
+
* @param evolveOptions - The options for the evolve process.
|
57
|
+
* @param evolveEntryMapList - The list of evolve entry maps.
|
58
|
+
* @returns The updated list of evolve entry maps with group names assigned.
|
59
|
+
*/
|
60
|
+
export const autoAssignGroupName = (evolveOptions, evolveEntryMapList) => {
|
61
|
+
const { projectVirtualPath } = evolveOptions;
|
62
|
+
const evolveEntryMapItemList = [];
|
63
|
+
let index = 0;
|
64
|
+
for (const evolveEntryMap of evolveEntryMapList) {
|
65
|
+
const evolveEntryMapItem = {};
|
66
|
+
const groupName = normalizeGroupName(projectVirtualPath, index++);
|
67
|
+
for (const [entryName, entryContent] of Object.entries(evolveEntryMap)) {
|
68
|
+
entryContent.groupName = groupName;
|
69
|
+
evolveEntryMapItem[entryName] = entryContent;
|
70
|
+
}
|
71
|
+
evolveEntryMapItemList.push(evolveEntryMapItem);
|
72
|
+
}
|
73
|
+
return evolveEntryMapItemList;
|
74
|
+
};
|
75
|
+
/**
|
76
|
+
* Groups the given autoEntries into multiple EvolveEntryMap based on their options.
|
77
|
+
* If the group size exceeds the maximum group size, it will be sliced into smaller groups.
|
78
|
+
*
|
79
|
+
* @param evolveOptions - The FlatEvolveOptions object.
|
80
|
+
* @param autoEntries - An array of EvolveEntryMapContent objects with an additional entryName property.
|
81
|
+
* @param ignoreOptionKeys - An array of keys to ignore in the EvolveEntryItemOption object.
|
82
|
+
* @param maxGroupSize - The maximum size of each group. Defaults to maxEntryGroupSize.
|
83
|
+
* @param serveMode - A boolean indicating whether the serve mode is enabled.
|
84
|
+
* @returns An array of EvolveEntryMap representing the grouped entries.
|
85
|
+
*/
|
86
|
+
export const autoGrouping = (evolveOptions, autoEntries, ignoreOptionKeys = [], maxGroupSize = maxEntryGroupSize, serveMode) => {
|
87
|
+
const autoGroupingReduceMap = autoGroupingReduce(autoEntries, ignoreOptionKeys, serveMode);
|
88
|
+
const autoGroupEntryMapList = [];
|
89
|
+
// slice each group
|
90
|
+
for (const [, groupItem] of Object.entries(autoGroupingReduceMap)) {
|
91
|
+
const groupKeys = Object.keys(groupItem);
|
92
|
+
if (groupKeys.length > maxGroupSize) {
|
93
|
+
for (let i = 0; i < groupKeys.length; i += maxGroupSize) {
|
94
|
+
const sliceGroupKeys = groupKeys.slice(i, i + maxGroupSize);
|
95
|
+
const sliceEvolveEntryMap = sliceGroupKeys.reduce((prev, curr) => {
|
96
|
+
prev[curr] = groupItem[curr];
|
97
|
+
return prev;
|
98
|
+
}, {});
|
99
|
+
autoGroupEntryMapList.push(sliceEvolveEntryMap);
|
100
|
+
}
|
101
|
+
}
|
102
|
+
else {
|
103
|
+
autoGroupEntryMapList.push(groupItem);
|
104
|
+
}
|
105
|
+
}
|
106
|
+
return autoAssignGroupName(evolveOptions, autoGroupEntryMapList);
|
107
|
+
};
|
108
|
+
/**
|
109
|
+
* Splits the served entries into groups based on the given options.
|
110
|
+
*
|
111
|
+
* @param evolveEntries - The map of served entries.
|
112
|
+
* @param ignoreOptionKeys - The list of option keys to ignore.
|
113
|
+
* @returns An array of evolve entry maps representing the groups.
|
114
|
+
*/
|
115
|
+
export const splitToEntryGroup = (evolveEntries, evolveOptions, ignoreOptionKeys = ignoreEntryOptionKeys, serveMode) => {
|
116
|
+
const { isolation = false } = evolveOptions;
|
117
|
+
if (isolation) {
|
118
|
+
const evolveEntryMapList = [];
|
119
|
+
for (const [entryName, entryContent] of Object.entries(evolveEntries)) {
|
120
|
+
entryContent.groupName = entryName;
|
121
|
+
evolveEntryMapList.push({
|
122
|
+
[entryName]: entryContent,
|
123
|
+
});
|
124
|
+
}
|
125
|
+
return evolveEntryMapList;
|
126
|
+
}
|
127
|
+
const evolveEntryFlatList = _.flatMap(evolveEntries, (entryOption, entryName) => {
|
128
|
+
return {
|
129
|
+
...entryOption,
|
130
|
+
entryName,
|
131
|
+
};
|
132
|
+
});
|
133
|
+
const evolveEntryGroupMap = _.groupBy(evolveEntryFlatList, (entry) => {
|
134
|
+
return entry.groupingSource;
|
135
|
+
});
|
136
|
+
const manualEvolveEntryMapList = manualGrouping(evolveEntryGroupMap['manual']);
|
137
|
+
const autoEvolveEntryMapList = autoGrouping(evolveOptions, evolveEntryGroupMap['auto'], ignoreOptionKeys, maxEntryGroupSize, serveMode);
|
138
|
+
return [...manualEvolveEntryMapList, ...autoEvolveEntryMapList];
|
139
|
+
};
|
@@ -1 +1,21 @@
|
|
1
|
-
import{ignoreEntryOptionKeys}from
|
1
|
+
import { ignoreEntryOptionKeys } from '../constants.js';
|
2
|
+
import { isDeepEqual } from './is-deep-equal.js';
|
3
|
+
import { normalizeCheckEntryOptions } from './normalize-check-entry-options.js';
|
4
|
+
/**
|
5
|
+
* Verifies if the options of all entries in a group are equal, excluding specified keys.
|
6
|
+
*
|
7
|
+
* @param groupEvolveEntryMap - The map of group entries.
|
8
|
+
* @param ignoreOptionKeys - The keys to be ignored when comparing options.
|
9
|
+
* @returns A boolean indicating if the options of all entries are equal.
|
10
|
+
*/
|
11
|
+
export const verifyGroupEntryOptions = (groupEvolveEntryMap, ignoreOptionKeys = ignoreEntryOptionKeys, serveMode) => {
|
12
|
+
const groupEvolveEntryMapValues = Object.values(groupEvolveEntryMap);
|
13
|
+
if (groupEvolveEntryMapValues.length === 1) {
|
14
|
+
return true;
|
15
|
+
}
|
16
|
+
const firstEntryMap = groupEvolveEntryMapValues.shift();
|
17
|
+
const firstEntryOptions = normalizeCheckEntryOptions(serveMode, firstEntryMap?.options, ignoreOptionKeys);
|
18
|
+
return groupEvolveEntryMapValues.every((entryOption) => {
|
19
|
+
return isDeepEqual(firstEntryOptions, normalizeCheckEntryOptions(serveMode, entryOption.options, ignoreOptionKeys));
|
20
|
+
});
|
21
|
+
};
|
package/dist/index.js
CHANGED
@@ -1 +1,5 @@
|
|
1
|
-
export*from
|
1
|
+
export * from './define-config/index.js';
|
2
|
+
export * from './load-config/index.js';
|
3
|
+
export * from './main/index.js';
|
4
|
+
export * from './types/types-options.js';
|
5
|
+
export * from './types/types-entry-map.js';
|
@@ -1 +1 @@
|
|
1
|
-
export*from
|
1
|
+
export * from './load-evolve-config.js';
|