@flatjs/evolve 2.1.0-next.3 → 2.1.0-next.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/dist/constants.js +26 -1
  2. package/dist/create-webpack/create-externals.js +6 -1
  3. package/dist/create-webpack/create-optimization.js +41 -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 +77 -1
  7. package/dist/create-webpack/create-resolve.js +37 -1
  8. package/dist/create-webpack/create-rule-sets.js +19 -1
  9. package/dist/create-webpack/load-webpack-config.js +56 -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 +50 -1
  13. package/dist/create-webpack/rule-sets/rule-css.js +101 -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 +84 -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-tasks.js +52 -1
  25. package/dist/dev-server/create-dev-server-entries.js +27 -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 +42 -1
  36. package/dist/dev-server/middlewares/get-page-module-html.js +120 -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-only-single-entry-item.js +23 -1
  44. package/dist/helpers/chunk-entry-map.js +21 -1
  45. package/dist/helpers/enable-bundle-hashname-for-module.js +6 -1
  46. package/dist/helpers/filter-actived-entries.js +42 -1
  47. package/dist/helpers/get-bundle-file-name.js +23 -1
  48. package/dist/helpers/get-git-root.js +4 -1
  49. package/dist/helpers/get-html-plugin-config.js +47 -1
  50. package/dist/helpers/get-max-process-tasks.js +7 -1
  51. package/dist/helpers/get-pacakge-dir.js +13 -1
  52. package/dist/helpers/index.js +17 -1
  53. package/dist/helpers/json-serializer.js +52 -1
  54. package/dist/helpers/merge-babel-options.js +45 -1
  55. package/dist/helpers/normalize-entry-map.js +38 -1
  56. package/dist/helpers/normalize-page-proxy.js +9 -1
  57. package/dist/helpers/normalize-resolve-alias.js +7 -1
  58. package/dist/helpers/open-page.js +15 -1
  59. package/dist/helpers/print-log.js +49 -1
  60. package/dist/helpers/refresh-evolve-mock-options.js +34 -1
  61. package/dist/helpers/resolve-entry-map-input-files.js +20 -1
  62. package/dist/helpers/script-injects.js +39 -1
  63. package/dist/helpers/should-enable-react-fast-refresh.js +10 -1
  64. package/dist/helpers/split-to-multi-compiler.js +32 -1
  65. package/dist/index.js +5 -1
  66. package/dist/load-config/index.js +1 -1
  67. package/dist/load-config/load-evolve-config.js +41 -1
  68. package/dist/load-config/types.js +1 -1
  69. package/dist/main/create-thread-worker.js +42 -1
  70. package/dist/main/env-verify.js +21 -1
  71. package/dist/main/get-worker-path.js +5 -1
  72. package/dist/main/index.js +4 -1
  73. package/dist/main/prepare-build.js +38 -1
  74. package/dist/main/prepare-serve.js +45 -1
  75. package/dist/main/prepare-static.js +30 -1
  76. package/dist/main/start-build-dynamic.js +157 -1
  77. package/dist/main/start-build-worker.js +46 -1
  78. package/dist/main/start-build.js +53 -1
  79. package/dist/main/start-one-entry-build.js +35 -1
  80. package/dist/main/start-serve.js +34 -1
  81. package/dist/main/start-static.js +19 -1
  82. package/dist/minimizer/create-minimizers.js +25 -1
  83. package/dist/minimizer/default-options.js +14 -1
  84. package/dist/minimizer/image-minimizer.js +65 -1
  85. package/dist/minimizer/index.js +1 -1
  86. package/dist/minimizer/terser-minimizer.js +15 -3
  87. package/dist/minimizer/types.js +1 -1
  88. package/dist/plugins/circular-dependency/circular-dependency-plugin.js +119 -1
  89. package/dist/plugins/circular-dependency/index.js +15 -1
  90. package/dist/plugins/clean-webpack/clean-webpack-plugin.js +173 -1
  91. package/dist/plugins/clean-webpack/index.js +22 -1
  92. package/dist/plugins/define-variable/define-variable-plugin.js +28 -1
  93. package/dist/plugins/define-variable/index.js +1 -1
  94. package/dist/plugins/html-inject-scripts/plugin-html-inject-script.js +27 -1
  95. package/dist/plugins/module-federation/external-template-remotes.js +92 -1
  96. package/dist/plugins/module-federation/index.js +1 -1
  97. package/dist/plugins/module-federation/module-federation.js +98 -1
  98. package/dist/plugins/multi-html/index.js +15 -1
  99. package/dist/plugins/multi-html/multi-html-cdn-plugin.js +84 -1
  100. package/dist/plugins/multi-html/multi-html-plugin.js +70 -1
  101. package/dist/plugins/ts-checker/index.d.ts +1 -0
  102. package/dist/plugins/ts-checker/index.js +1 -0
  103. package/dist/plugins/ts-checker/ts-checker-plugin.d.ts +4 -0
  104. package/dist/plugins/ts-checker/ts-checker-plugin.js +18 -0
  105. package/dist/types/index.js +8 -1
  106. package/dist/types/types-ci.js +1 -1
  107. package/dist/types/types-dev-server.js +1 -1
  108. package/dist/types/types-entry-map.js +1 -1
  109. package/dist/types/types-federation.js +1 -1
  110. package/dist/types/types-loader-options.js +1 -1
  111. package/dist/types/types-modular-import.js +1 -1
  112. package/dist/types/types-multi-html.js +1 -1
  113. package/dist/types/types-options.js +1 -1
  114. package/dist/types/types-plugin-options.js +1 -1
  115. package/dist/types/types-webpack.js +1 -1
  116. package/package.json +5 -5
