@flatjs/evolve 2.1.0-next.11 → 2.1.0-next.12

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.
Files changed (125) hide show
  1. package/dist/constants.js +36 -1
  2. package/dist/create-webpack/create-externals.js +6 -1
  3. package/dist/create-webpack/create-optimization.js +43 -1
  4. package/dist/create-webpack/create-output.js +35 -1
  5. package/dist/create-webpack/create-performance.js +7 -1
  6. package/dist/create-webpack/create-plugins.js +78 -1
  7. package/dist/create-webpack/create-resolve.js +37 -1
  8. package/dist/create-webpack/create-rule-sets.js +20 -1
  9. package/dist/create-webpack/load-webpack-config.js +57 -1
  10. package/dist/create-webpack/resolve-public-path.js +15 -1
  11. package/dist/create-webpack/rule-sets/constants.js +3 -1
  12. package/dist/create-webpack/rule-sets/rule-assets.js +52 -1
  13. package/dist/create-webpack/rule-sets/rule-css.js +111 -1
  14. package/dist/create-webpack/rule-sets/rule-less.js +44 -1
  15. package/dist/create-webpack/rule-sets/rule-scripts.js +34 -1
  16. package/dist/create-webpack/rule-sets/rule-svg-icon.js +25 -1
  17. package/dist/create-webpack/rule-sets/rule-utils.js +10 -1
  18. package/dist/create-webpack/types.js +1 -1
  19. package/dist/default-options.js +83 -1
  20. package/dist/define-config/define-config.js +4 -1
  21. package/dist/define-config/index.js +1 -1
  22. package/dist/dev-server/add-compiler-to-dev-server.js +58 -1
  23. package/dist/dev-server/create-app-page-route.js +13 -1
  24. package/dist/dev-server/create-dev-server-compiler-task.js +55 -1
  25. package/dist/dev-server/create-dev-server-entries.js +25 -1
  26. package/dist/dev-server/create-dev-server.js +24 -1
  27. package/dist/dev-server/index.js +6 -1
  28. package/dist/dev-server/middlewares/create-page-middleware.js +33 -1
  29. package/dist/dev-server/middlewares/create-public-assets-middleware.js +25 -1
  30. package/dist/dev-server/middlewares/get-all-sorted-modules.js +24 -1
  31. package/dist/dev-server/middlewares/get-bundle-asset.js +7 -1
  32. package/dist/dev-server/middlewares/get-dev-server-host-uri.js +5 -1
  33. package/dist/dev-server/middlewares/get-hmr-runtime-chunks.js +14 -1
  34. package/dist/dev-server/middlewares/get-normalized-entry-name.js +14 -1
  35. package/dist/dev-server/middlewares/get-page-main-html.js +49 -1
  36. package/dist/dev-server/middlewares/get-page-module-html.js +123 -1
  37. package/dist/dev-server/middlewares/get-project-virtual-path.js +3 -1
  38. package/dist/dev-server/middlewares/get-runtime-manifest.js +25 -1
  39. package/dist/dev-server/middlewares/index.js +2 -1
  40. package/dist/dev-server/middlewares/types.js +1 -1
  41. package/dist/errors/evolve-build-error.js +10 -1
  42. package/dist/helpers/allow-px2rem-for-module.js +6 -1
  43. package/dist/helpers/assert-group-entry-item.js +19 -1
  44. package/dist/helpers/assert-single-compiler.js +45 -1
  45. package/dist/helpers/chunk-entry-map.js +21 -1
  46. package/dist/helpers/delete-object-keys.js +20 -1
  47. package/dist/helpers/enable-bundle-hashname-for-module.js +6 -1
  48. package/dist/helpers/filter-actived-entries.js +42 -1
  49. package/dist/helpers/flat-entry-map.js +11 -1
  50. package/dist/helpers/get-bundle-file-name.js +23 -1
  51. package/dist/helpers/get-git-root.js +4 -1
  52. package/dist/helpers/get-html-plugin-config.js +47 -1
  53. package/dist/helpers/get-max-process-tasks.js +7 -1
  54. package/dist/helpers/get-pacakge-dir.js +13 -1
  55. package/dist/helpers/get-runtime-cdn-base.js +21 -1
  56. package/dist/helpers/index.js +27 -1
  57. package/dist/helpers/is-deep-equal.js +67 -1
  58. package/dist/helpers/json-serializer.js +52 -1
  59. package/dist/helpers/merge-babel-options.js +45 -1
  60. package/dist/helpers/normalize-check-entry-options.js +28 -1
  61. package/dist/helpers/normalize-entry-map.js +59 -1
  62. package/dist/helpers/normalize-group-name.js +16 -1
  63. package/dist/helpers/normalize-page-proxy.js +9 -1
  64. package/dist/helpers/normalize-resolve-alias.js +7 -1
  65. package/dist/helpers/normalize-template-inject-tokens.js +22 -1
  66. package/dist/helpers/open-page.js +15 -1
  67. package/dist/helpers/print-log.js +49 -1
  68. package/dist/helpers/refresh-evolve-mock-options.js +34 -1
  69. package/dist/helpers/resolve-entry-map-input-files.js +20 -1
  70. package/dist/helpers/script-injects.js +39 -1
  71. package/dist/helpers/should-enable-react-fast-refresh.js +14 -1
  72. package/dist/helpers/split-to-entry-group.js +139 -1
  73. package/dist/helpers/verify-group-entry-options.js +21 -1
  74. package/dist/index.js +5 -1
  75. package/dist/load-config/index.js +1 -1
  76. package/dist/load-config/load-evolve-config.js +41 -1
  77. package/dist/load-config/types.js +1 -1
  78. package/dist/main/create-thread-worker.js +51 -1
  79. package/dist/main/env-verify.js +21 -1
  80. package/dist/main/get-worker-path.js +5 -1
  81. package/dist/main/index.js +4 -1
  82. package/dist/main/prepare-build.js +39 -1
  83. package/dist/main/prepare-serve.js +69 -1
  84. package/dist/main/prepare-static.js +30 -1
  85. package/dist/main/start-build-dynamic.js +171 -1
  86. package/dist/main/start-build-worker.js +44 -1
  87. package/dist/main/start-build.js +69 -1
  88. package/dist/main/start-group-entry-build.js +32 -1
  89. package/dist/main/start-serve.js +34 -1
  90. package/dist/main/start-static.js +19 -1
  91. package/dist/minimizer/create-minimizers.js +25 -1
  92. package/dist/minimizer/default-options.js +14 -1
  93. package/dist/minimizer/image-minimizer.js +65 -1
  94. package/dist/minimizer/index.js +1 -1
  95. package/dist/minimizer/terser-minimizer.js +15 -3
  96. package/dist/minimizer/types.js +1 -1
  97. package/dist/plugins/circular-dependency/circular-dependency-plugin.js +119 -1
  98. package/dist/plugins/circular-dependency/index.js +15 -1
  99. package/dist/plugins/clean-webpack/clean-webpack-plugin.js +173 -1
  100. package/dist/plugins/clean-webpack/index.js +22 -1
  101. package/dist/plugins/define-variable/define-variable-plugin.js +28 -1
  102. package/dist/plugins/define-variable/index.js +1 -1
  103. package/dist/plugins/html-inject-scripts/plugin-html-inject-script.js +27 -1
  104. package/dist/plugins/module-federation/external-template-remotes.js +92 -1
  105. package/dist/plugins/module-federation/index.js +1 -1
  106. package/dist/plugins/module-federation/module-federation.js +100 -1
  107. package/dist/plugins/multi-html/index.js +16 -1
  108. package/dist/plugins/multi-html/multi-html-cdn-plugin.js +83 -1
  109. package/dist/plugins/multi-html/multi-html-plugin.js +65 -1
  110. package/dist/plugins/ts-checker/index.js +1 -1
  111. package/dist/plugins/ts-checker/ts-checker-plugin.js +24 -1
  112. package/dist/types/index.js +8 -1
  113. package/dist/types/types-ci.js +1 -1
  114. package/dist/types/types-dev-server.js +1 -1
  115. package/dist/types/types-entry-map.js +1 -1
  116. package/dist/types/types-federation.js +1 -1
  117. package/dist/types/types-loader-options.d.ts +30 -3
  118. package/dist/types/types-loader-options.js +1 -1
  119. package/dist/types/types-modular-import.js +1 -1
  120. package/dist/types/types-multi-html.js +1 -1
  121. package/dist/types/types-options.js +1 -1
  122. package/dist/types/types-plugin-options.js +1 -1
  123. package/dist/types/types-threads-options.js +1 -1
  124. package/dist/types/types-webpack.js +1 -1
  125. package/package.json +2 -2
