@flatjs/evolve 2.1.0-next.26 → 2.1.0-next.28

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. package/dist/constants.d.ts +4 -0
  2. package/dist/constants.js +1 -1
  3. package/dist/create-webpack/create-plugins.d.ts +2 -1
  4. package/dist/create-webpack/create-plugins.js +1 -1
  5. package/dist/create-webpack/load-webpack-config.d.ts +2 -1
  6. package/dist/create-webpack/load-webpack-config.js +1 -1
  7. package/dist/dev-server/add-compiler-to-dev-server.js +1 -1
  8. package/dist/helpers/format-spinner-text.d.ts +3 -2
  9. package/dist/helpers/format-spinner-text.js +1 -1
  10. package/dist/helpers/get-stats-file-name.d.ts +2 -0
  11. package/dist/helpers/get-stats-file-name.js +1 -0
  12. package/dist/helpers/index.d.ts +1 -0
  13. package/dist/helpers/index.js +1 -1
  14. package/dist/main/prepare-analyzer.d.ts +9 -0
  15. package/dist/main/prepare-analyzer.js +1 -0
  16. package/dist/main/prepare-build.d.ts +2 -1
  17. package/dist/main/prepare-build.js +1 -1
  18. package/dist/main/start-analyzer.d.ts +10 -0
  19. package/dist/main/start-analyzer.js +1 -0
  20. package/dist/main/start-build-dynamic.js +1 -1
  21. package/dist/main/start-build-worker.d.ts +3 -0
  22. package/dist/main/start-build-worker.js +1 -1
  23. package/dist/main/start-build.d.ts +2 -1
  24. package/dist/main/start-build.js +1 -1
  25. package/dist/main/start-group-entry-build.d.ts +2 -1
  26. package/dist/main/start-group-entry-build.js +1 -1
  27. package/dist/plugins/stats-webpack/helper-write-stats.d.ts +28 -0
  28. package/dist/plugins/stats-webpack/helper-write-stats.js +1 -0
  29. package/dist/plugins/stats-webpack/index.d.ts +12 -0
  30. package/dist/plugins/stats-webpack/index.js +1 -0
  31. package/dist/plugins/stats-webpack/stats-webpack-plugin.d.ts +25 -0
  32. package/dist/plugins/stats-webpack/stats-webpack-plugin.js +1 -0
  33. package/dist/types/index.d.ts +1 -0
  34. package/dist/types/index.js +1 -1
  35. package/dist/types/types-analyzer.d.ts +70 -0
  36. package/dist/types/types-analyzer.js +1 -0
  37. package/dist/types/types-cli-options.d.ts +12 -0
  38. package/dist/types/types-cli-options.js +1 -0
  39. package/dist/types/types-dev-server.d.ts +13 -1
  40. package/dist/types/types-options.d.ts +0 -4
  41. package/package.json +4 -1
