@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.
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';