@@ -1 +1,52 @@
1
- function stringifyWithFns(n){return JSON.stringify(n,(function(n,t){if("function"==typeof t)try{return makeFunctionFromString(t),t.toString()}catch(n){return`function ${t.toString()}`}return t}))}function looksLikeAFunctionString(n){return!![/^function[^(]*\(([^()]*)\)\s*\{[\s\S]*\}$/m,/^(\s*async\s*)?(\w*\s*)\(([^)]*)\)\s*=>\s*(.*)$/m,/^\s*\w+\s*=>/m].find((t=>t.test(n)))}function makeFunctionFromString(funcString){return eval("("+funcString+")")}function parseWithFns(n){try{return JSON.parse(n,(function(n,t){return looksLikeAFunctionString(t)?makeFunctionFromString(t):t}))}catch(n){return{}}}export const jsonSerializer={stringify:stringifyWithFns,parse:parseWithFns};
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"@armit/babel-merge";import babelPluginImport from"@flatjs/babel-plugin-import";import{logger}from"@flatjs/common";import{reactBabelPreset,vueBabelPreset}from"@flatjs/evolve-preset-babel";import{moduleName}from"../constants.js";export const mergeBabelOption=(e=[],r={usePreset:"react"})=>{const t=e.map((e=>[babelPluginImport,{transformToDefaultImport:!1,libraryDirectory:"dist",...e},e.libraryName])),{usePreset:a="react",...l}=r,o="react"===a?reactBabelPreset():"vue"===a?vueBabelPreset():reactBabelPreset();let m={};try{m=babelMerge(o,l),m.plugins?m.plugins.unshift(...t):m.plugins=t}catch(e){logger.error(e,moduleName)}return{...m,babelrc:!1,compact:!1}};
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"@flatjs/common";import{ignoreEntryOptionKeys}from"../constants.js";import{deleteObjectKeys}from"./delete-object-keys.js";import{normalizeTemplateInjectTokens}from"./normalize-template-inject-tokens.js";export const normalizeCheckEntryOptions=(e,t,o=ignoreEntryOptionKeys)=>{const n={mode:e?"development":"production",envCdn:urlJoin(e?"http://dev.flatjs.com":"https://file.40017.cn/jinfu",["public"])},r=normalizeTemplateInjectTokens(n,t),i={...t,...r};return deleteObjectKeys(i,o)};
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{join}from"node:path";import _ from"lodash";const normalizeEntryGroupOptions=o=>o&&o.groupName?{groupName:o.groupName,groupingSource:"manual"}:{groupingSource:"auto"};export const normalizeEvolveEntryName=(o,r)=>{const e=o.replace(/^\//,""),n=r.replace(/^\//,"");return(e.startsWith(n)?e:join(n,e)).replace(/\/$/,"")};export const normalizeEvolveEntryMap=(o={},r={})=>{const e={};for(const[n,t]of Object.entries(r)){const r={options:{}};if(o[n]){const p=normalizeEntryGroupOptions(t);e[n]=_.merge({},r,t,o[n],p)}}return e};
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"./normalize-entry-map.js";export const normalizeGroupName=(r,o)=>{const e=Array.from({length:26},((r,o)=>String.fromCharCode(65+o))),m=[...Array.from({length:26},((r,o)=>String.fromCharCode(97+o))),...e],n=Math.floor(o/52);return normalizeEvolveEntryName(`${m[o%52]}${n||""}`,r)};
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
- export const normalizePageProxy=(e="/pages")=>"/"+(e.replace(/^\//,"").replace(/\/$/,"")||"pages");
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"node:path";export const normalizeResolveAlias=(e,o={})=>{for(const[r,t]of Object.entries(o))o[r]=resolve(e,t);return o};
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"./get-html-plugin-config.js";export const normalizeTemplateInjectTokens=(e,t)=>({headBeforeHtmlTags:getHtmlPluginConfig("headBeforeHtmlTags",e,t?.headBeforeHtmlTags),inlineScripts:getHtmlPluginConfig("inlineScripts",e,t?.inlineScripts),headBeforeStyles:getHtmlPluginConfig("headBeforeStyles",e,t?.headBeforeStyles),headBeforeScripts:getHtmlPluginConfig("headBeforeScripts",e,t?.headBeforeScripts),bodyAfterScripts:getHtmlPluginConfig("bodyAfterScripts",e,t?.bodyAfterScripts)});
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"better-opn";export const openPage=n=>{try{opn(n)}catch(n){console.warn("Unable to open browser. If you are running in a headless environment\n")}};
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"@flatjs/common";import{moduleName}from"../constants.js";export const printInfo=(r,o=!1)=>{o||logger.info(r,moduleName)};export const printError=r=>{logger.error(r,moduleName)};const formatCompilerError=(r,o=[])=>{if(!r)return o;if("string"==typeof r)o.push(r);else if(Array.isArray(r))for(const e of r)formatCompilerError(e,o);else if("object"==typeof r){const e=r.stack||r.message;delete r.stack,delete r.message;const t={...r,_newMsg:e};for(const[,r]of Object.entries(t))formatCompilerError(r,o)}return o};export const printCompilerError=r=>{const o=formatCompilerError(r,[]);for(const r of o)console.log(r);return o};
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}from"@flatjs/common";import{loadMockConfig,getMockCwd}from"@flatjs/mock";import _ from"lodash";export const refreshEvolveMockOptions=async(o,t,e)=>{const s=t.devServer,r=e?.esmLoaderOptions,i=r?.externals||[],n={projectCwd:o,resolve:requireResolve},c=await loadMockConfig(n,o,s?.mockOptions||{},_.merge({},e,{configFile:"flatjs-mock",esmLoaderOptions:{externals:[...i,"@flatjs/mock"]}}));if(s){s.mockOptions=c||{},s.mockOptions&&!s.mockOptions.https&&(s.mockOptions.https=s?.https);const o=getMockCwd(c);Array.isArray(s?.watchOptions?.ignored)&&s?.watchOptions?.ignored.push(o)}return t};
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"@armit/file-utility";import{arrayUnique}from"@flatjs/common";export const resolveEntryMapInputFiles=async(t,r)=>{const e=[];for(const[,t]of Object.entries(r)){const r=t.entry.map((t=>t.replace(/.(?:js|jsx|tsx|ts)$/,"")+".*"));e.push(...r)}const o=arrayUnique(e);return await fileWalk(o,{cwd:t,absolute:!0})};
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(n="",e=""){return n.replace(/\/$/,"")+"/"+e.replace(/^\//,"")}export function cdnFinder(n,e){const r=window.location.href,o=/[?&]env(=([^&#]*)|&|#|$)/.exec(r);let t=o&&o[2]?decodeURIComponent(o[2].replace(/\+/g," ")):"prod";t=e&&e(r)||t;const c=n[t]||n.prod||[];return c[Math.floor(Math.random()*c.length)].replace(/\/$/,"")+"/"}export function findEnvCdn(n={},e="prod"){const r=n[e]||n.prod||[];return r[Math.floor(Math.random()*r.length)]}export function injectFederationScripts(n,e=function cdnResolver(){}){return`window.evolveFetchMicroWidgets = function () {\n var cdnConfig = ${JSON.stringify(n)};\n var cdnResolver = ${e.toString()};\n var cdnFinder = ${cdnFinder.toString()};\n return (cdnFinder(cdnConfig, cdnResolver) || '').replace(/\\/$/, '');\n }\n `}
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=(e,o,t)=>{const r=o[1],s=!!r.options?.moduleFederation,a=!!r.options?.output?.library;return e&&"react"===t.loaderOptions.babelOptions?.usePreset&&!s&&!a&&!0!==t.devServer?.liveReload};
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"lodash";import{ignoreEntryOptionKeys,maxEntryGroupSize}from"../constants.js";import{isDeepEqual}from"./is-deep-equal.js";import{normalizeCheckEntryOptions}from"./normalize-check-entry-options.js";import{normalizeGroupName}from"./normalize-group-name.js";export const manualGrouping=o=>{const e=_.groupBy(o,(o=>o.groupName)),t=[];for(const[,o]of Object.entries(e)){const e=o.reduce(((o,e)=>(o[e.entryName]=_.omitBy(e,"entryName"),o)),{});t.push(e)}return t};export const autoGroupingReduce=(o,e=[],t)=>_.reduce(o,((o,r,n)=>{let s=`auto_grouping_reduce-${n}`;const u=normalizeCheckEntryOptions(t,r.options,e);for(const[r,n]of Object.entries(o)){const o=Object.values(n)[0],i=normalizeCheckEntryOptions(t,o.options,e);if(isDeepEqual(u,i)){s=r;break}}return o[s]=_.merge(o[s],{[r.entryName]:_.omitBy(r,"entryName")}),o}),{});export const autoAssignGroupName=(o,e)=>{const{projectVirtualPath:t}=o,r=[];let n=0;for(const o of e){const e={},s=normalizeGroupName(t,n++);for(const[t,r]of Object.entries(o))r.groupName=s,e[t]=r;r.push(e)}return r};export const autoGrouping=(o,e,t=[],r=maxEntryGroupSize,n)=>{const s=autoGroupingReduce(e,t,n),u=[];for(const[,o]of Object.entries(s)){const e=Object.keys(o);if(e.length>r)for(let t=0;t<e.length;t+=r){const n=e.slice(t,t+r).reduce(((e,t)=>(e[t]=o[t],e)),{});u.push(n)}else u.push(o)}return autoAssignGroupName(o,u)};export const splitToEntryGroup=(o,e,t=ignoreEntryOptionKeys,r)=>{const{isolation:n=!1}=e;if(n){const e=[];for(const[t,r]of Object.entries(o))r.groupName=t,e.push({[t]:r});return e}const s=_.flatMap(o,((o,e)=>({...o,entryName:e}))),u=_.groupBy(s,(o=>o.groupingSource));return[...manualGrouping(u.manual),...autoGrouping(e,u.auto,t,maxEntryGroupSize,r)]};
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"../constants.js";import{isDeepEqual}from"./is-deep-equal.js";import{normalizeCheckEntryOptions}from"./normalize-check-entry-options.js";export const verifyGroupEntryOptions=(n,o=ignoreEntryOptionKeys,t)=>{const e=Object.values(n);if(1===e.length)return!0;const r=e.shift(),i=normalizeCheckEntryOptions(t,r?.options,o);return e.every((n=>isDeepEqual(i,normalizeCheckEntryOptions(t,n.options,o))))};
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"./define-config/index.js";export*from"./load-config/index.js";export*from"./main/index.js";export*from"./types/types-options.js";export*from"./types/types-entry-map.js";
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"./load-evolve-config.js";
1
+ export * from './load-evolve-config.js';