@@ -27,3 +27,7 @@ export declare const devReactFastRefresh: {
27
27
  * Array of keys to ignore in the verifyGroupEntryOptions step
28
28
  */
29
29
  export declare const ignoreEntryOptionKeys: Array<keyof EvolveEntryItemOption>;
30
+ /**
31
+ * The directory where the webpack stats files are stored. relative to projectCwd
32
+ */
33
+ export declare const webpackStatsDir = ".cache/stats";
package/dist/constants.js CHANGED
@@ -1 +1 @@
1
- export const moduleName="@flatjs/evolve";export const configFileName="flatjs-evolve";export const viewportScripts='(function(d){var j;var b=1;var i=1;var h=750;var c=100;function e(s,o){var q=d.document;var l=q.documentElement;var k=navigator.userAgent;var m=k.toLowerCase().indexOf("android")>-1;i=d.devicePixelRatio||1;if(i>3){i=3}if(m){i=1}console.log("current devicePixelRatio:",i);l.setAttribute("data-dpr",i.toString());var p=q.querySelector(\'meta[name="viewport"]\');if(!p){b=1/i;p=q.createElement("meta");p.setAttribute("name","viewport");q.head.appendChild(p);p.setAttribute(["content","width=device-width,user-scalable=no,initial-scale=",b,",maximum-scale=",b,",minimum-scale=",b].join(""))}function n(){var t=document.documentElement.clientWidth;j=t/o*(s/i)*i;q.documentElement.style.fontSize=String(j)+"px"}var r;d.addEventListener("resize",function(){clearTimeout(r);r=setTimeout(n,300)},false);d.addEventListener("onload",n,false);n()}e(c,h);window.fabricViewport={currRem:j,currDpr:i,currScale:b,dpiPX2px:function f(k){return parseFloat(k.toString())/j*100+"px"},px2DPIpx:function a(k){return parseFloat(k.toString())/100*j+"px"},px2rem:function g(k){return parseFloat(k.toString())/100+"rem"}}})(window);';export const polyfill=["https://polyfill.io/v3/polyfill.min.js?features=Array.from%2CArray.isArray%2CArray.of%2CArray.prototype.entries%2CArray.prototype.every%2CArray.prototype.fill%2CArray.prototype.filter%2CArray.prototype.find%2CArray.prototype.findIndex%2CArray.prototype.flat%2CArray.prototype.forEach%2CArray.prototype.flatMap%2CArray.prototype.keys%2CArray.prototype.indexOf%2CArray.prototype.includes%2CArray.prototype.lastIndexOf%2CArray.prototype.map%2CArray.prototype.reduce%2CArray.prototype.reduceRight%2CArray.prototype.some%2CArray.prototype.sort%2CArray.prototype.values%2CArrayBuffer%2CBlob%2CDataView%2CDate.now%2CObject.assign%2CObject.create%2CObject.defineProperties%2CObject.defineProperty%2CObject.entries%2CObject.freeze%2CObject.fromEntries%2CObject.getOwnPropertySymbols%2CObject.getOwnPropertyNames%2CObject.getOwnPropertyDescriptors%2CObject.getOwnPropertyDescriptor%2CObject.getPrototypeOf%2CObject.is%2CObject.isExtensible%2CObject.isFrozen%2CObject.isSealed%2CObject.keys%2CObject.values%2CObject.setPrototypeOf%2CPromise%2CPromise.prototype.finally%2CReflect%2CReflect.apply%2CReflect.construct%2CReflect.defineProperty%2CReflect.deleteProperty%2CReflect.getPrototypeOf%2CReflect.getOwnPropertyDescriptor%2CReflect.get%2CReflect.ownKeys%2CReflect.isExtensible%2CReflect.has%2CReflect.preventExtensions%2CReflect.set%2CReflect.setPrototypeOf%2CSet%2CString.prototype.trimStart%2CString.prototype.trimEnd%2CString.prototype.trim%2CString.prototype.startsWith%2CString.prototype.repeat%2CString.prototype.replaceAll%2CString.prototype.padStart%2CString.prototype.padEnd%2CMap%2CObject.seal%2Cconsole.groupEnd%2Cconsole.group"];export const devReactFastRefresh={runtime:"reactRefreshRuntime",reactRefreshSetup:"reactRefreshSetup"};export const ignoreEntryOptionKeys=["title"];
1
+ export const moduleName="@flatjs/evolve";export const configFileName="flatjs-evolve";export const viewportScripts='(function(d){var j;var b=1;var i=1;var h=750;var c=100;function e(s,o){var q=d.document;var l=q.documentElement;var k=navigator.userAgent;var m=k.toLowerCase().indexOf("android")>-1;i=d.devicePixelRatio||1;if(i>3){i=3}if(m){i=1}console.log("current devicePixelRatio:",i);l.setAttribute("data-dpr",i.toString());var p=q.querySelector(\'meta[name="viewport"]\');if(!p){b=1/i;p=q.createElement("meta");p.setAttribute("name","viewport");q.head.appendChild(p);p.setAttribute(["content","width=device-width,user-scalable=no,initial-scale=",b,",maximum-scale=",b,",minimum-scale=",b].join(""))}function n(){var t=document.documentElement.clientWidth;j=t/o*(s/i)*i;q.documentElement.style.fontSize=String(j)+"px"}var r;d.addEventListener("resize",function(){clearTimeout(r);r=setTimeout(n,300)},false);d.addEventListener("onload",n,false);n()}e(c,h);window.fabricViewport={currRem:j,currDpr:i,currScale:b,dpiPX2px:function f(k){return parseFloat(k.toString())/j*100+"px"},px2DPIpx:function a(k){return parseFloat(k.toString())/100*j+"px"},px2rem:function g(k){return parseFloat(k.toString())/100+"rem"}}})(window);';export const polyfill=["https://polyfill.io/v3/polyfill.min.js?features=Array.from%2CArray.isArray%2CArray.of%2CArray.prototype.entries%2CArray.prototype.every%2CArray.prototype.fill%2CArray.prototype.filter%2CArray.prototype.find%2CArray.prototype.findIndex%2CArray.prototype.flat%2CArray.prototype.forEach%2CArray.prototype.flatMap%2CArray.prototype.keys%2CArray.prototype.indexOf%2CArray.prototype.includes%2CArray.prototype.lastIndexOf%2CArray.prototype.map%2CArray.prototype.reduce%2CArray.prototype.reduceRight%2CArray.prototype.some%2CArray.prototype.sort%2CArray.prototype.values%2CArrayBuffer%2CBlob%2CDataView%2CDate.now%2CObject.assign%2CObject.create%2CObject.defineProperties%2CObject.defineProperty%2CObject.entries%2CObject.freeze%2CObject.fromEntries%2CObject.getOwnPropertySymbols%2CObject.getOwnPropertyNames%2CObject.getOwnPropertyDescriptors%2CObject.getOwnPropertyDescriptor%2CObject.getPrototypeOf%2CObject.is%2CObject.isExtensible%2CObject.isFrozen%2CObject.isSealed%2CObject.keys%2CObject.values%2CObject.setPrototypeOf%2CPromise%2CPromise.prototype.finally%2CReflect%2CReflect.apply%2CReflect.construct%2CReflect.defineProperty%2CReflect.deleteProperty%2CReflect.getPrototypeOf%2CReflect.getOwnPropertyDescriptor%2CReflect.get%2CReflect.ownKeys%2CReflect.isExtensible%2CReflect.has%2CReflect.preventExtensions%2CReflect.set%2CReflect.setPrototypeOf%2CSet%2CString.prototype.trimStart%2CString.prototype.trimEnd%2CString.prototype.trim%2CString.prototype.startsWith%2CString.prototype.repeat%2CString.prototype.replaceAll%2CString.prototype.padStart%2CString.prototype.padEnd%2CMap%2CObject.seal%2Cconsole.groupEnd%2Cconsole.group"];export const devReactFastRefresh={runtime:"reactRefreshRuntime",reactRefreshSetup:"reactRefreshSetup"};export const ignoreEntryOptionKeys=["title"];export const webpackStatsDir=".cache/stats";
@@ -1,4 +1,5 @@
1
+ import { FlatCliOptions } from '../types/types-cli-options.js';
1
2
  import { type EntryMapItem } from '../types/types-entry-map.js';
2
3
  import { type FlatEvolveOptions } from '../types/types-options.js';
3
4
  import { type FlatEvolveWebpackOptions } from '../types/types-webpack.js';
4
- export declare const createPlugins: (serveMode: boolean, entryMapItemList: EntryMapItem[], evolveOptions: FlatEvolveOptions) => Promise<FlatEvolveWebpackOptions["plugins"]>;
5
+ export declare const createPlugins: (serveMode: boolean, entryMapItemList: EntryMapItem[], evolveOptions: FlatEvolveOptions, cliOptions?: FlatCliOptions) => Promise<FlatEvolveWebpackOptions["plugins"]>;
@@ -1 +1 @@
1
- import CaseSensitivePathsPlugin from"case-sensitive-paths-webpack-plugin";import MiniCssExtractPlugin from"mini-css-extract-plugin";import webpack from"webpack";import{BundleAnalyzerPlugin}from"webpack-bundle-analyzer";import{logger}from"@flatjs/common";import ReactRefreshWebpackPlugin from"@pmmmwh/react-refresh-webpack-plugin";import{enableBundleHashNameForModule}from"../helpers/enable-bundle-hashname-for-module.js";import{getBundleFileName}from"../helpers/get-bundle-file-name.js";import{shouldEnableReactFastRefresh}from"../helpers/should-enable-react-fast-refresh.js";import{createCircularDependencyPlugin}from"../plugins/circular-dependency/index.js";import{createCleanWebpackPlugin}from"../plugins/clean-webpack/index.js";import{createBuiltinDefineVariables}from"../plugins/define-variable/index.js";import{createModuleFederationPlugin}from"../plugins/module-federation/index.js";import{createHtmlPlugins}from"../plugins/multi-html/index.js";export const createPlugins=async(e,a,n)=>{const l=a[0],[r,i]=l,t=enableBundleHashNameForModule(n,i?.options),s=[new webpack.WatchIgnorePlugin({paths:[/\.d\.[cm]ts$/]}),new CaseSensitivePathsPlugin,...createCircularDependencyPlugin(e,n),new MiniCssExtractPlugin({filename:`[name]/${getBundleFileName("css",e,t)}`,chunkFilename:"[id].[contenthash].css"}),...await createBuiltinDefineVariables(e,n),...createCleanWebpackPlugin(e,a,n),...createModuleFederationPlugin(e,a,n),...createHtmlPlugins(e,a,n)];n.analyzer&&s.push(new BundleAnalyzerPlugin({analyzerPort:"auto",analyzerMode:"server",...n.analyzer}));const o=shouldEnableReactFastRefresh(e,l,n);o&&s.push(new ReactRefreshWebpackPlugin({overlay:!1})),!o&&e&&(n.devServer?.liveReload?logger.warn('The HMR disabled cause of "liveReload" specificed'):logger.warn(`The HMR disabled cause of \`"moduleFederation":"${r}"\``));const c=n.webpack?.plugins||[];return s.concat(c)};
1
+ import CaseSensitivePathsPlugin from"case-sensitive-paths-webpack-plugin";import MiniCssExtractPlugin from"mini-css-extract-plugin";import webpack from"webpack";import{logger}from"@flatjs/common";import ReactRefreshWebpackPlugin from"@pmmmwh/react-refresh-webpack-plugin";import{enableBundleHashNameForModule}from"../helpers/enable-bundle-hashname-for-module.js";import{getBundleFileName}from"../helpers/get-bundle-file-name.js";import{shouldEnableReactFastRefresh}from"../helpers/should-enable-react-fast-refresh.js";import{createCircularDependencyPlugin}from"../plugins/circular-dependency/index.js";import{createCleanWebpackPlugin}from"../plugins/clean-webpack/index.js";import{createBuiltinDefineVariables}from"../plugins/define-variable/index.js";import{createModuleFederationPlugin}from"../plugins/module-federation/index.js";import{createHtmlPlugins}from"../plugins/multi-html/index.js";import{createStatsWebpackPlugin}from"../plugins/stats-webpack/index.js";export const createPlugins=async(e,a,n,i)=>{const r=a[0],[l,t]=r,s=enableBundleHashNameForModule(n,t?.options),o=[new webpack.WatchIgnorePlugin({paths:[/\.d\.[cm]ts$/]}),new CaseSensitivePathsPlugin,...createCircularDependencyPlugin(e,n),new MiniCssExtractPlugin({filename:`[name]/${getBundleFileName("css",e,s)}`,chunkFilename:"[id].[contenthash].css"}),...await createBuiltinDefineVariables(e,n),...createCleanWebpackPlugin(e,a,n),...createModuleFederationPlugin(e,a,n),...createHtmlPlugins(e,a,n),...createStatsWebpackPlugin(e,n,i)],c=shouldEnableReactFastRefresh(e,r,n);c&&o.push(new ReactRefreshWebpackPlugin({overlay:!1})),!c&&e&&(n.devServer?.liveReload?logger.warn('The HMR disabled cause of "liveReload" specificed'):logger.warn(`The HMR disabled cause of \`"moduleFederation":"${l}"\``));const u=n.webpack?.plugins||[];return o.concat(u)};
@@ -1,4 +1,5 @@
1
1
  import { type Configuration } from 'webpack';
2
+ import { FlatCliOptions } from '../types/types-cli-options.js';
2
3
  import { type EvolveEntryMap } from '../types/types-entry-map.js';
3
4
  import { type FlatEvolveOptions } from '../types/types-options.js';
4
5
  /**
@@ -7,4 +8,4 @@ import { type FlatEvolveOptions } from '../types/types-options.js';
7
8
  * @param entryMap The only single one `servedEntry` or `toBuildEntry`
8
9
  * @param overrideOptions The manually override configuration options for flatjsEvolve
9
10
  */
10
- export declare const loadWebpackConfig: (mode: "production" | "development", entryMap: EvolveEntryMap, evolveOptions: FlatEvolveOptions) => Promise<Omit<Configuration, "entry">>;
11
+ export declare const loadWebpackConfig: (mode: "production" | "development", entryMap: EvolveEntryMap, evolveOptions: FlatEvolveOptions, cliOptions?: FlatCliOptions) => Promise<Omit<Configuration, "entry">>;
@@ -1 +1 @@
1
- import{assertGroupEntryItem}from"../helpers/assert-group-entry-item.js";import{createExternals}from"./create-externals.js";import{createOptimization}from"./create-optimization.js";import{createOutput}from"./create-output.js";import{createPerformance}from"./create-performance.js";import{createPlugins}from"./create-plugins.js";import{createResolve}from"./create-resolve.js";import{createRuleSets}from"./create-rule-sets.js";import{loadWatchOptions}from"./load-watch-options.js";export const loadWebpackConfig=async(e,t,r)=>{const a="development"===e,{projectCwd:o,webpack:s,devServer:c}=r,n=loadWatchOptions(t,r,c?.watchOptions),p=assertGroupEntryItem(t,r),i=createRuleSets(a,p,r),m=await createPlugins(a,p,r),l=p[0];return{mode:e,plugins:m,watchOptions:n,output:await createOutput(a,r,l),context:o,target:s?.target??["web","es5"],resolve:createResolve(o,s),module:{rules:i},devtool:a?"eval-source-map":s?.sourceMap||!1,externalsType:s?.externalsType,externals:createExternals(s?.externals,l),performance:createPerformance(a,s?.performance),optimization:createOptimization(a,r,l),infrastructureLogging:s?.infrastructureLogging??{level:"warn"},stats:s?.stats??{preset:"errors-warnings"},cache:{type:"memory"}}};
1
+ import{assertGroupEntryItem}from"../helpers/assert-group-entry-item.js";import{createExternals}from"./create-externals.js";import{createOptimization}from"./create-optimization.js";import{createOutput}from"./create-output.js";import{createPerformance}from"./create-performance.js";import{createPlugins}from"./create-plugins.js";import{createResolve}from"./create-resolve.js";import{createRuleSets}from"./create-rule-sets.js";import{loadWatchOptions}from"./load-watch-options.js";export const loadWebpackConfig=async(e,t,r,a)=>{const o="development"===e,{projectCwd:s,webpack:c,devServer:n}=r,p=loadWatchOptions(t,r,n?.watchOptions),i=assertGroupEntryItem(t,r),m=createRuleSets(o,i,r),l=await createPlugins(o,i,r,a),u=i[0];return{mode:e,plugins:l,watchOptions:p,output:await createOutput(o,r,u),context:s,target:c?.target??["web","es5"],resolve:createResolve(s,c),module:{rules:m},devtool:o?"eval-source-map":c?.sourceMap||!1,externalsType:c?.externalsType,externals:createExternals(c?.externals,u),performance:createPerformance(o,c?.performance),optimization:createOptimization(o,r,u),infrastructureLogging:c?.infrastructureLogging??{level:"warn"},stats:c?.stats??{preset:"errors-warnings"},cache:{type:"memory"}}};
@@ -1 +1 @@
1
- import{join}from"node:path";import WebpackDevServer from"webpack-dev-server";export const addCompilerToDevServer=(e,o,r,t,s)=>{const{projectCwd:p,devServer:c}=s,l=new WebpackDevServer({server:{type:c?.https?"https":"http",options:{...c?.https}},open:!1,compress:!0,port:r,hot:o,liveReload:!o,allowedHosts:"all",static:{directory:`${join(p,"/public")}`},headers:{"Access-Control-Allow-Origin":"*"},client:{progress:!0,overlay:c?.clientOverlay,webSocketURL:"localIp"===c?.webSocketURL?{hostname:t||void 0}:{hostname:"0.0.0.0",...c?.webSocketURL}}},e);return new Promise(((e,o)=>{l.startCallback((r=>{if(r)return o(r);e(!0)}))}))};
1
+ import{join}from"node:path";import WebpackDevServer from"webpack-dev-server";export const addCompilerToDevServer=(e,r,t,o,s)=>{const{projectCwd:d,devServer:l}=s,a=new WebpackDevServer({server:{type:l?.https?"https":"http",options:{...l?.https}},open:!1,compress:!0,port:t,hot:r,liveReload:!r,allowedHosts:"all",static:{directory:`${join(d,"/public")}`},headers:{"Access-Control-Allow-Origin":"*"},setupMiddlewares:e=>(l?.devBeforeMiddlewares&&e.unshift(...l.devBeforeMiddlewares),l?.devAfterMiddlewares&&e.push(...l.devAfterMiddlewares),e),client:{progress:!0,overlay:l?.clientOverlay,webSocketURL:"localIp"===l?.webSocketURL?{hostname:o||void 0}:{hostname:"0.0.0.0",...l?.webSocketURL}}},e);return new Promise(((e,r)=>{a.startCallback((t=>{if(t)return r(t);e(!0)}))}))};
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * Formats the spinner text by adding prefixes and styling using chalk.
3
3
  *
4
- * @param strArr - An array of strings to format.
4
+ * @param strArr - An array of strings to be formatted.
5
+ * @param prefixCode - The prefix to replace default prefix code.
5
6
  * @returns The formatted spinner text.
6
7
  */
7
- export declare const formatSpinnerText: (strArr?: string[]) => string;
8
+ export declare const formatSpinnerText: (strArr?: string[], prefixCode?: string) => string;
@@ -1 +1 @@
1
- import{chalk}from"@flatjs/common";export const formatSpinnerText=(n=[])=>{if(1===n.length)return` ${chalk(["blue"])("●")} ${n[0]} \n`;return n.map(((t,e)=>{let r="├";return 0===e?r="┌":e===n.length-1&&(r="└"),` ${chalk(["blue"])(r)} ${t} \n`})).join("")};
1
+ import{chalk}from"@flatjs/common";export const formatSpinnerText=(n=[],t)=>{if(1===n.length)return` ${chalk(["blue"])(t||"●")} ${n[0]} \n`;return n.map(((e,r)=>{let l="├";return 0===r?l="┌":r===n.length-1&&(l="└"),` ${chalk(["blue"])(t||l)} ${e} \n`})).join("")};
@@ -0,0 +1,2 @@
1
+ import { StatsCompilation } from 'webpack';
2
+ export declare const getStatsFileName: (stats: StatsCompilation) => string;
@@ -0,0 +1 @@
1
+ export const getStatsFileName=t=>t.hash+".json";
@@ -12,6 +12,7 @@ export * from './get-bundle-file-name.js';
12
12
  export * from './get-html-plugin-config.js';
13
13
  export * from './get-pacakge-dir.js';
14
14
  export * from './get-runtime-cdn-base.js';
15
+ export * from './get-stats-file-name.js';
15
16
  export * from './is-deep-equal.js';
16
17
  export * from './json-serializer.js';
17
18
  export * from './merge-babel-options.js';
@@ -1 +1 @@
1
- export*from"./allow-px2rem-for-module.js";export*from"./assert-group-entry-item.js";export*from"./assert-single-compiler.js";export*from"./check-runtime-env.js";export*from"./chunk-entry-map.js";export*from"./custom-listr-renderer.js";export*from"./delete-object-keys.js";export*from"./enable-bundle-hashname-for-module.js";export*from"./flat-entry-map.js";export*from"./format-spinner-text.js";export*from"./get-bundle-file-name.js";export*from"./get-html-plugin-config.js";export*from"./get-pacakge-dir.js";export*from"./get-runtime-cdn-base.js";export*from"./is-deep-equal.js";export*from"./json-serializer.js";export*from"./merge-babel-options.js";export*from"./normalize-check-entry-options.js";export*from"./normalize-entry-map.js";export*from"./normalize-group-name.js";export*from"./normalize-page-proxy.js";export*from"./normalize-resolve-alias.js";export*from"./normalize-template-inject-tokens.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-entry-group.js";export*from"./verify-group-entry-options.js";
1
+ export*from"./allow-px2rem-for-module.js";export*from"./assert-group-entry-item.js";export*from"./assert-single-compiler.js";export*from"./check-runtime-env.js";export*from"./chunk-entry-map.js";export*from"./custom-listr-renderer.js";export*from"./delete-object-keys.js";export*from"./enable-bundle-hashname-for-module.js";export*from"./flat-entry-map.js";export*from"./format-spinner-text.js";export*from"./get-bundle-file-name.js";export*from"./get-html-plugin-config.js";export*from"./get-pacakge-dir.js";export*from"./get-runtime-cdn-base.js";export*from"./get-stats-file-name.js";export*from"./is-deep-equal.js";export*from"./json-serializer.js";export*from"./merge-babel-options.js";export*from"./normalize-check-entry-options.js";export*from"./normalize-entry-map.js";export*from"./normalize-group-name.js";export*from"./normalize-page-proxy.js";export*from"./normalize-resolve-alias.js";export*from"./normalize-template-inject-tokens.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-entry-group.js";export*from"./verify-group-entry-options.js";
@@ -0,0 +1,9 @@
1
+ import { type AnalyzeServeOptions } from '../types/types-analyzer.js';
2
+ /**
3
+ * Prepares and analyzes webpack bundle stats.
4
+ *
5
+ * @param statsPaths - An array of paths to the webpack bundle stats files.
6
+ * @param options - Options for analyzing the webpack bundle stats.
7
+ * @returns A promise that resolves to a boolean indicating whether the analysis was successful.
8
+ */
9
+ export declare const prepareAnalyzer: (statsPaths: string[], options: AnalyzeServeOptions) => Promise<boolean>;
@@ -0,0 +1 @@
1
+ import _ from"lodash";import{createReadStream}from"node:fs";import{start}from"webpack-bundle-analyzer";import{cancel,confirm,intro,isCancel,multiselect,outro}from"@clack/prompts";import{parseChunked}from"@discoveryjs/json-ext";import{chalk,logger}from"@flatjs/common";import{moduleName}from"../constants.js";import{formatSpinnerText}from"../helpers/format-spinner-text.js";import{getStatsFileName}from"../helpers/get-stats-file-name.js";const readStatsFromFile=async e=>parseChunked(createReadStream(e,{encoding:"utf8"})),getStatsFilenames=async e=>{const t=[];for(const[r,a]of Object.entries(e)){const e=_.flattenDeep(Object.values(a.assetsByChunkName||{})).filter((e=>e.endsWith(".js"))),s=`Group ${chalk(["magenta"])(a.name||"")} \n${formatSpinnerText(e,`${chalk(["cyan"])("◆ ")}`)}`;t.push({value:r,label:s})}intro("Webpack bundle analyzer");const r=await multiselect({message:"Select entry groups to analyze",required:!0,options:t});if(isCancel(r))return cancel("The process has exited"),process.exit(0);const a=await confirm({message:"Are you sure to perform the analysis?"});return isCancel(a)?(cancel("The process has exited"),process.exit(0)):a?(outro("You're all set!"),r):getStatsFilenames(e)},startServer=async(e,t)=>{try{return await start(e,t),!0}catch(e){return logger.error(`Failed to start the analyzer serve ${e}`,moduleName),!1}};export const prepareAnalyzer=async(e,t)=>{const r={};for(const t of e){const e=await readStatsFromFile(t);r[getStatsFileName(e)]=e}const a=[],s=await getStatsFilenames(r);for(const e of s)a.push(startServer(r[e],t));return Promise.all(a).then((()=>!0))};
@@ -1,3 +1,4 @@
1
+ import { FlatCliOptions } from '../types/types-cli-options.js';
1
2
  import { type EvolveEntryMap } from '../types/types-entry-map.js';
2
3
  import { type FlatEvolveOptions } from '../types/types-options.js';
3
4
  import { type EvolveBuildResult } from './start-group-entry-build.js';
@@ -6,4 +7,4 @@ import { type EvolveBuildResult } from './start-group-entry-build.js';
6
7
  * @param entryMapItem The `entryMapItem` for one entry build task
7
8
  * @param evolveOptions FlatEvolveOptions
8
9
  */
9
- export declare const prepareBuild: (groupEntries: EvolveEntryMap, evolveOptions: FlatEvolveOptions) => Promise<EvolveBuildResult>;
10
+ export declare const prepareBuild: (groupEntries: EvolveEntryMap, evolveOptions: FlatEvolveOptions, cliOptions?: FlatCliOptions) => Promise<EvolveBuildResult>;
@@ -1 +1 @@
1
- import{ensureSlash,mergeOptions}from"@flatjs/common";import{ignoreEntryOptionKeys}from"../constants.js";import{EvolveBuildError}from"../errors/evolve-build-error.js";import{printCompilerError}from"../helpers/print-log.js";import{verifyGroupEntryOptions}from"../helpers/verify-group-entry-options.js";import{startGroupEntryBuild}from"./start-group-entry-build.js";export const prepareBuild=async(r,o)=>{const t=Object.values(r)[0];if(!verifyGroupEntryOptions(r,ignoreEntryOptionKeys,!0))throw new Error("The entry options in a group must be the same.");const e=o.multiHtmlCdn?.prod||[];if(!e.length)throw new Error(`No CDN config for env:"prod", groupName: ${t.groupName}`);const n=ensureSlash(e[Math.floor(Math.random()*e.length)],!0);try{const e=t.options?.useRelativeAssetPath,i=mergeOptions(o,{webpack:{publicPath:e?"auto":n}});return await startGroupEntryBuild(r,i)}catch(r){const o=printCompilerError(r);throw new EvolveBuildError("BUILD_ERROR",o)}};
1
+ import{ensureSlash,mergeOptions}from"@flatjs/common";import{ignoreEntryOptionKeys}from"../constants.js";import{EvolveBuildError}from"../errors/evolve-build-error.js";import{printCompilerError}from"../helpers/print-log.js";import{verifyGroupEntryOptions}from"../helpers/verify-group-entry-options.js";import{startGroupEntryBuild}from"./start-group-entry-build.js";export const prepareBuild=async(r,o,t)=>{const e=Object.values(r)[0];if(!verifyGroupEntryOptions(r,ignoreEntryOptionKeys,!0))throw new Error("The entry options in a group must be the same.");const n=o.multiHtmlCdn?.prod||[];if(!n.length)throw new Error(`No CDN config for env:"prod", groupName: ${e.groupName}`);const i=ensureSlash(n[Math.floor(Math.random()*n.length)],!0);try{const n=e.options?.useRelativeAssetPath,s=mergeOptions(o,{webpack:{publicPath:n?"auto":i}});return await startGroupEntryBuild(r,s,t)}catch(r){const o=printCompilerError(r);throw new EvolveBuildError("BUILD_ERROR",o)}};
@@ -0,0 +1,10 @@
1
+ import { type AnalyzeServeOptions } from '../types/types-analyzer.js';
2
+ import { FlatEvolveOptions } from '../types/types-options.js';
3
+ /**
4
+ * Starts the analysis process for the given evolve options and analyze options.
5
+ *
6
+ * @param evolveOptions - The options for the evolve process.
7
+ * @param analyzeOptions - The options for the analyze process (optional).
8
+ * @returns A promise that resolves when the analysis process is complete.
9
+ */
10
+ export declare const startAnalyzer: (evolveOptions: FlatEvolveOptions, analyzeOptions?: AnalyzeServeOptions) => Promise<boolean | undefined>;
@@ -0,0 +1 @@
1
+ import{join}from"node:path";import{fileWalkSync}from"@armit/file-utility";import{logger,mergeOptions}from"@flatjs/common";import{webpackStatsDir}from"../constants.js";import{prepareAnalyzer}from"./prepare-analyzer.js";export const startAnalyzer=async(t,r={})=>{const{projectCwd:o,webpack:e}=t,n="function"==typeof e?.outputDir?await e.outputDir():e?.outputDir||"public",a=join(o,webpackStatsDir),i=fileWalkSync(["*.json"],{cwd:a});if(!i.length)return void logger.warn(`No stats files found in ${o}. skipping analyze.`);const p={openBrowser:!0,reportTitle:"flatjs_evolve_analyzer",port:0,host:"127.0.0.1",bundleDir:join(o,n),analyzerUrl:t=>{const{listenHost:r,boundAddress:o}=t;return`http://${r}:${o.port}`}},s=mergeOptions(p,r);return await prepareAnalyzer(i,s)};
@@ -1 +1 @@
1
- import Listr from"listr";import{isAbsolute,join}from"node:path";import{getCommitIdOfBranch,getDiffFiles}from"@armit/git";import{arraysIntersect,chalk,logger,requireResolve}from"@flatjs/common";import{traverseGraph}from"@flatjs/graph";import{createGlobalCompiler}from"../compiler/create-global-compiler.js";import{ignoreEntryOptionKeys,moduleName}from"../constants.js";import{isCI}from"../helpers/check-runtime-env.js";import{CustomListrRenderer}from"../helpers/custom-listr-renderer.js";import{filterActivedEntriesByEntryInputs,filterActivedEntriesByModule}from"../helpers/filter-actived-entries.js";import{formatSpinnerText}from"../helpers/format-spinner-text.js";import{getGitRoot}from"../helpers/get-git-root.js";import{getMaxProcessTasks}from"../helpers/get-max-process-tasks.js";import{jsonSerializer}from"../helpers/json-serializer.js";import{normalizeEvolveEntryMap}from"../helpers/normalize-entry-map.js";import{resolveEntryMapInputFiles}from"../helpers/resolve-entry-map-input-files.js";import{splitToEntryGroup}from"../helpers/split-to-entry-group.js";import{loadEvolveConfig}from"../load-config/load-evolve-config.js";import{createThreadWorker}from"./create-thread-worker.js";import{envVerify}from"./env-verify.js";export async function getBuildEntryFiles(e,r,t,o,i){const n=[],s=[];for(const e of t)r.includes(e)?n.push(e):s.push(e);if(i&&logger.info("Use custom graph traverse filter",moduleName),s.length){const t=await traverseGraph({input:s,projectCwd:e,treeNodeFilter:i||(()=>!0),lessImportOptions:{projectCwd:e,aliases:o}});if(!t)return n;logger.debug(`DependencyGraph:\n${JSON.stringify(t,null,2)}`);for(const e of s){const o=t[e]||[];arraysIntersect(o,r)&&n.push(e)}}return n}export async function dynamicCheckBuildEntryMap(e,r,t,o,i){const n={projectCwd:e,command:"build",resolve:requireResolve},s=await loadEvolveConfig(n,e,o,i);if(s.ci?.fixedBuildModules&&s.ci?.fixedBuildModules.length){logger.info("Use `fixedBuildModules` configuration to build...");return{buildEntries:filterActivedEntriesByModule(s.entryMap,s.ci?.fixedBuildModules),newEvolveOptions:s}}if(logger.info("Dynamicly checking code changed modules ..."),!r){const e=s.ci?.basedBranch||"origin/master";r=await getCommitIdOfBranch(e),logger.info(`Resolving base branch "${e}" commit hash "${r}" ...`)}let a=r?await getDiffFiles(r,t):[];const l=getGitRoot(e);if(!l)throw new Error(`No .git root (${e}) found`);if(a=a.map((e=>isAbsolute(e)?e:join(l,e))),logger.debug(`Diff files: \n${JSON.stringify(a,null,2)}`),!a.length)return logger.warn("It seems that there are no code files changed."),{buildEntries:{},newEvolveOptions:s};const p=await resolveEntryMapInputFiles(e,s.entryMap),c=await getBuildEntryFiles(e,a,p,s.webpack?.resolve?.alias,s.ci?.graphTreeNodeFilter);logger.debug(`To build entry files: \n${JSON.stringify(c,null,2)}`);return{buildEntries:await filterActivedEntriesByEntryInputs(e,s.entryMap,c),newEvolveOptions:s}}export const startDynamicBuild=async(e,r,t,o={},i)=>{const{buildEntries:n,newEvolveOptions:s}=await dynamicCheckBuildEntryMap(e,r,t,o,i);await envVerify(e,s);const a=normalizeEvolveEntryMap(n,s.entryMap),l=splitToEntryGroup(a,s,ignoreEntryOptionKeys,!1);if(!l.length)return logger.warn("No build entries provided!"),[];await createGlobalCompiler(!1,s);const{threads:p={}}=s,c=getMaxProcessTasks(l.length,p?.maxThreads);logger.info(`Start dynamic build with (${chalk(["magenta"])(String(c))}) workers`);const m=createThreadWorker({...p,maxThreads:c}),f=new Listr([],{concurrent:c,exitOnError:!0,renderer:isCI()?void 0:CustomListrRenderer}),d=[];for(const r of l){const t=Object.values(r)?.[0]?.groupName||"",n=Object.keys(r);let s=`Group ${chalk(["magenta"])(t)} $STATUS \n${formatSpinnerText(n)}`;isCI()&&(s=`Group ${chalk(["magenta"])(t)} compiling... \n${formatSpinnerText(n)}`),f.add({title:s,task:async()=>{const r=await m.startBuildWorker({projectCwd:e,entryKeys:n,serializedEvolveOptions:jsonSerializer.stringify(o),configLoaderOptions:i});d.push(r)}})}if(f.tasks.length)try{await f.run()}catch(e){throw m.terminate(),e}return m.terminate(),d};
1
+ import Listr from"listr";import{isAbsolute,join}from"node:path";import{getCommitIdOfBranch,getDiffFiles}from"@armit/git";import{arraysIntersect,chalk,logger,requireResolve}from"@flatjs/common";import{traverseGraph}from"@flatjs/graph";import{createGlobalCompiler}from"../compiler/create-global-compiler.js";import{ignoreEntryOptionKeys,moduleName}from"../constants.js";import{isCI}from"../helpers/check-runtime-env.js";import{CustomListrRenderer}from"../helpers/custom-listr-renderer.js";import{filterActivedEntriesByEntryInputs,filterActivedEntriesByModule}from"../helpers/filter-actived-entries.js";import{formatSpinnerText}from"../helpers/format-spinner-text.js";import{getGitRoot}from"../helpers/get-git-root.js";import{getMaxProcessTasks}from"../helpers/get-max-process-tasks.js";import{jsonSerializer}from"../helpers/json-serializer.js";import{normalizeEvolveEntryMap}from"../helpers/normalize-entry-map.js";import{resolveEntryMapInputFiles}from"../helpers/resolve-entry-map-input-files.js";import{splitToEntryGroup}from"../helpers/split-to-entry-group.js";import{loadEvolveConfig}from"../load-config/load-evolve-config.js";import{createThreadWorker}from"./create-thread-worker.js";import{envVerify}from"./env-verify.js";export async function getBuildEntryFiles(e,r,t,o,i){const n=[],s=[];for(const e of t)r.includes(e)?n.push(e):s.push(e);if(i&&logger.info("Use custom graph traverse filter",moduleName),s.length){const t=await traverseGraph({input:s,projectCwd:e,treeNodeFilter:i||(()=>!0),lessImportOptions:{projectCwd:e,aliases:o}});if(!t)return n;logger.debug(`DependencyGraph:\n${JSON.stringify(t,null,2)}`);for(const e of s){const o=t[e]||[];arraysIntersect(o,r)&&n.push(e)}}return n}export async function dynamicCheckBuildEntryMap(e,r,t,o,i){const n={projectCwd:e,command:"build",resolve:requireResolve},s=await loadEvolveConfig(n,e,o,i);if(s.ci?.fixedBuildModules&&s.ci?.fixedBuildModules.length){logger.info("Use `fixedBuildModules` configuration to build...");return{buildEntries:filterActivedEntriesByModule(s.entryMap,s.ci?.fixedBuildModules),newEvolveOptions:s}}if(logger.info("Dynamicly checking code changed modules ..."),!r){const e=s.ci?.basedBranch||"origin/master";r=await getCommitIdOfBranch(e),logger.info(`Resolving base branch "${e}" commit hash "${r}" ...`)}let a=r?await getDiffFiles(r,t):[];const l=getGitRoot(e);if(!l)throw new Error(`No .git root (${e}) found`);if(a=a.map((e=>isAbsolute(e)?e:join(l,e))),logger.debug(`Diff files: \n${JSON.stringify(a,null,2)}`),!a.length)return logger.warn("It seems that there are no code files changed."),{buildEntries:{},newEvolveOptions:s};const p=await resolveEntryMapInputFiles(e,s.entryMap),m=await getBuildEntryFiles(e,a,p,s.webpack?.resolve?.alias,s.ci?.graphTreeNodeFilter);logger.debug(`To build entry files: \n${JSON.stringify(m,null,2)}`);return{buildEntries:await filterActivedEntriesByEntryInputs(e,s.entryMap,m),newEvolveOptions:s}}export const startDynamicBuild=async(e,r,t,o={},i)=>{const{buildEntries:n,newEvolveOptions:s}=await dynamicCheckBuildEntryMap(e,r,t,o,i);await envVerify(e,s);const a=normalizeEvolveEntryMap(n,s.entryMap),l=splitToEntryGroup(a,s,ignoreEntryOptionKeys,!1);if(!l.length)return logger.warn("No build entries provided!"),[];await createGlobalCompiler(!1,s);const{threads:p={}}=s,m=getMaxProcessTasks(l.length,p?.maxThreads);logger.info(`Start dynamic build with (${chalk(["magenta"])(String(m))}) workers`);const c=createThreadWorker({...p,maxThreads:m}),f=new Listr([],{concurrent:m,exitOnError:!0,renderer:isCI()?void 0:CustomListrRenderer}),d=[];for(const r of l){const t=Object.values(r)?.[0]?.groupName||"",n=Object.keys(r);let s=`Group ${chalk(["magenta"])(t)} $STATUS \n${formatSpinnerText(n)}`;isCI()&&(s=`Group ${chalk(["magenta"])(t)} compiling... \n${formatSpinnerText(n)}`),f.add({title:s,task:async()=>{const r=await c.startBuildWorker({projectCwd:e,entryKeys:n,serializedEvolveOptions:jsonSerializer.stringify(o),configLoaderOptions:i,groupName:t});d.push(r)}})}if(f.tasks.length)try{await f.run()}catch(e){throw c.terminate(),e}return c.terminate(),d};
@@ -1,5 +1,6 @@
1
1
  import { MessageChannel } from 'node:worker_threads';
2
2
  import { type ConfigLoaderOptions } from '../load-config/types.js';
3
+ import { FlatCliOptions } from '../types/types-cli-options.js';
3
4
  import { type EvolveBuildResult } from './start-group-entry-build.js';
4
5
  /**
5
6
  * FIXME: The main entry to start an evolve `build`, NOTE: avoid pass configuration with `function` here.
@@ -16,5 +17,7 @@ declare const _default: (options: {
16
17
  serializedEvolveOptions: string;
17
18
  configLoaderOptions?: ConfigLoaderOptions;
18
19
  messagePort?: MessageChannel["port1"];
20
+ groupName?: string;
21
+ cliOptions?: FlatCliOptions;
19
22
  }) => Promise<EvolveBuildResult>;
20
23
  export default _default;
@@ -1 +1 @@
1
- import{configLoggerStdWriteSteam,loggerSimpleStdWriteSteam,requireResolve}from"@flatjs/common";import{ignoreEntryOptionKeys}from"../constants.js";import{isCI}from"../helpers/check-runtime-env.js";import{filterActivedEntriesByModule}from"../helpers/filter-actived-entries.js";import{jsonSerializer}from"../helpers/json-serializer.js";import{normalizeEvolveEntryMap}from"../helpers/normalize-entry-map.js";import{splitToEntryGroup}from"../helpers/split-to-entry-group.js";import{loadEvolveConfig}from"../load-config/load-evolve-config.js";import{prepareBuild}from"./prepare-build.js";export default async e=>{isCI()||configLoggerStdWriteSteam();const{projectCwd:r,entryKeys:o,serializedEvolveOptions:t,configLoaderOptions:i,messagePort:s}=e,n={projectCwd:r,command:"build",resolve:requireResolve},p=jsonSerializer.parse(t)||{},l=await loadEvolveConfig(n,r,p,i),a=o.map((e=>new RegExp(`^${e}$`))),m=filterActivedEntriesByModule(l.entryMap,a),d=normalizeEvolveEntryMap(m,l.entryMap),f=splitToEntryGroup(d,l,ignoreEntryOptionKeys,!1);return prepareBuild(f[0],l).then((e=>(isCI()||loggerSimpleStdWriteSteam.postMessage(s),e)))};
1
+ import{configLoggerStdWriteSteam,loggerSimpleStdWriteSteam,requireResolve}from"@flatjs/common";import{ignoreEntryOptionKeys}from"../constants.js";import{isCI}from"../helpers/check-runtime-env.js";import{filterActivedEntriesByModule}from"../helpers/filter-actived-entries.js";import{jsonSerializer}from"../helpers/json-serializer.js";import{normalizeEvolveEntryMap}from"../helpers/normalize-entry-map.js";import{splitToEntryGroup}from"../helpers/split-to-entry-group.js";import{loadEvolveConfig}from"../load-config/load-evolve-config.js";import{prepareBuild}from"./prepare-build.js";export default async e=>{isCI()||configLoggerStdWriteSteam();const{projectCwd:r,entryKeys:o,serializedEvolveOptions:t,configLoaderOptions:i,messagePort:s,groupName:p="flatjs_evolve_group",cliOptions:n}=e,l={projectCwd:r,command:"build",resolve:requireResolve},a=jsonSerializer.parse(t)||{},m=await loadEvolveConfig(l,r,a,i),f=o.map((e=>new RegExp(`^${e}$`))),g=filterActivedEntriesByModule(m.entryMap,f),d=normalizeEvolveEntryMap(g,m.entryMap),v=splitToEntryGroup(d,m,ignoreEntryOptionKeys,!1)[0];for(const[,e]of Object.entries(v))e.groupName=p;return prepareBuild(v,m,n).then((e=>(isCI()||loggerSimpleStdWriteSteam.postMessage(s),e)))};
@@ -1,5 +1,6 @@
1
1
  import { type PartialDeep } from 'type-fest';
2
2
  import { type ConfigLoaderOptions } from '../load-config/types.js';
3
+ import { FlatCliOptions } from '../types/types-cli-options.js';
3
4
  import { type FlatEvolveOptions } from '../types/types-options.js';
4
5
  import { type EvolveBuildResult } from './start-group-entry-build.js';
5
- export declare const startBuild: (projectCwd: string, buildModules: string[], overrideEvolveOptions?: PartialDeep<FlatEvolveOptions>, configLoaderOptions?: ConfigLoaderOptions) => Promise<EvolveBuildResult[]>;
6
+ export declare const startBuild: (projectCwd: string, buildModules: string[], overrideEvolveOptions?: PartialDeep<FlatEvolveOptions>, configLoaderOptions?: ConfigLoaderOptions, cliOptions?: FlatCliOptions) => Promise<EvolveBuildResult[]>;
@@ -1 +1 @@
1
- import Listr from"listr";import{chalk,logger,requireResolve}from"@flatjs/common";import{createGlobalCompiler}from"../compiler/create-global-compiler.js";import{ignoreEntryOptionKeys}from"../constants.js";import{isCI}from"../helpers/check-runtime-env.js";import{CustomListrRenderer}from"../helpers/custom-listr-renderer.js";import{filterActivedEntriesByModule}from"../helpers/filter-actived-entries.js";import{formatSpinnerText}from"../helpers/format-spinner-text.js";import{getMaxProcessTasks}from"../helpers/get-max-process-tasks.js";import{jsonSerializer}from"../helpers/json-serializer.js";import{normalizeEvolveEntryMap}from"../helpers/normalize-entry-map.js";import{splitToEntryGroup}from"../helpers/split-to-entry-group.js";import{loadEvolveConfig}from"../load-config/load-evolve-config.js";import{createThreadWorker}from"./create-thread-worker.js";import{envVerify}from"./env-verify.js";export const startBuild=async(r,e,t={},o)=>{const i={projectCwd:r,command:"build",resolve:requireResolve},s=await loadEvolveConfig(i,r,t,o);await envVerify(r,s);const n=filterActivedEntriesByModule(s.entryMap,e),a=normalizeEvolveEntryMap(n,s.entryMap),l=splitToEntryGroup(a,s,ignoreEntryOptionKeys,!1);if(!l.length)return logger.warn("No build entries provided!"),[];await createGlobalCompiler(!1,s);const{threads:m={}}=s,p=getMaxProcessTasks(l.length,m?.maxThreads);logger.info(`Start standard build with (${chalk(["magenta"])(String(p))}) workers`);const c=createThreadWorker({...m,maxThreads:p}),f=new Listr([],{concurrent:p,exitOnError:!0,renderer:isCI()?void 0:CustomListrRenderer}),d=[];for(const e of l){const i=Object.values(e)?.[0]?.groupName||"",s=Object.keys(e);let n=`Group ${chalk(["magenta"])(i)} $STATUS \n${formatSpinnerText(s)}`;isCI()&&(n=`Group ${chalk(["magenta"])(i)} compiling... \n${formatSpinnerText(s)}`),f.add({title:n,task:async()=>{const e=await c.startBuildWorker({projectCwd:r,entryKeys:s,serializedEvolveOptions:jsonSerializer.stringify(t),configLoaderOptions:o});d.push(e)}})}if(f.tasks.length)try{await f.run()}catch(r){throw c.terminate(),r}return c.terminate(),d};
1
+ import Listr from"listr";import{chalk,logger,requireResolve}from"@flatjs/common";import{createGlobalCompiler}from"../compiler/create-global-compiler.js";import{ignoreEntryOptionKeys}from"../constants.js";import{isCI}from"../helpers/check-runtime-env.js";import{CustomListrRenderer}from"../helpers/custom-listr-renderer.js";import{filterActivedEntriesByModule}from"../helpers/filter-actived-entries.js";import{formatSpinnerText}from"../helpers/format-spinner-text.js";import{getMaxProcessTasks}from"../helpers/get-max-process-tasks.js";import{jsonSerializer}from"../helpers/json-serializer.js";import{normalizeEvolveEntryMap}from"../helpers/normalize-entry-map.js";import{splitToEntryGroup}from"../helpers/split-to-entry-group.js";import{loadEvolveConfig}from"../load-config/load-evolve-config.js";import{createThreadWorker}from"./create-thread-worker.js";import{envVerify}from"./env-verify.js";import{startAnalyzer}from"./start-analyzer.js";export const startBuild=async(r,e,t={},o,i={})=>{const{analyzer:s=!1}=i,a={projectCwd:r,command:"build",resolve:requireResolve},n=await loadEvolveConfig(a,r,t,o);await envVerify(r,n);const l=filterActivedEntriesByModule(n.entryMap,e),m=normalizeEvolveEntryMap(l,n.entryMap),p=splitToEntryGroup(m,n,ignoreEntryOptionKeys,!1);if(!p.length)return logger.warn("No build entries provided!"),[];await createGlobalCompiler(!1,n);const{threads:c={}}=n,f=getMaxProcessTasks(p.length,c?.maxThreads);logger.info(`Start standard build with (${chalk(["magenta"])(String(f))}) workers`);const d=createThreadWorker({...c,maxThreads:f}),g=new Listr([],{concurrent:f,exitOnError:!0,renderer:isCI()?void 0:CustomListrRenderer}),y=[];for(const e of p){const s=Object.values(e)?.[0]?.groupName||"",a=Object.keys(e);let n=`Group ${chalk(["magenta"])(s)} $STATUS \n${formatSpinnerText(a)}`;isCI()&&(n=`Group ${chalk(["magenta"])(s)} compiling... \n${formatSpinnerText(a)}`),g.add({title:n,task:async()=>{const e=await d.startBuildWorker({projectCwd:r,entryKeys:a,groupName:s,serializedEvolveOptions:jsonSerializer.stringify(t),configLoaderOptions:o,cliOptions:i});y.push(e)}})}if(g.tasks.length)try{await g.run()}catch(r){throw d.terminate(),r}return d.terminate(),s&&startAnalyzer(n),y};
@@ -1,3 +1,4 @@
1
+ import { FlatCliOptions } from '../types/types-cli-options.js';
1
2
  import { type EvolveEntryMap } from '../types/types-entry-map.js';
2
3
  import { type FlatEvolveOptions } from '../types/types-options.js';
3
4
  export type EvolveBuildResult = {
@@ -11,4 +12,4 @@ export type EvolveBuildResult = {
11
12
  * @param evolveOptions - The options for the build process.
12
13
  * @returns A promise that resolves to the build result.
13
14
  */
14
- export declare const startGroupEntryBuild: (groupBuildEntry: EvolveEntryMap, evolveOptions: FlatEvolveOptions) => Promise<EvolveBuildResult>;
15
+ export declare const startGroupEntryBuild: (groupBuildEntry: EvolveEntryMap, evolveOptions: FlatEvolveOptions, cliOptions?: FlatCliOptions) => Promise<EvolveBuildResult>;
@@ -1 +1 @@
1
- import webpack from"webpack";import{loadWebpackConfig}from"../create-webpack/load-webpack-config.js";import{assertSingleCompiler}from"../helpers/assert-single-compiler.js";import{normalizeEvolveEntryName}from"../helpers/normalize-entry-map.js";export const startGroupEntryBuild=async(r,e)=>{const n=await loadWebpackConfig("production",r,e),o=assertSingleCompiler(r,n,e,!1);return new Promise(((n,t)=>{webpack(o,((o,a)=>{if(o)return t(o);const i=a?.toJson();if(i?.errors?.length)return t(i.errors);if(e.rejectWarnings&&i?.warnings?.length)return t(i.warnings);const{projectVirtualPath:s}=e,p=Object.keys(r).map((r=>normalizeEvolveEntryName(r,s)));n({name:p,warningStats:i?.warnings})}))}))};
1
+ import webpack from"webpack";import{loadWebpackConfig}from"../create-webpack/load-webpack-config.js";import{assertSingleCompiler}from"../helpers/assert-single-compiler.js";import{normalizeEvolveEntryName}from"../helpers/normalize-entry-map.js";export const startGroupEntryBuild=async(r,e,n)=>{const o=await loadWebpackConfig("production",r,e,n),t=assertSingleCompiler(r,o,e,!1);return new Promise(((n,o)=>{webpack(t,((t,a)=>{if(t)return o(t);const i=a?.toJson();if(i?.errors?.length)return o(i.errors);if(e.rejectWarnings&&i?.warnings?.length)return o(i.warnings);const{projectVirtualPath:s}=e,p=Object.keys(r).map((r=>normalizeEvolveEntryName(r,s)));n({name:p,warningStats:i?.warnings})}))}))};
@@ -0,0 +1,28 @@
1
+ import { Readable } from 'node:stream';
2
+ import { StatsCompilation } from 'webpack';
3
+ /**
4
+ * A readable stream that serializes a StatsCompilation object into a string representation.
5
+ */
6
+ export declare class StatsSerializeStream extends Readable {
7
+ private indentLevel;
8
+ private stringifier;
9
+ /**
10
+ * Creates an instance of StatsSerializeStream.
11
+ * @param stats - The StatsCompilation object to be serialized.
12
+ */
13
+ constructor(stats: StatsCompilation);
14
+ /**
15
+ * Gets the indentation string based on the current indent level.
16
+ */
17
+ get indent(): string;
18
+ /**
19
+ * Implements the _read method required by the Readable stream.
20
+ */
21
+ _read(): void;
22
+ /**
23
+ * Generator function that recursively converts an object into a string representation.
24
+ * @param obj - The object to be serialized.
25
+ */
26
+ _stringify(obj: StatsCompilation): any;
27
+ }
28
+ export declare const writeStats: (stats: StatsCompilation, filepath: string) => Promise<unknown>;
@@ -0,0 +1 @@
1
+ import{createWriteStream}from"node:fs";import{Readable}from"node:stream";export class StatsSerializeStream extends Readable{constructor(e){super(),this.indentLevel=0,this.stringifier=this._stringify(e)}get indent(){return" ".repeat(this.indentLevel)}_read(){let e=!0;for(;e;){const{value:t,done:i}=this.stringifier.next();i?(this.push(null),e=!1):e=this.push(t)}}*_stringify(e){if("string"==typeof e||"number"==typeof e||"boolean"==typeof e||null===e)yield JSON.stringify(e);else if(Array.isArray(e)){yield"[",this.indentLevel++;let t=!0;for(let i of e)void 0===i&&(i=null),yield`${t?"":","}\n${this.indent}`,yield*this._stringify(i),t=!1;this.indentLevel--,yield e.length?`\n${this.indent}]`:"]"}else{yield"{",this.indentLevel++;let t=!0;const i=Object.entries(e);for(const[e,n]of i)void 0!==n&&(yield`${t?"":","}\n${this.indent}${JSON.stringify(e)}: `,yield*this._stringify(n),t=!1);this.indentLevel--,yield i.length?`\n${this.indent}}`:"}"}}}export const writeStats=(e,t)=>new Promise(((i,n)=>{new StatsSerializeStream(e).on("end",i).on("error",n).pipe(createWriteStream(t))}));
@@ -0,0 +1,12 @@
1
+ import { type WebpackPlugin } from '../../create-webpack/types.js';
2
+ import { FlatCliOptions } from '../../types/types-cli-options.js';
3
+ import { type FlatEvolveOptions } from '../../types/types-options.js';
4
+ /**
5
+ * Creates an array of Webpack plugins for generating stats files.
6
+ *
7
+ * @param serveMode - A boolean indicating whether the application is running in serve mode.
8
+ * @param evolveOptions - The options for the evolve package.
9
+ * @param cliOptions - The options passed through the command-line interface.
10
+ * @returns An array of Webpack plugins.
11
+ */
12
+ export declare const createStatsWebpackPlugin: (serveMode: boolean, evolveOptions: FlatEvolveOptions, cliOptions?: FlatCliOptions) => WebpackPlugin[];
@@ -0,0 +1 @@
1
+ import{StatsWebpackPlugin}from"./stats-webpack-plugin.js";export const createStatsWebpackPlugin=(t,e,a={})=>{const{analyzer:r=!1}=a;return t||!r?[]:[new StatsWebpackPlugin({verbose:!0,projectCwd:e.projectCwd})]};
@@ -0,0 +1,25 @@
1
+ import { Compiler, Stats, StatsCompilation } from 'webpack';
2
+ export interface Options {
3
+ /**
4
+ * The project root.
5
+ */
6
+ projectCwd?: string;
7
+ /**
8
+ * Write Logs to Console
9
+ * (Always enabled when dry is true)
10
+ *
11
+ * default: false
12
+ */
13
+ verbose?: boolean;
14
+ }
15
+ export declare class StatsWebpackPlugin {
16
+ private readonly verbose;
17
+ private outputPath;
18
+ private projectCwd;
19
+ private statsFilename;
20
+ constructor(options?: Options);
21
+ apply(compiler: Compiler): void;
22
+ handleBeforeClean(): void;
23
+ handleDone(stats: Stats, callback: (error?: Error) => void): Promise<void>;
24
+ generateStatsFile(stats: StatsCompilation): Promise<void>;
25
+ }
@@ -0,0 +1 @@
1
+ import{rmSync}from"node:fs";import{mkdir}from"node:fs/promises";import{dirname,join,resolve}from"node:path";import{logger}from"@flatjs/common";import{webpackStatsDir}from"../../constants.js";import{getStatsFileName}from"../../helpers/get-stats-file-name.js";import{writeStats}from"./helper-write-stats.js";export class StatsWebpackPlugin{constructor(t={}){this.verbose=!0===t.verbose||!1,this.projectCwd=t.projectCwd||process.cwd(),this.outputPath=join(this.projectCwd,webpackStatsDir)}apply(t){this.handleBeforeClean();t.hooks.done.tapAsync("stats-webpack-plugin",((t,e)=>{this.statsFilename=getStatsFileName(t),this.handleDone(t,e)}))}handleBeforeClean(){rmSync(this.outputPath,{force:!0,recursive:!0})}async handleDone(t,e){try{await this.generateStatsFile(t.toJson()),e()}catch(t){e(t)}}async generateStatsFile(t){const e=resolve(this.outputPath,this.statsFilename);await mkdir(dirname(e),{recursive:!0});try{await writeStats(t,e),this.verbose&&logger.debug(`stats-webpack-plugin: saved stats file to ${e}`)}catch(t){this.verbose&&logger.error(`stats-webpack-plugin: error saving stats file to ${e}: ${t}`)}}}
@@ -1,3 +1,4 @@
1
+ export * from './types-analyzer.js';
1
2
  export * from './types-dev-server.js';
2
3
  export * from './types-entry-map.js';
3
4
  export * from './types-federation.js';
@@ -1 +1 @@
1
- export*from"./types-dev-server.js";export*from"./types-entry-map.js";export*from"./types-federation.js";export*from"./types-global-compiler-options.js";export*from"./types-loader-options.js";export*from"./types-modular-import.js";export*from"./types-multi-html.js";export*from"./types-options.js";export*from"./types-webpack.js";
1
+ export*from"./types-analyzer.js";export*from"./types-dev-server.js";export*from"./types-entry-map.js";export*from"./types-federation.js";export*from"./types-global-compiler-options.js";export*from"./types-loader-options.js";export*from"./types-modular-import.js";export*from"./types-multi-html.js";export*from"./types-options.js";export*from"./types-webpack.js";
@@ -0,0 +1,70 @@
1
+ import { type StatsCompilation } from 'webpack';
2
+ type ExcludeAssetsPatternFn = (assetName: string) => boolean;
3
+ type ExcludeAssetsPattern = string | RegExp | ExcludeAssetsPatternFn;
4
+ interface AddressInfo {
5
+ address: string;
6
+ family: string;
7
+ port: number;
8
+ }
9
+ /**
10
+ * Options for serving and analyzing a project.
11
+ */
12
+ export type AnalyzeServeOptions = {
13
+ /**
14
+ * The port number to listen on.
15
+ * @default 0 (auto-assign a port)
16
+ */
17
+ port?: number;
18
+ /**
19
+ * The host address to bind to.
20
+ * @default '127.0.0.1'
21
+ */
22
+ host?: string;
23
+ /**
24
+ * Whether to automatically open the browser.
25
+ * @default true
26
+ */
27
+ openBrowser?: boolean;
28
+ /**
29
+ * The directory where the bundled files are located.
30
+ */
31
+ bundleDir?: string;
32
+ /**
33
+ * Module sizes to show in the report by default.
34
+ * Should be one of "parsed", "stat", or "gzip".
35
+ * @default 'parsed'
36
+ */
37
+ defaultSizes?: 'parsed' | 'stat' | 'gzip' | undefined;
38
+ /**
39
+ * Patterns that will be used to match against asset names to exclude them from the report.
40
+ * If the pattern is a string, it will be converted to a regular expression via `new RegExp(str)`.
41
+ * If the pattern is a function, it should have the following signature: `(assetName: string) => boolean`
42
+ * and should return true to exclude the matching asset.
43
+ * If multiple patterns are provided, an asset should match at least one of them to be excluded.
44
+ * @default null
45
+ */
46
+ excludeAssets?: null | ExcludeAssetsPattern | ExcludeAssetsPattern[] | undefined;
47
+ /**
48
+ * Content of the HTML title element; or a function of the form `() => string` that provides the content.
49
+ * @default A function that returns the pretty printed current date and time.
50
+ */
51
+ reportTitle?: string | (() => string) | undefined;
52
+ /**
53
+ * The URL printed to the console with server mode.
54
+ * @default 'http://${listenHost}:${boundAddress.port}'
55
+ */
56
+ analyzerUrl?: (options: {
57
+ listenPort: string;
58
+ listenHost: string;
59
+ boundAddress: AddressInfo;
60
+ }) => string;
61
+ };
62
+ export type BundleStatsMapping = {
63
+ [statsFilename: string]: StatsCompilation;
64
+ };
65
+ export type PromptsOptionValue = {
66
+ value: string;
67
+ label: string;
68
+ hint?: string;
69
+ };
70
+ export {};
@@ -0,0 +1 @@
1
+ export{};
@@ -0,0 +1,12 @@
1
+ export interface FlatCliOptions {
2
+ /**
3
+ * Visualize size of webpack output files with an interactive zoomable treemap.
4
+ *
5
+ * With build mode `production` only
6
+ *
7
+ * This Configuration take effect only during the build phase
8
+ *
9
+ * @default false
10
+ */
11
+ analyzer?: boolean;
12
+ }
@@ -0,0 +1 @@
1
+ export{};
@@ -1,5 +1,5 @@
1
1
  import { type RequestHandler } from 'express';
2
- import { type ClientConfiguration, type WebSocketURL } from 'webpack-dev-server';
2
+ import { type ClientConfiguration, Middleware, type WebSocketURL } from 'webpack-dev-server';
3
3
  import { type FlatMockOptions, type SecureContextHttps } from '@flatjs/mock';
4
4
  import { type EvolveEntryMapContent } from './types-entry-map.js';
5
5
  export interface WebpackWatchOptions {
@@ -36,6 +36,18 @@ export type FlatEvolveDevServerOptions = {
36
36
  * This configuration will be merged into `webpack-dev-server`
37
37
  */
38
38
  watchOptions?: WebpackWatchOptions;
39
+ /**
40
+ * Provides the ability to execute a custom function and apply custom middleware(s).
41
+ * https://webpack.js.org/configuration/dev-server/#devserversetupmiddlewares
42
+ * @default []
43
+ */
44
+ devBeforeMiddlewares?: Middleware[];
45
+ /**
46
+ * Provides the ability to execute a custom function and apply custom middleware(s).
47
+ * https://webpack.js.org/configuration/dev-server/#devserversetupmiddlewares
48
+ * @default []
49
+ */
50
+ devAfterMiddlewares?: Middleware[];
39
51
  /**
40
52
  * Allow us costomized global serve data injected into `window.GLOBAL = {...globalData}`
41
53
  */
@@ -105,10 +105,6 @@ export interface FlatEvolveOptions {
105
105
  entryMap: {
106
106
  [K in keyof EvolveEntryMap]: Omit<EvolveEntryMap[K], 'groupingSource'>;
107
107
  };
108
- /**
109
- * Visualize size of webpack output files with an interactive zoomable treemap.
110
- */
111
- analyzer?: Record<string, unknown>;
112
108
  /**
113
109
  * For `production` mode, the value indicates if we interrupt compilation process while received "warnings" while evolve `build`
114
110
  * @default false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flatjs/evolve",
3
- "version": "2.1.0-next.26",
3
+ "version": "2.1.0-next.28",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -19,6 +19,7 @@
19
19
  ],
20
20
  "scripts": {
21
21
  "serve": "yarn node --import=@hyperse/ts-node-paths/register ./tests/dev-server/dev-server.ts",
22
+ "analyzer": "yarn node --import=@hyperse/ts-node-paths/register ./tests/build-analyzer/start-analyzer.ts",
22
23
  "build": "rimraf dist && tsc -p ./tsconfig.build.json && npm run minify",
23
24
  "?build-release": "When https://github.com/atlassian/changesets/issues/432 has a solution we can remove this trick",
24
25
  "build-release": "yarn build && rimraf ./_release && yarn pack && mkdir ./_release && tar zxvf ./package.tgz --directory ./_release && rm ./package.tgz",
@@ -40,6 +41,8 @@
40
41
  "@armit/git": "^0.2.2",
41
42
  "@armit/package": "^0.2.3",
42
43
  "@babel/core": "^7.24.7",
44
+ "@clack/prompts": "^0.7.0",
45
+ "@discoveryjs/json-ext": "0.6.0",
43
46
  "@flatjs/babel-plugin-import": "2.1.0-next.9",
44
47
  "@flatjs/common": "2.1.0-next.8",
45
48
  "@flatjs/evolve-preset-babel": "2.1.0-next.9",