@@ -1 +1,25 @@
1
- import{getSortedModules}from"./get-all-sorted-modules.js";import{getBundleAsset}from"./get-bundle-asset.js";import{getHmrRuntimeChunks}from"./get-hmr-runtime-chunks.js";export const getRuntimeManifest=async(e,t,s)=>{const r=getSortedModules(s,e,t),n={};for(const t of r){const{entryName:r,isServedEntry:o,entryContent:m,devServerHostUri:u,normalizedEntryName:d}=t,i=[getBundleAsset(u,d,".js")],g=[getBundleAsset(u,d,".css")],l=getHmrRuntimeChunks(e,r,d,m,s,u);n[d]={entryName:r,styles:g,scripts:i,isServed:o,runtimeChunks:l}}return n};
1
+ import { getSortedModules } from './get-all-sorted-modules.js';
2
+ import { getBundleAsset } from './get-bundle-asset.js';
3
+ import { getHmrRuntimeChunks } from './get-hmr-runtime-chunks.js';
4
+ export const getRuntimeManifest = async (servedDevServerEntries, devHostUri, evolveOptions) => {
5
+ const sortedModules = getSortedModules(evolveOptions, servedDevServerEntries, devHostUri);
6
+ const runtimeManifest = {};
7
+ for (const moduleItem of sortedModules) {
8
+ const { entryName, isServedEntry, entryContent, devServerHostUri, normalizedEntryName, } = moduleItem;
9
+ const bundleScripts = [
10
+ getBundleAsset(devServerHostUri, normalizedEntryName, '.js'),
11
+ ];
12
+ const bundleStyles = [
13
+ getBundleAsset(devServerHostUri, normalizedEntryName, '.css'),
14
+ ];
15
+ const hmrRuntimeChunks = getHmrRuntimeChunks(servedDevServerEntries, entryName, normalizedEntryName, entryContent, evolveOptions, devServerHostUri);
16
+ runtimeManifest[normalizedEntryName] = {
17
+ entryName,
18
+ styles: bundleStyles,
19
+ scripts: bundleScripts,
20
+ isServed: isServedEntry,
21
+ runtimeChunks: hmrRuntimeChunks,
22
+ };
23
+ }
24
+ return runtimeManifest;
25
+ };
@@ -1 +1,2 @@
1
- export*from"./create-page-middleware.js";export*from"./create-public-assets-middleware.js";
1
+ export * from './create-page-middleware.js';
2
+ export * from './create-public-assets-middleware.js';
@@ -1 +1 @@
1
- export{};
1
+ export {};
@@ -1 +1,10 @@
1
- export class EvolveBuildError extends Error{constructor(r,e){let o=r;e&&(o+=": "+JSON.stringify(e)),super(o),this.code=r}}
1
+ export class EvolveBuildError extends Error {
2
+ constructor(code, messages) {
3
+ let message = code;
4
+ if (messages) {
5
+ message += ': ' + JSON.stringify(messages);
6
+ }
7
+ super(message);
8
+ this.code = code;
9
+ }
10
+ }
@@ -1 +1,6 @@
1
- export const allowPx2remForModule=(o,e)=>{const l=e?.loaderOptions?.pixelOptions;return!!((o&&o[1]?.options?.allowPx2rem)??l)};
1
+ export const allowPx2remForModule = (entryItem, evolveOptions) => {
2
+ // Global settings for `AllowPx2Rem`
3
+ const globalAllowPx2Rem = evolveOptions?.loaderOptions?.pixelOptions;
4
+ const currItemPx2Rem = (entryItem && entryItem[1]?.options?.allowPx2rem) ?? globalAllowPx2Rem;
5
+ return !!currItemPx2Rem;
6
+ };
@@ -1 +1,23 @@
1
- import{normalizeEvolveEntryName}from"./normalize-entry-map.js";export const assertOnlySingleEntryItem=(e,r)=>{if(Object.keys(e).length>1)throw new Error("Only single one entry map support right now for `serve`, `build`!");let t;for(const[r,o]of Object.entries(e)){t=[r,o];break}if(!t)throw new Error('No entry map found while "serve", "build" process!');const[o,n]=t;return[normalizeEvolveEntryName(o,r.projectVirtualPath),n]};
1
+ import { normalizeEvolveEntryName } from './normalize-entry-map.js';
2
+ /**
3
+ * Only fetch single one entry map once `serve`,`build` recycle.
4
+ * @returns
5
+ */
6
+ export const assertOnlySingleEntryItem = (entryMap, evolveOptions) => {
7
+ if (Object.keys(entryMap).length > 1) {
8
+ throw new Error('Only single one entry map support right now for `serve`, `build`!');
9
+ }
10
+ let result = undefined;
11
+ for (const [entryChunkName, entryItem] of Object.entries(entryMap)) {
12
+ result = [entryChunkName, entryItem];
13
+ break;
14
+ }
15
+ if (!result) {
16
+ throw new Error(`No entry map found while "serve", "build" process!`);
17
+ }
18
+ const [entryName, entryConfig] = result;
19
+ // Make sure that we have correct `virtualPath` for each webpack `entry`
20
+ const normalizedEntryName = normalizeEvolveEntryName(entryName, evolveOptions.projectVirtualPath);
21
+ `entry`;
22
+ return [normalizedEntryName, entryConfig];
23
+ };
@@ -1 +1,21 @@
1
- import{arrayChunk}from"@flatjs/common";export const chunkEntryMap=(r,o=2)=>{const n=Object.keys(r),t=arrayChunk(n,o),c=[];for(const o of t){const n=o.reduce(((o,n)=>({...o,[n]:r[n]})),{});c.push(n)}return c};
1
+ import { arrayChunk } from '@flatjs/common';
2
+ /**
3
+ * Split entryMap into multi entryMap with a `size`
4
+ * @param entryMap
5
+ * @param size
6
+ */
7
+ export const chunkEntryMap = (entryMap, size = 2) => {
8
+ const keys = Object.keys(entryMap);
9
+ const entryKeyChunks = arrayChunk(keys, size);
10
+ const finalEntryMaps = [];
11
+ for (const keys of entryKeyChunks) {
12
+ const chunkMap = keys.reduce((prev, curr) => {
13
+ return {
14
+ ...prev,
15
+ [curr]: entryMap[curr],
16
+ };
17
+ }, {});
18
+ finalEntryMaps.push(chunkMap);
19
+ }
20
+ return finalEntryMaps;
21
+ };
@@ -1 +1,6 @@
1
- export const enableBundleHashNameForModule=(e,a)=>{const n=e.webpack?.enableBundleHashName;return!!(a?.enableBundleHashName??n)};
1
+ export const enableBundleHashNameForModule = (evolveOptions, entryItemOption) => {
2
+ // Global settings for `enableBundleHashName`
3
+ const globalEnabledStatus = evolveOptions.webpack?.enableBundleHashName;
4
+ const bundleHashNameEnabled = entryItemOption?.enableBundleHashName ?? globalEnabledStatus;
5
+ return !!bundleHashNameEnabled;
6
+ };
@@ -1 +1,42 @@
1
- import{arraysIntersect,normalizeSemicolonFilterParts}from"@flatjs/common";import{resolveEntryMapInputFiles}from"./resolve-entry-map-input-files.js";export const filterActivedEntriesByModule=(t,e)=>{const r=normalizeSemicolonFilterParts(e),n={};for(const[e,o]of Object.entries(t)){r.find((t=>("string"==typeof t||"number"==typeof t?new RegExp(`${t}`):t).test(e)))&&(n[e]=o)}return n};export const filterActivedEntriesByEntryInputs=async(t,e,r)=>{const n={};for(const[o,s]of Object.entries(e)){const e=await resolveEntryMapInputFiles(t,{[o]:s});arraysIntersect(e,r)&&(n[o]=s)}return n};
1
+ import { arraysIntersect, normalizeSemicolonFilterParts } from '@flatjs/common';
2
+ import { resolveEntryMapInputFiles } from './resolve-entry-map-input-files.js';
3
+ /**
4
+ * Filter to find actived entry input by entry name filter.
5
+ * @param definedEntries
6
+ * @param modules `home;mine;`
7
+ * @returns activedEntries
8
+ */
9
+ export const filterActivedEntriesByModule = (definedEntries, modules) => {
10
+ const patterns = normalizeSemicolonFilterParts(modules);
11
+ const newActivedEntries = {};
12
+ for (const [entryKey, itemConfig] of Object.entries(definedEntries)) {
13
+ const matched = patterns.find((m) => {
14
+ // Also need to support `numeric` named module.
15
+ const testRegExp = typeof m === 'string' || typeof m === 'number' ? new RegExp(`${m}`) : m;
16
+ return testRegExp.test(entryKey);
17
+ });
18
+ if (matched) {
19
+ newActivedEntries[entryKey] = itemConfig;
20
+ }
21
+ }
22
+ return newActivedEntries;
23
+ };
24
+ /**
25
+ * Filter to find actived entry input by absolute entry filepath
26
+ * @param projectCwd
27
+ * @param definedEntries
28
+ * @param entryInputs [`/xxxx/x/xxxx/src/home/index.tsx`]
29
+ * @returns activedEntries
30
+ */
31
+ export const filterActivedEntriesByEntryInputs = async (projectCwd, definedEntries, entryInputs) => {
32
+ const newActivedEntries = {};
33
+ for (const [entryKey, itemConfig] of Object.entries(definedEntries)) {
34
+ const entryAbsFiles = await resolveEntryMapInputFiles(projectCwd, {
35
+ [entryKey]: itemConfig,
36
+ });
37
+ if (arraysIntersect(entryAbsFiles, entryInputs)) {
38
+ newActivedEntries[entryKey] = itemConfig;
39
+ }
40
+ }
41
+ return newActivedEntries;
42
+ };
@@ -1 +1,23 @@
1
- export const currNow=()=>Date.now().toString();export const getBundleFileName=(e,n,t=!0)=>{const o="js"===e?".js":".css";return n?`bundle${o}`:t?`bundle[contenthash]${o}`:`bundle${o}?${currNow()}`};
1
+ /**
2
+ * Get current timestramp as `string`
3
+ */
4
+ export const currNow = () => Date.now().toString();
5
+ /**
6
+ * Generate bundle file name from rules
7
+ * 1. if `serveMode`, always return `bundle
8
+ * 2. else if `enableBundleHashName` always return `bundle[contenthash].{css,js}`
9
+ * 3. otherwise return `bundle.{css,js}?${currNow}`
10
+ * @param type `js` | `css`
11
+ * @param serveMode If we are run `serve` mode
12
+ * @param enableBundleHashName If we need to generate bundle file name with `[contenthash]`
13
+ */
14
+ export const getBundleFileName = (type, serveMode, enableBundleHashName = true) => {
15
+ const fileEndFix = type === 'js' ? '.js' : '.css';
16
+ if (serveMode) {
17
+ return `bundle${fileEndFix}`;
18
+ }
19
+ if (enableBundleHashName) {
20
+ return `bundle[contenthash]${fileEndFix}`;
21
+ }
22
+ return `bundle${fileEndFix}?${currNow()}`;
23
+ };
@@ -1 +1,4 @@
1
- import{searchParentDir}from"@armit/package";export const getGitRoot=r=>searchParentDir(r,".git");
1
+ import { searchParentDir } from '@armit/package';
2
+ export const getGitRoot = (searchFrom) => {
3
+ return searchParentDir(searchFrom, '.git');
4
+ };
@@ -1 +1,47 @@
1
- import{polyfill,viewportScripts}from"../constants.js";import{getPackageDir}from"./get-pacakge-dir.js";export const defaultHtmlPluginConfig={title:"",favicon:"",headBeforeHtmlTags:[],inlineScripts:[],headBeforeStyles:[],headBeforeScripts:[...polyfill],bodyAfterScripts:[],viewport:viewportScripts,excludeCdnEnvs:["me","dev","ntv"],htmlMinify:!0,templatePath:getPackageDir("templates/html-plugin/index-{0}.html")};export const getHtmlPluginConfig=(t,e,i)=>{let o;if(void 0!==i&&(o="function"==typeof i?i(e):i),void 0===o){const i=defaultHtmlPluginConfig[t];return"function"==typeof i?i(e):i}return o};
1
+ import { polyfill, viewportScripts } from '../constants.js';
2
+ import { getPackageDir } from './get-pacakge-dir.js';
3
+ export const defaultHtmlPluginConfig = {
4
+ // The page title
5
+ title: '',
6
+ // The page favicon url地址
7
+ favicon: '',
8
+ // The customized html tags should be inject to `<header />`
9
+ headBeforeHtmlTags: [],
10
+ // Allow us customized inline scripts into compiled html template.
11
+ inlineScripts: [],
12
+ // The ordered styles will be injected start of html head.
13
+ headBeforeStyles: [],
14
+ // The ordered scripts will be injected before html head.
15
+ headBeforeScripts: [...polyfill],
16
+ // The ordered scripts will be injected end of html body.
17
+ bodyAfterScripts: [],
18
+ // `allowPx2rem` default is true
19
+ viewport: viewportScripts,
20
+ // avoid use cdn `me`, `dev`, `ntv`
21
+ excludeCdnEnvs: ['me', 'dev', 'ntv'],
22
+ // `minify` is true, `dev` always don't minify.
23
+ htmlMinify: true,
24
+ // Default use It must be an absolute path.
25
+ templatePath: getPackageDir('templates/html-plugin/index-{0}.html'),
26
+ };
27
+ /**
28
+ * 获取html plugin 模版相关定义字段.
29
+ * @param preferredValue 用户首选的值, 如果返回为undefined, 将使用默认值
30
+ * @returns
31
+ */
32
+ export const getHtmlPluginConfig = (key, configData, preferredValue) => {
33
+ let userValue;
34
+ if (typeof preferredValue !== 'undefined') {
35
+ userValue =
36
+ typeof preferredValue === 'function'
37
+ ? preferredValue(configData)
38
+ : preferredValue;
39
+ }
40
+ if (typeof userValue === 'undefined') {
41
+ const defaultValue = defaultHtmlPluginConfig[key];
42
+ return typeof defaultValue === 'function'
43
+ ? defaultValue(configData)
44
+ : defaultValue;
45
+ }
46
+ return userValue;
47
+ };
@@ -1 +1,7 @@
1
- import{cpus}from"node:os";export const getMaxProcessTasks=(t,s)=>{const e=Math.max(1,"string"==typeof s&&s.endsWith("%")?Math.round(cpus().length*Number(s.slice(0,-1))/100):Number(s));return t>e?e:Math.max(1,t)};
1
+ import { cpus } from 'node:os';
2
+ export const getMaxProcessTasks = (totalTasks, maxProcesses) => {
3
+ const maxCpu = Math.max(1, typeof maxProcesses === 'string' && maxProcesses.endsWith('%')
4
+ ? Math.round((cpus().length * Number(maxProcesses.slice(0, -1))) / 100)
5
+ : Number(maxProcesses));
6
+ return totalTasks > maxCpu ? maxCpu : Math.max(1, totalTasks);
7
+ };
@@ -1 +1,13 @@
1
- import{join}from"node:path";import{getDirname}from"@armit/file-utility";import{searchPackageDir}from"@armit/package";export const getPackageDir=(...r)=>{const e=getDirname(import.meta.url),o=searchPackageDir({cwd:e});if(!o)throw new Error("Could not resolve package root for `flatjs/evolve`");return join(o,...r)};
1
+ import { join } from 'node:path';
2
+ import { getDirname } from '@armit/file-utility';
3
+ import { searchPackageDir } from '@armit/package';
4
+ export const getPackageDir = (...paths) => {
5
+ const dir = getDirname(import.meta.url);
6
+ const packageDir = searchPackageDir({
7
+ cwd: dir,
8
+ });
9
+ if (!packageDir) {
10
+ throw new Error('Could not resolve package root for `flatjs/evolve`');
11
+ }
12
+ return join(packageDir, ...paths);
13
+ };
@@ -1 +1,17 @@
1
- export*from"./allow-px2rem-for-module.js";export*from"./assert-only-single-entry-item.js";export*from"./chunk-entry-map.js";export*from"./enable-bundle-hashname-for-module.js";export*from"./get-bundle-file-name.js";export*from"./get-html-plugin-config.js";export*from"./get-pacakge-dir.js";export*from"./merge-babel-options.js";export*from"./normalize-entry-map.js";export*from"./open-page.js";export*from"./print-log.js";export*from"./refresh-evolve-mock-options.js";export*from"./script-injects.js";export*from"./should-enable-react-fast-refresh.js";export*from"./split-to-multi-compiler.js";export*from"./json-serializer.js";export*from"./normalize-resolve-alias.js";
1
+ export * from './allow-px2rem-for-module.js';
2
+ export * from './assert-only-single-entry-item.js';
3
+ export * from './chunk-entry-map.js';
4
+ export * from './enable-bundle-hashname-for-module.js';
5
+ export * from './get-bundle-file-name.js';
6
+ export * from './get-html-plugin-config.js';
7
+ export * from './get-pacakge-dir.js';
8
+ export * from './merge-babel-options.js';
9
+ export * from './normalize-entry-map.js';
10
+ export * from './open-page.js';
11
+ export * from './print-log.js';
12
+ export * from './refresh-evolve-mock-options.js';
13
+ export * from './script-injects.js';
14
+ export * from './should-enable-react-fast-refresh.js';
15
+ export * from './split-to-multi-compiler.js';
16
+ export * from './json-serializer.js';
17
+ export * from './normalize-resolve-alias.js';
@@ -1 +1,52 @@
1
- function stringifyWithFns(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,38 @@
1
- import{join}from"node:path";import _ from"lodash";export const normalizeEvolveEntryName=(o,e)=>{const r=o.replace(/^\//,""),t=e.replace(/^\//,"");return(r.startsWith(t)?r:join(t,r)).replace(/\/$/,"")};export const normalizeEvolveEntryMap=(o={},e={})=>{const r={};for(const[t,n]of Object.entries(e)){const e={options:{}};o[t]&&(r[t]=_.merge({},e,n,o[t])),_.merge(n,e)}return r};
1
+ import { join } from 'node:path';
2
+ import _ from 'lodash';
3
+ /**
4
+ * Make sure that we have correct `virtualPath` for each webpack `entry`
5
+ * @param entryName the entryName defined via `flatjs-evolve.config.ts`.
6
+ * @param evolveOptions
7
+ * @returns
8
+ */
9
+ export const normalizeEvolveEntryName = (entryName, projectVirtualPath) => {
10
+ const servedEntryName = entryName.replace(/^\//, '');
11
+ const virtualPath = projectVirtualPath.replace(/^\//, '');
12
+ const withVirtualPath = servedEntryName.startsWith(virtualPath);
13
+ // Make sure that we have correct `virtualPath` for each webpack `entry`
14
+ const finalEntryName = withVirtualPath
15
+ ? servedEntryName
16
+ : join(virtualPath, servedEntryName);
17
+ return finalEntryName.replace(/\/$/, '');
18
+ };
19
+ /**
20
+ * Normalize flatjs.evolve entry map definition data.
21
+ * Merge default entry item configuration values.
22
+ * @param activedEntryMap actived entries
23
+ * @param definedEntryMap defined entries in flatjs.evolve.js
24
+ */
25
+ export const normalizeEvolveEntryMap = (activedEntryMap = {}, definedEntryMap = {}) => {
26
+ const newActivedEntries = {};
27
+ for (const [entryKey, itemConfig] of Object.entries(definedEntryMap)) {
28
+ // Setup default entry options.
29
+ const defaultEntryItemConfig = {
30
+ options: {},
31
+ };
32
+ if (activedEntryMap[entryKey]) {
33
+ newActivedEntries[entryKey] = _.merge({}, defaultEntryItemConfig, itemConfig, activedEntryMap[entryKey]);
34
+ }
35
+ _.merge(itemConfig, defaultEntryItemConfig);
36
+ }
37
+ return newActivedEntries;
38
+ };
@@ -1 +1,9 @@
1
- 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,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,10 @@
1
- export const shouldEnableReactFastRefresh=(e,o,t)=>{const r=o[1],s=!!r.options?.moduleFederation;return e&&"react"===t.loaderOptions.babelOptions?.usePreset&&!s&&!0!==t.devServer?.liveReload};
1
+ export const shouldEnableReactFastRefresh = (serveMode, entryMapItem, evolveOptions) => {
2
+ const entryItemOption = entryMapItem[1];
3
+ const hasModuleFederation = !!entryItemOption.options?.moduleFederation;
4
+ // Inject `react-refresh` if we are using preset `react`
5
+ return (serveMode &&
6
+ evolveOptions.loaderOptions.babelOptions?.usePreset === 'react' &&
7
+ !hasModuleFederation &&
8
+ // No specificed `liveReload` config
9
+ evolveOptions.devServer?.liveReload !== true);
10
+ };