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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/dist/constants.js +36 -1
  2. package/dist/create-webpack/create-externals.js +6 -1
  3. package/dist/create-webpack/create-optimization.js +43 -1
  4. package/dist/create-webpack/create-output.js +35 -1
  5. package/dist/create-webpack/create-performance.js +7 -1
  6. package/dist/create-webpack/create-plugins.js +78 -1
  7. package/dist/create-webpack/create-resolve.js +37 -1
  8. package/dist/create-webpack/create-rule-sets.js +20 -1
  9. package/dist/create-webpack/load-webpack-config.js +57 -1
  10. package/dist/create-webpack/resolve-public-path.js +15 -1
  11. package/dist/create-webpack/rule-sets/constants.js +3 -1
  12. package/dist/create-webpack/rule-sets/rule-assets.js +52 -1
  13. package/dist/create-webpack/rule-sets/rule-css.js +111 -1
  14. package/dist/create-webpack/rule-sets/rule-less.js +44 -1
  15. package/dist/create-webpack/rule-sets/rule-scripts.js +34 -1
  16. package/dist/create-webpack/rule-sets/rule-svg-icon.js +25 -1
  17. package/dist/create-webpack/rule-sets/rule-utils.js +10 -1
  18. package/dist/create-webpack/types.js +1 -1
  19. package/dist/default-options.js +83 -1
  20. package/dist/define-config/define-config.js +4 -1
  21. package/dist/define-config/index.js +1 -1
  22. package/dist/dev-server/add-compiler-to-dev-server.js +58 -1
  23. package/dist/dev-server/create-app-page-route.js +13 -1
  24. package/dist/dev-server/create-dev-server-compiler-task.js +55 -1
  25. package/dist/dev-server/create-dev-server-entries.js +25 -1
  26. package/dist/dev-server/create-dev-server.js +24 -1
  27. package/dist/dev-server/index.js +6 -1
  28. package/dist/dev-server/middlewares/create-page-middleware.js +33 -1
  29. package/dist/dev-server/middlewares/create-public-assets-middleware.js +25 -1
  30. package/dist/dev-server/middlewares/get-all-sorted-modules.js +24 -1
  31. package/dist/dev-server/middlewares/get-bundle-asset.js +7 -1
  32. package/dist/dev-server/middlewares/get-dev-server-host-uri.js +5 -1
  33. package/dist/dev-server/middlewares/get-hmr-runtime-chunks.js +14 -1
  34. package/dist/dev-server/middlewares/get-normalized-entry-name.js +14 -1
  35. package/dist/dev-server/middlewares/get-page-main-html.js +49 -1
  36. package/dist/dev-server/middlewares/get-page-module-html.js +123 -1
  37. package/dist/dev-server/middlewares/get-project-virtual-path.js +3 -1
  38. package/dist/dev-server/middlewares/get-runtime-manifest.js +25 -1
  39. package/dist/dev-server/middlewares/index.js +2 -1
  40. package/dist/dev-server/middlewares/types.js +1 -1
  41. package/dist/errors/evolve-build-error.js +10 -1
  42. package/dist/helpers/allow-px2rem-for-module.js +6 -1
  43. package/dist/helpers/assert-group-entry-item.js +19 -1
  44. package/dist/helpers/assert-single-compiler.js +45 -1
  45. package/dist/helpers/chunk-entry-map.js +21 -1
  46. package/dist/helpers/delete-object-keys.js +20 -1
  47. package/dist/helpers/enable-bundle-hashname-for-module.js +6 -1
  48. package/dist/helpers/filter-actived-entries.js +42 -1
  49. package/dist/helpers/flat-entry-map.js +11 -1
  50. package/dist/helpers/get-bundle-file-name.js +23 -1
  51. package/dist/helpers/get-git-root.js +4 -1
  52. package/dist/helpers/get-html-plugin-config.js +47 -1
  53. package/dist/helpers/get-max-process-tasks.js +7 -1
  54. package/dist/helpers/get-pacakge-dir.js +13 -1
  55. package/dist/helpers/get-runtime-cdn-base.js +21 -1
  56. package/dist/helpers/index.js +27 -1
  57. package/dist/helpers/is-deep-equal.js +67 -1
  58. package/dist/helpers/json-serializer.js +52 -1
  59. package/dist/helpers/merge-babel-options.js +45 -1
  60. package/dist/helpers/normalize-check-entry-options.js +28 -1
  61. package/dist/helpers/normalize-entry-map.js +59 -1
  62. package/dist/helpers/normalize-group-name.js +16 -1
  63. package/dist/helpers/normalize-page-proxy.js +9 -1
  64. package/dist/helpers/normalize-resolve-alias.js +7 -1
  65. package/dist/helpers/normalize-template-inject-tokens.js +22 -1
  66. package/dist/helpers/open-page.js +15 -1
  67. package/dist/helpers/print-log.js +49 -1
  68. package/dist/helpers/refresh-evolve-mock-options.js +34 -1
  69. package/dist/helpers/resolve-entry-map-input-files.js +20 -1
  70. package/dist/helpers/script-injects.js +39 -1
  71. package/dist/helpers/should-enable-react-fast-refresh.js +14 -1
  72. package/dist/helpers/split-to-entry-group.js +139 -1
  73. package/dist/helpers/verify-group-entry-options.js +21 -1
  74. package/dist/index.js +5 -1
  75. package/dist/load-config/index.js +1 -1
  76. package/dist/load-config/load-evolve-config.js +41 -1
  77. package/dist/load-config/types.js +1 -1
  78. package/dist/main/create-thread-worker.js +51 -1
  79. package/dist/main/env-verify.js +21 -1
  80. package/dist/main/get-worker-path.js +5 -1
  81. package/dist/main/index.js +4 -1
  82. package/dist/main/prepare-build.js +39 -1
  83. package/dist/main/prepare-serve.js +69 -1
  84. package/dist/main/prepare-static.js +30 -1
  85. package/dist/main/start-build-dynamic.js +171 -1
  86. package/dist/main/start-build-worker.js +44 -1
  87. package/dist/main/start-build.js +69 -1
  88. package/dist/main/start-group-entry-build.js +32 -1
  89. package/dist/main/start-serve.js +34 -1
  90. package/dist/main/start-static.js +19 -1
  91. package/dist/minimizer/create-minimizers.js +25 -1
  92. package/dist/minimizer/default-options.js +14 -1
  93. package/dist/minimizer/image-minimizer.js +65 -1
  94. package/dist/minimizer/index.js +1 -1
  95. package/dist/minimizer/terser-minimizer.js +15 -3
  96. package/dist/minimizer/types.js +1 -1
  97. package/dist/plugins/circular-dependency/circular-dependency-plugin.js +119 -1
  98. package/dist/plugins/circular-dependency/index.js +15 -1
  99. package/dist/plugins/clean-webpack/clean-webpack-plugin.js +173 -1
  100. package/dist/plugins/clean-webpack/index.js +22 -1
  101. package/dist/plugins/define-variable/define-variable-plugin.js +28 -1
  102. package/dist/plugins/define-variable/index.js +1 -1
  103. package/dist/plugins/html-inject-scripts/plugin-html-inject-script.js +27 -1
  104. package/dist/plugins/module-federation/external-template-remotes.js +92 -1
  105. package/dist/plugins/module-federation/index.js +1 -1
  106. package/dist/plugins/module-federation/module-federation.js +100 -1
  107. package/dist/plugins/multi-html/index.js +16 -1
  108. package/dist/plugins/multi-html/multi-html-cdn-plugin.js +83 -1
  109. package/dist/plugins/multi-html/multi-html-plugin.js +65 -1
  110. package/dist/plugins/ts-checker/index.js +1 -1
  111. package/dist/plugins/ts-checker/ts-checker-plugin.js +24 -1
  112. package/dist/types/index.js +8 -1
  113. package/dist/types/types-ci.js +1 -1
  114. package/dist/types/types-dev-server.js +1 -1
  115. package/dist/types/types-entry-map.js +1 -1
  116. package/dist/types/types-federation.js +1 -1
  117. package/dist/types/types-loader-options.d.ts +30 -3
  118. package/dist/types/types-loader-options.js +1 -1
  119. package/dist/types/types-modular-import.js +1 -1
  120. package/dist/types/types-multi-html.js +1 -1
  121. package/dist/types/types-options.js +1 -1
  122. package/dist/types/types-plugin-options.js +1 -1
  123. package/dist/types/types-threads-options.js +1 -1
  124. package/dist/types/types-webpack.js +1 -1
  125. package/package.json +2 -2
package/dist/constants.js CHANGED
@@ -1 +1,36 @@
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 maxEntryGroupSize=10;
1
+ export const moduleName = `@flatjs/evolve`;
2
+ /**
3
+ * the configuration file of `flat-evolve`
4
+ * flatjs-evolve.config.ts,.mjs,.mts
5
+ */
6
+ export const configFileName = `flatjs-evolve`;
7
+ /**
8
+ * `viewport.js`, Used to support the mobile `rem` adaptive solution.
9
+ * The viewport code is dynamically inserted to `html` file via `html-plugin`
10
+ */
11
+ 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);`;
12
+ /**
13
+ * https://polyfill.io
14
+ */
15
+ export const polyfill = [
16
+ `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`,
17
+ ];
18
+ /**
19
+ * Applies the react-refresh Babel plugin on non-production modes only
20
+ * Ensure `react-refresh/runtime` is hoisted and shared
21
+ * https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/docs/TROUBLESHOOTING.md#externalising-react
22
+ */
23
+ export const devReactFastRefresh = {
24
+ runtime: `reactRefreshRuntime`,
25
+ reactRefreshSetup: `reactRefreshSetup`,
26
+ };
27
+ /**
28
+ * Array of keys to ignore in the verifyGroupEntryOptions step
29
+ */
30
+ export const ignoreEntryOptionKeys = [
31
+ 'title',
32
+ ];
33
+ /**
34
+ * The maximum size of an entry group.
35
+ */
36
+ export const maxEntryGroupSize = 10;
@@ -1 +1,6 @@
1
- import{mergeOptions}from"@flatjs/common";export const createExternals=(t={},e)=>{const o=e[1],r=o.options?.externals||{};return mergeOptions(t,r)};
1
+ import { mergeOptions } from '@flatjs/common';
2
+ export const createExternals = (externals = {}, entryItem) => {
3
+ const entryItemContent = entryItem[1];
4
+ const entryItemExternals = entryItemContent.options?.externals || {};
5
+ return mergeOptions(externals, entryItemExternals);
6
+ };
@@ -1 +1,43 @@
1
- import{join}from"node:path";import{devReactFastRefresh}from"../constants.js";import{shouldEnableReactFastRefresh}from"../helpers/should-enable-react-fast-refresh.js";import{createMinimizers}from"../minimizer/index.js";export const createOptimization=(e,i,n)=>({nodeEnv:e?"development":"production",chunkIds:"named",moduleIds:"named",runtimeChunk:!!shouldEnableReactFastRefresh(e,n,i)&&{name:e=>join(e.name,devReactFastRefresh.runtime)},minimize:!1!==i.webpack?.minimizer&&!e,minimizer:createMinimizers(e,i.webpack),splitChunks:{name:!1,chunks:"all",minSize:25e5,cacheGroups:{default:!1,defaultVendors:!1}}});
1
+ import { join } from 'node:path';
2
+ import { devReactFastRefresh } from '../constants.js';
3
+ import { shouldEnableReactFastRefresh } from '../helpers/should-enable-react-fast-refresh.js';
4
+ import { createMinimizers } from '../minimizer/index.js';
5
+ export const createOptimization = (serveMode, evolveOptions, entryMapItem) => {
6
+ // Indicates current we use `hot` mode for `webpack-dev-server` hot reload true.
7
+ const enabledHmr = shouldEnableReactFastRefresh(serveMode, entryMapItem, evolveOptions);
8
+ const webpackOptimization = {
9
+ nodeEnv: serveMode ? 'development' : 'production',
10
+ chunkIds: 'named',
11
+ moduleIds: 'named',
12
+ // Ensure `react-refresh/runtime` is hoisted and shared, Could be replicated via a vendors chunk
13
+ // NOTE: This is only for `HMR` mode, if we have no `HMR` mode, we should not use this! it always be `false`
14
+ runtimeChunk: enabledHmr
15
+ ? {
16
+ name: (entrypoint) => {
17
+ return join(entrypoint.name, devReactFastRefresh.runtime);
18
+ },
19
+ }
20
+ : false,
21
+ // This is true in production mode. Tell webpack to minimize the bundle using the TerserPlugin
22
+ minimize: evolveOptions.webpack?.minimizer !== false && !serveMode,
23
+ // Note: the `minimizer` will executed must be wait until `minimize` is `true`
24
+ minimizer: createMinimizers(serveMode, evolveOptions.webpack),
25
+ // Disabled WARNING in webpack while chunk exceed the recommended size limit for `serve`
26
+ splitChunks: {
27
+ // It is recommended to set splitChunks.name to false for production builds
28
+ // so that it doesn't change names unnecessarily.
29
+ name: false,
30
+ // include all types of chunks
31
+ // chunks: 'async',
32
+ chunks: 'all',
33
+ // 2.3841858(MB)
34
+ minSize: 2500000,
35
+ // disable vendors~loadsh.js...
36
+ cacheGroups: {
37
+ default: false,
38
+ defaultVendors: false,
39
+ },
40
+ },
41
+ };
42
+ return webpackOptimization;
43
+ };
@@ -1 +1,35 @@
1
- import{join}from"node:path";import{getBundleFileName}from"../helpers/get-bundle-file-name.js";import{resolvePublicPath}from"./resolve-public-path.js";export const createOutput=async(e,t,o)=>{const{projectCwd:n,webpack:a}=t,i=o[1],p=resolvePublicPath(t),u="function"==typeof a?.outputDir?await a.outputDir():a?.outputDir||"public";return{devtoolModuleFilenameTemplate:({namespace:e,resourcePath:t})=>`webpack:///${join(e,t)}`,environment:{},pathinfo:!1,path:join(n,u),publicPath:p,filename:`[name]/${getBundleFileName("js",e,a?.enableBundleHashName)}`,chunkFilename:"[id].[contenthash].js",...i.options?.output}};
1
+ import { join } from 'node:path';
2
+ import { getBundleFileName } from '../helpers/get-bundle-file-name.js';
3
+ import { resolvePublicPath } from './resolve-public-path.js';
4
+ export const createOutput = async (serveMode, evolveOptions, entryItem) => {
5
+ const { projectCwd, webpack } = evolveOptions;
6
+ const entryItemOption = entryItem[1];
7
+ // If we have customized publicPath, should be converted to `https://cdn.example.com/assets/`, `/assets/`
8
+ const publicPath = resolvePublicPath(evolveOptions);
9
+ // Allow us dynamic return `outputDir`, e.g dev_xxxx, we can create built directory via `branchName`
10
+ const outputDir = typeof webpack?.outputDir === 'function'
11
+ ? await webpack.outputDir()
12
+ : webpack?.outputDir || 'public';
13
+ const webpackOutput = {
14
+ // Formatting devtool sourcemap template file.
15
+ devtoolModuleFilenameTemplate: ({ namespace, resourcePath }) => {
16
+ return `webpack:///${join(namespace, resourcePath)}`;
17
+ },
18
+ // Replace output.ecmaVersion with output.environment and more detailed
19
+ environment: {},
20
+ // Include comments with information about the modules, Disable it can improved performance.
21
+ pathinfo: false,
22
+ // The output directory as an absolute path.
23
+ path: join(projectCwd, outputDir),
24
+ // The publicPath specifies the public URL address of the output files when referenced in a browser.
25
+ publicPath,
26
+ // Specifies the name of each output file on disk. You must not specify an absolute path here!
27
+ filename: `[name]/${getBundleFileName('js', serveMode, webpack?.enableBundleHashName)}`,
28
+ // hotUpdateMainFilename: '[runtime].[fullhash].hot-update.json',
29
+ // The filename of non-entry chunks as relative path inside the output.path directory.
30
+ chunkFilename: `[id].[contenthash].js`,
31
+ // Extends / overrides the default output configuration
32
+ ...entryItemOption.options?.output,
33
+ };
34
+ return webpackOutput;
35
+ };
@@ -1 +1,7 @@
1
- export const createPerformance=(n,e={})=>{const r={hints:!n&&"warning"};return Object.assign(r,e)};
1
+ export const createPerformance = (serveMode, performanceOptions = {}) => {
2
+ const basePerformance = {
3
+ // Disable entry size exceeds recommands warning for `serve` mode
4
+ hints: serveMode ? false : 'warning',
5
+ };
6
+ return Object.assign(basePerformance, performanceOptions);
7
+ };
@@ -1 +1,78 @@
1
- import{logger}from"@flatjs/common";import ReactRefreshWebpackPlugin from"@pmmmwh/react-refresh-webpack-plugin";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{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{createTsCheckerPlugins}from"../plugins/ts-checker/index.js";export const createPlugins=async(e,a,n)=>{const r=a[0],[l,i]=r,s=enableBundleHashNameForModule(n,i?.options),t=[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),...createTsCheckerPlugins(e,a,n)];n.analyzer&&t.push(new BundleAnalyzerPlugin({analyzerPort:"auto",analyzerMode:"server",...n.analyzer}));const o=shouldEnableReactFastRefresh(e,r,n);o&&t.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":"${l}"\``));const c=n.webpack?.plugins||[];return t.concat(c)};
1
+ import { logger } from '@flatjs/common';
2
+ import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin';
3
+ import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin';
4
+ import MiniCssExtractPlugin from 'mini-css-extract-plugin';
5
+ import webpack from 'webpack';
6
+ import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
7
+ import { enableBundleHashNameForModule } from '../helpers/enable-bundle-hashname-for-module.js';
8
+ import { getBundleFileName } from '../helpers/get-bundle-file-name.js';
9
+ import { shouldEnableReactFastRefresh } from '../helpers/should-enable-react-fast-refresh.js';
10
+ import { createCircularDependencyPlugin } from '../plugins/circular-dependency/index.js';
11
+ import { createCleanWebpackPlugin } from '../plugins/clean-webpack/index.js';
12
+ import { createBuiltinDefineVariables } from '../plugins/define-variable/index.js';
13
+ import { createModuleFederationPlugin } from '../plugins/module-federation/index.js';
14
+ import { createHtmlPlugins } from '../plugins/multi-html/index.js';
15
+ import { createTsCheckerPlugins } from '../plugins/ts-checker/index.js';
16
+ export const createPlugins = async (serveMode, entryMapItemList, evolveOptions) => {
17
+ const firstEntryMapItem = entryMapItemList[0];
18
+ const [entryName, entryItemOption] = firstEntryMapItem;
19
+ const bundleHashNameEnabled = enableBundleHashNameForModule(evolveOptions, entryItemOption?.options);
20
+ const builtInPlugins = [
21
+ // Because TS will may generate .js and .d.ts files, you should ignore these files,
22
+ // otherwise watchers may go into an infinite watch loop.
23
+ new webpack.WatchIgnorePlugin({
24
+ paths: [/\.d\.[cm]ts$/],
25
+ }),
26
+ // Case Sensitive Paths for OSX
27
+ new CaseSensitivePathsPlugin(),
28
+ // Detect modules with circular dependencies when bundling with webpack for `development` mode.
29
+ ...createCircularDependencyPlugin(serveMode, evolveOptions),
30
+ // For css minify extractor, Note `"sideEffects": false,` of `package.json` will not emits a file (writes a file to the filesystem)
31
+ new MiniCssExtractPlugin({
32
+ // Options similar to the same options in webpackOptions.output
33
+ // both options are optional
34
+ filename: `[name]/${getBundleFileName('css', serveMode, bundleHashNameEnabled)}`,
35
+ // the chunkFilename option can be a function for webpack@5
36
+ chunkFilename: '[id].[contenthash].css',
37
+ }),
38
+ // create builtin DefinePlugin
39
+ ...(await createBuiltinDefineVariables(serveMode, evolveOptions)),
40
+ // clean webpack plugin
41
+ ...createCleanWebpackPlugin(serveMode, entryMapItemList, evolveOptions),
42
+ // Put ModuleFederationPlugin before html webpack plugin.
43
+ ...createModuleFederationPlugin(serveMode, entryMapItemList, evolveOptions),
44
+ // Create all need html plugins
45
+ ...createHtmlPlugins(serveMode, entryMapItemList, evolveOptions),
46
+ // Create all need ts-checker plugins
47
+ ...createTsCheckerPlugins(serveMode, entryMapItemList, evolveOptions),
48
+ ];
49
+ // Analyze an existing bundle, if allowed.
50
+ if (evolveOptions.analyzer) {
51
+ builtInPlugins.push(new BundleAnalyzerPlugin({
52
+ analyzerPort: 'auto',
53
+ analyzerMode: 'server',
54
+ ...evolveOptions.analyzer,
55
+ }));
56
+ }
57
+ // Indicates current we use `hot` mode for `webpack-dev-server` hot reload true.
58
+ const enabledHmr = shouldEnableReactFastRefresh(serveMode, firstEntryMapItem, evolveOptions);
59
+ if (enabledHmr) {
60
+ // Applies the react-refresh Babel plugin on non-production modes only
61
+ // Ensure `react-refresh/runtime` is hoisted and shared
62
+ // https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/docs/TROUBLESHOOTING.md#externalising-react
63
+ builtInPlugins.push(new ReactRefreshWebpackPlugin({
64
+ // Always use webpack-dev-server `client` overlay!
65
+ overlay: false,
66
+ }));
67
+ }
68
+ if (!enabledHmr && serveMode) {
69
+ if (evolveOptions.devServer?.liveReload) {
70
+ logger.warn(`The HMR disabled cause of "liveReload" specificed`);
71
+ }
72
+ else {
73
+ logger.warn(`The HMR disabled cause of \`"moduleFederation":"${entryName}"\``);
74
+ }
75
+ }
76
+ const extraPlugins = evolveOptions.webpack?.plugins || [];
77
+ return builtInPlugins.concat(extraPlugins);
78
+ };
@@ -1 +1,37 @@
1
- import{join}from"node:path";import{mergeOptions}from"@flatjs/common";import{TsconfigPathsPlugin}from"tsconfig-paths-webpack-plugin";export const createResolve=(s,o)=>{const n={mainFields:["browser","module","main"],extensions:[".ts",".tsx",".js",".json"],extensionAlias:{".js":[".js",".ts"],".cjs":[".cjs",".cts"],".mjs":[".mjs",".mts"],".jsx":[".jsx",".tsx"]},plugins:[new TsconfigPathsPlugin({configFile:join(s,"tsconfig.json"),extensions:[".ts",".tsx",".js",".jsx"]})]};return mergeOptions(n,o?.resolve||{})};
1
+ /* eslint-disable @typescript-eslint/naming-convention */
2
+ import { join } from 'node:path';
3
+ import { mergeOptions } from '@flatjs/common';
4
+ import { TsconfigPathsPlugin } from 'tsconfig-paths-webpack-plugin';
5
+ export const createResolve = (projectCwd, webpackOptions) => {
6
+ const resolve = {
7
+ mainFields: ['browser', 'module', 'main'],
8
+ // Add `.ts` and `.tsx` as a resolvable extension.
9
+ extensions: ['.ts', '.tsx', '.js', '.json'],
10
+ // Add support for TypeScripts fully qualified ESM imports.
11
+ extensionAlias: {
12
+ '.js': ['.js', '.ts'],
13
+ '.cjs': ['.cjs', '.cts'],
14
+ '.mjs': ['.mjs', '.mts'],
15
+ '.jsx': ['.jsx', '.tsx'],
16
+ },
17
+ plugins: [
18
+ // Resolve modules according to baseUrl and paths in your tsconfig.json.
19
+ // https://www.npmjs.com/package/tsconfig-paths-webpack-plugin
20
+ // FIXME: Don't support `moduleResolution:nodenext`, for now support `moduleResolution:node`
21
+ // All alias import don't include suffix e.g. `.js`
22
+ // 1. correct `import { x } from '@/utils/str`
23
+ // 2. wrong `import { x } from '@/utils/str.js`
24
+ // 3. it will also help `less-loader` to support `@import` directly no additional `resolve.alias` setup
25
+ // @import '~@/utils/xxx.less'
26
+ // @import url('./child.less');
27
+ // @import url('~@/react/less/alias.less');
28
+ // @import '~@/react/less/alias2.less';
29
+ // @import '~@/utils/shared.less';
30
+ new TsconfigPathsPlugin({
31
+ configFile: join(projectCwd, 'tsconfig.json'),
32
+ extensions: ['.ts', '.tsx', '.js', '.jsx'],
33
+ }),
34
+ ],
35
+ };
36
+ return mergeOptions(resolve, webpackOptions?.resolve || {});
37
+ };
@@ -1 +1,20 @@
1
- import{ruleAssets}from"./rule-sets/rule-assets.js";import{ruleCss}from"./rule-sets/rule-css.js";import{ruleLess}from"./rule-sets/rule-less.js";import{ruleScripts}from"./rule-sets/rule-scripts.js";import{ruleSvgIcon}from"./rule-sets/rule-svg-icon.js";export const createRuleSets=(s,e,r)=>{const l=e[0],t=[ruleSvgIcon(),ruleAssets(e,r),ruleCss(s,l,r,!1),ruleCss(s,l,r,!0),ruleLess(s,l,r),ruleScripts(s,l,r)],u=r.webpack?.ruleSets||[];return t.concat(u)};
1
+ import { ruleAssets } from './rule-sets/rule-assets.js';
2
+ import { ruleCss } from './rule-sets/rule-css.js';
3
+ import { ruleLess } from './rule-sets/rule-less.js';
4
+ import { ruleScripts } from './rule-sets/rule-scripts.js';
5
+ import { ruleSvgIcon } from './rule-sets/rule-svg-icon.js';
6
+ export const createRuleSets = (serveMode, entryMapItemList, evolveOptions) => {
7
+ const entryMapItem = entryMapItemList[0];
8
+ const rules = [
9
+ ruleSvgIcon(),
10
+ ruleAssets(entryMapItemList, evolveOptions),
11
+ // normal css style.
12
+ ruleCss(serveMode, entryMapItem, evolveOptions, false),
13
+ // css module style. xxx.module.css
14
+ ruleCss(serveMode, entryMapItem, evolveOptions, true),
15
+ ruleLess(serveMode, entryMapItem, evolveOptions),
16
+ ruleScripts(serveMode, entryMapItem, evolveOptions),
17
+ ];
18
+ const extraRuleSets = evolveOptions.webpack?.ruleSets || [];
19
+ return rules.concat(extraRuleSets);
20
+ };
@@ -1 +1,57 @@
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";export const loadWebpackConfig=async(e,t,r)=>{const a="development"===e,{projectCwd:o,webpack:s,devServer:c}=r,n=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:"minimal"},cache:{type:"memory"}}};
1
+ import { assertGroupEntryItem } from '../helpers/assert-group-entry-item.js';
2
+ import { createExternals } from './create-externals.js';
3
+ import { createOptimization } from './create-optimization.js';
4
+ import { createOutput } from './create-output.js';
5
+ import { createPerformance } from './create-performance.js';
6
+ import { createPlugins } from './create-plugins.js';
7
+ import { createResolve } from './create-resolve.js';
8
+ import { createRuleSets } from './create-rule-sets.js';
9
+ /**
10
+ * Try to organization the configuraiton object of `webpack`
11
+ * @param mode Enable production optimizations or development hints.
12
+ * @param entryMap The only single one `servedEntry` or `toBuildEntry`
13
+ * @param overrideOptions The manually override configuration options for flatjsEvolve
14
+ */
15
+ export const loadWebpackConfig = async (mode, entryMap, evolveOptions) => {
16
+ const serveMode = mode === 'development';
17
+ const { projectCwd, webpack, devServer } = evolveOptions;
18
+ const watchOptions = devServer?.watchOptions;
19
+ const entryMapItemList = assertGroupEntryItem(entryMap, evolveOptions);
20
+ const moduleRules = createRuleSets(serveMode, entryMapItemList, evolveOptions);
21
+ const plugins = await createPlugins(serveMode, entryMapItemList, evolveOptions);
22
+ const firstEntryMap = entryMapItemList[0];
23
+ const output = await createOutput(serveMode, evolveOptions, firstEntryMap);
24
+ const webpackConfig = {
25
+ mode,
26
+ plugins,
27
+ watchOptions,
28
+ output,
29
+ // The base directory, an absolute path, for resolving entry points and loaders from configuration.
30
+ // The context is an absolute string to the directory that contains the entry files.
31
+ context: projectCwd,
32
+ target: webpack?.target ?? ['web', 'es5'],
33
+ resolve: createResolve(projectCwd, webpack),
34
+ module: { rules: moduleRules },
35
+ devtool: serveMode ? 'eval-source-map' : webpack?.sourceMap || false,
36
+ externalsType: webpack?.externalsType,
37
+ // It's globally external configurations for all entries, if we need to specificed externals for each entry.
38
+ // Simply move it into entry options.
39
+ externals: createExternals(webpack?.externals, firstEntryMap),
40
+ performance: createPerformance(serveMode, webpack?.performance),
41
+ optimization: createOptimization(serveMode, evolveOptions, firstEntryMap),
42
+ // Setup logging level for `infrastructure` like. `webpack-dev-server`
43
+ infrastructureLogging: webpack?.infrastructureLogging ?? {
44
+ level: 'warn',
45
+ },
46
+ stats: webpack?.stats ?? {
47
+ preset: 'minimal',
48
+ },
49
+ cache: {
50
+ // Use `filesystem` cache to improve performance for `production` build
51
+ // Default cache directory is `node_modules/.cache`
52
+ // type: serveMode ? 'memory' : 'filesystem',
53
+ type: 'memory',
54
+ },
55
+ };
56
+ return webpackConfig;
57
+ };
@@ -1 +1,15 @@
1
- import{ensureSlash}from"@flatjs/common";export const resolvePublicPath=t=>{const{webpack:a}=t;let e="auto";return a?.publicPath&&"auto"!==a.publicPath&&(e=ensureSlash(a.publicPath,!0)),e};
1
+ import { ensureSlash } from '@flatjs/common';
2
+ /**
3
+ * Try to normalize publicPath, if we have customized publicPath, should be converted to `https://cdn.example.com/assets/`, `/assets/`
4
+ * @param evolveOptions
5
+ * @returns `auto` or customizd publicPath
6
+ */
7
+ export const resolvePublicPath = (evolveOptions) => {
8
+ const { webpack } = evolveOptions;
9
+ let publicPath = 'auto';
10
+ // If we have customized publicPath, should be converted to `https://cdn.example.com/assets/`, `/assets/`
11
+ if (webpack?.publicPath && webpack.publicPath !== 'auto') {
12
+ publicPath = ensureSlash(webpack.publicPath, true);
13
+ }
14
+ return publicPath;
15
+ };
@@ -1 +1,3 @@
1
- export const ICON_PATH_REGEX=/svg-icons\//;export const IMAGE_PATH_REGEX=/\.(?:jpe?g|png|gif|svg)$/;export const FONT_PATH_REGEX=/\.(?:ttf|eot|woff|woff2)(?:\?.+)?$/;
1
+ export const ICON_PATH_REGEX = /svg-icons\//;
2
+ export const IMAGE_PATH_REGEX = /\.(?:jpe?g|png|gif|svg)$/;
3
+ export const FONT_PATH_REGEX = /\.(?:ttf|eot|woff|woff2)(?:\?.+)?$/;
@@ -1 +1,52 @@
1
- import{dirname,join,relative,resolve}from"node:path";import{resolvePublicPath}from"../resolve-public-path.js";import{FONT_PATH_REGEX,IMAGE_PATH_REGEX}from"./constants.js";import{isIconSvg}from"./rule-utils.js";const getEntryAssetFileName=(e,t,r)=>{for(const o of t){const[t,s]=o,{projectCwd:a,projectVirtualPath:i}=r;let n=dirname(join(i,e.replace(/^src/,"")));const l=s.entry.map((e=>dirname(join(a,e)))),m=resolve(a,e),c=l.find((e=>m.startsWith(e)));return c&&(n=dirname(join(t,relative(c,m)))),`${n}/[name]-[contenthash:8][ext]`}};export const ruleAssets=(e,t)=>{const r=resolvePublicPath(t);return{type:"asset",test:e=>FONT_PATH_REGEX.test(e)||IMAGE_PATH_REGEX.test(e)&&!isIconSvg(e),generator:{filename:({filename:r})=>getEntryAssetFileName(r,e,t),publicPath:"auto"===r?void 0:r},parser:{dataUrlCondition:{maxSize:t.loaderOptions.assetDataUrlMaxSize}}}};
1
+ import { dirname, join, relative, resolve } from 'node:path';
2
+ import { resolvePublicPath } from '../resolve-public-path.js';
3
+ import { FONT_PATH_REGEX, IMAGE_PATH_REGEX } from './constants.js';
4
+ import { isIconSvg } from './rule-utils.js';
5
+ const getEntryAssetFileName = (filename, entryMapItemList, evolveOptions) => {
6
+ for (const entryMapItem of entryMapItemList) {
7
+ const [entryName, entryConfig] = entryMapItem;
8
+ const { projectCwd, projectVirtualPath } = evolveOptions;
9
+ let assetBase = dirname(join(projectVirtualPath, filename.replace(/^src/, '')));
10
+ const entryDirs = entryConfig.entry.map((file) => dirname(join(projectCwd, file)));
11
+ const assetAbsName = resolve(projectCwd, filename);
12
+ const matchedEntryDir = entryDirs.find((s) => assetAbsName.startsWith(s));
13
+ if (matchedEntryDir) {
14
+ assetBase = dirname(join(entryName, relative(matchedEntryDir, assetAbsName)));
15
+ }
16
+ return `${assetBase}/[name]-[contenthash:8][ext]`;
17
+ }
18
+ };
19
+ /**
20
+ * Preparing image loader for normal pictures except stored in folder `icons`
21
+ * Webpack@5 don't need `file-loader`, `raw-loader`, `url-loader` provider us `asset-modules`
22
+ * https://webpack.js.org/guides/asset-modules/
23
+ * @param entryMapItemList The available entries, `development` it contains multiple enties, `production`
24
+ */
25
+ export const ruleAssets = (entryMapItemList, evolveOptions) => {
26
+ // If we have customized publicPath, should be converted to `https://cdn.example.com/assets/`, `/assets/`
27
+ const publicPath = resolvePublicPath(evolveOptions);
28
+ const loader = {
29
+ type: 'asset',
30
+ test(resource) {
31
+ return (FONT_PATH_REGEX.test(resource) ||
32
+ (IMAGE_PATH_REGEX.test(resource) && !isIconSvg(resource)));
33
+ },
34
+ generator: {
35
+ // Rule.generator.filename is the same as output.assetModuleFilename and works only with asset and asset/resource module types.
36
+ filename({ filename }) {
37
+ return getEntryAssetFileName(filename, entryMapItemList, evolveOptions);
38
+ },
39
+ // Make sure that we use production cdn for images avoid use `requireExtensions`
40
+ // NOTE: if `auto` we need to remove `publicPath` configuration leave it to undefined.
41
+ publicPath: publicPath === 'auto' ? undefined : publicPath,
42
+ },
43
+ parser: {
44
+ // Now webpack will automatically choose between resource and inline by following
45
+ // a default condition: a file with size less than 8kb will be treated as a inline module type and resource module type otherwise.
46
+ dataUrlCondition: {
47
+ maxSize: evolveOptions.loaderOptions.assetDataUrlMaxSize, // 4 * 1024, // 4kb
48
+ },
49
+ },
50
+ };
51
+ return loader;
52
+ };
@@ -1 +1,111 @@
1
- import{requireResolve}from"@flatjs/common";import{forgePostcssPluginPixel}from"@flatjs/forge-postcss-plugin-pixel";import cssnano from"cssnano";import MiniCssExtractPlugin from"mini-css-extract-plugin";import{allowPx2remForModule}from"../../helpers/allow-px2rem-for-module.js";const getPostcssOptions=(s,o={},e={})=>{const r=[...e.plugins||[],cssnano({preset:["default",{discardComments:{removeAll:!s},reduceInitial:!1,normalizeWhitespace:!s,...e.cssnanoOptions}]})];return!1!==o&&r.push(forgePostcssPluginPixel(o)),{plugins:r}};export const ruleCss=(s,o,e,r=!1)=>{const{pixelOptions:t,cssLoaderOptions:i={},postcssOptions:l}=e.loaderOptions,n=r?{}:{modules:!1},p={test:/\.css$/i,use:[{loader:MiniCssExtractPlugin.loader,options:{esModule:!0}},{loader:requireResolve(import.meta.url,"css-loader"),options:{sourceMap:s,...i,...n}}]};r?p.include=/\.module\.css$/i:p.exclude=/\.module\.css$/i;const c=allowPx2remForModule(o,e);if(Array.isArray(p.use)){const o=getPostcssOptions(s,!!c&&t,l);p.use.push({loader:requireResolve(import.meta.url,"postcss-loader"),options:{postcssOptions:{...o,config:!1},sourceMap:s}})}return p};
1
+ import { requireResolve } from '@flatjs/common';
2
+ import { forgePostcssPluginPixel, } from '@flatjs/forge-postcss-plugin-pixel';
3
+ import cssnano from 'cssnano';
4
+ import MiniCssExtractPlugin from 'mini-css-extract-plugin';
5
+ import { allowPx2remForModule } from '../../helpers/allow-px2rem-for-module.js';
6
+ /**
7
+ * Normalize postcss-loader options.
8
+ * @param serveMode The value indicates if we are in `built` or `serve` mode.
9
+ * @param pixelOptions The pixel options of `postcss` plugin
10
+ * @param cssnanoOptions The configuration rules for `cssnano`
11
+ */
12
+ const getPostcssOptions = (serveMode, pixelOptions = {}, postcssOptions = {}) => {
13
+ // Use cssnano to minify css styles.
14
+ // https://cssnano.co/docs/config-file
15
+ const postCssPlugins = [
16
+ ...(postcssOptions.plugins || []),
17
+ cssnano({
18
+ // https://www.npmjs.com/package/cssnano-preset-default
19
+ // Note Advanced optimisations for cssnano; may or may not break your CSS!
20
+ // `Antd` was broken while use `advanced` preset.:(
21
+ preset: [
22
+ 'default',
23
+ {
24
+ discardComments: {
25
+ removeAll: !serveMode,
26
+ },
27
+ // throw new error `Please provide a proper feature name. Cannot find css-initial-value`
28
+ // disable this plugin `postcss-reduce-initial` via reduceInitial: false
29
+ // disable this plugin `postcss-minify-font-values` via minifyFontValues:false
30
+ reduceInitial: false,
31
+ // minifyFontValues: false,
32
+ normalizeWhitespace: !serveMode,
33
+ // allow us override cssnano configuration rules.
34
+ ...postcssOptions.cssnanoOptions,
35
+ },
36
+ ],
37
+ }),
38
+ ];
39
+ if (pixelOptions !== false) {
40
+ postCssPlugins.push(forgePostcssPluginPixel(pixelOptions));
41
+ }
42
+ return {
43
+ plugins: postCssPlugins,
44
+ };
45
+ };
46
+ /**
47
+ * Actually, style-loader is the one that is responsible for CSS HMR
48
+ * https://github.com/webpack-contrib/style-loader/blob/master/src/index.js#L31-L42
49
+ * @param serveMode
50
+ * @param entryMapItem
51
+ * @param evolveOptions `builtin` loaders
52
+ */
53
+ export const ruleCss = (serveMode, entryMapItem, evolveOptions, useCssModule = false) => {
54
+ // The value indicates we will enable px2rem using `@flatjs/forge-postcss-plugin-pixel`
55
+ const { pixelOptions, cssLoaderOptions = {}, postcssOptions, } = evolveOptions.loaderOptions;
56
+ const { modules, ...restCssLoaderOptions } = cssLoaderOptions;
57
+ // automatically enable css modules for files with .module.css extension
58
+ const cssLoaderOfCssModules = !useCssModule
59
+ ? { modules: false }
60
+ : {
61
+ modules: Object.assign({
62
+ // keep empty to allow user customized css modules options.
63
+ // Depends on the value of the esModule option. If the value of the esModule options is true, this value will also be true, otherwise it will be false.
64
+ // For now give default value `false` to allow import css module via `import styles from './stye.module.css'`, if we want to use named exports we can set it to `true` via `flatjs-evolve.config.ts`
65
+ namedExport: false,
66
+ }, modules),
67
+ };
68
+ const ruleSet = {
69
+ test: /\.css$/i,
70
+ use: [
71
+ {
72
+ loader: MiniCssExtractPlugin.loader,
73
+ options: {
74
+ // https://github.com/webpack-contrib/mini-css-extract-plugin/releases/tag/v1.0.0
75
+ // https://github.com/webpack-contrib/css-loader/blob/master/README.md#modules
76
+ esModule: true,
77
+ },
78
+ },
79
+ {
80
+ loader: requireResolve(import.meta.url, 'css-loader'),
81
+ options: {
82
+ sourceMap: serveMode,
83
+ ...cssLoaderOfCssModules,
84
+ ...restCssLoaderOptions,
85
+ },
86
+ },
87
+ ],
88
+ };
89
+ if (useCssModule) {
90
+ ruleSet.include = /\.module\.css$/i;
91
+ }
92
+ else {
93
+ ruleSet.exclude = /\.module\.css$/i;
94
+ }
95
+ const isAllowPx2Rem = allowPx2remForModule(entryMapItem, evolveOptions);
96
+ if (Array.isArray(ruleSet.use)) {
97
+ const postCssOption = getPostcssOptions(serveMode, isAllowPx2Rem ? pixelOptions : false, postcssOptions);
98
+ ruleSet.use.push({
99
+ loader: requireResolve(import.meta.url, 'postcss-loader'),
100
+ options: {
101
+ postcssOptions: {
102
+ ...postCssOption,
103
+ // Removes the need to lookup and load external config files ( `postcss.config.cjs`...) multiple times during compilation.
104
+ config: false,
105
+ },
106
+ sourceMap: serveMode,
107
+ },
108
+ });
109
+ }
110
+ return ruleSet;
111
+ };
@@ -1 +1,44 @@
1
- import{requireResolve}from"@flatjs/common";import{ruleCss}from"./rule-css.js";export const ruleLess=(s,e,r)=>{const o=ruleCss(s,e,r);o.test=/\.less$/i;const t=r.loaderOptions.lessOptions;return Array.isArray(o.use)&&o.use.push({loader:requireResolve(import.meta.url,"less-loader"),options:{sourceMap:s,lessOptions:{sourceMap:s,javascriptEnabled:!0,...t}}}),o};
1
+ import { requireResolve } from '@flatjs/common';
2
+ import { ruleCss } from './rule-css.js';
3
+ /**
4
+ * Preparing configurations for `less-loader`
5
+ * @param serveMode The value indicates if we are in `built` or `serve` mode.
6
+ * @param pluginLoaderOptions `builtin` loaders
7
+ * @example
8
+ * ```ts
9
+ * `~` makes the url an module
10
+ * webpack: {
11
+ * externals: {
12
+ * antd: 'antd',
13
+ * dayjs: 'dayjs',
14
+ * },
15
+ * resolve: {
16
+ * alias: {
17
+ * '@': resolve(projectCwd, './src'),
18
+ * },
19
+ * },
20
+ * },
21
+ * `@import '~@/theme/default.less';` at `src/theme/default.less`
22
+ *
23
+ * ```
24
+ */
25
+ export const ruleLess = (serveMode, entryMapItem, evolveOptions) => {
26
+ const ruleSet = ruleCss(serveMode, entryMapItem, evolveOptions);
27
+ ruleSet.test = /\.less$/i;
28
+ // The Options for Less.
29
+ const lessOptions = evolveOptions.loaderOptions.lessOptions;
30
+ if (Array.isArray(ruleSet.use)) {
31
+ ruleSet.use.push({
32
+ loader: requireResolve(import.meta.url, 'less-loader'),
33
+ options: {
34
+ sourceMap: serveMode,
35
+ lessOptions: {
36
+ sourceMap: serveMode,
37
+ javascriptEnabled: true,
38
+ ...lessOptions,
39
+ },
40
+ },
41
+ });
42
+ }
43
+ return ruleSet;
44
+ };
@@ -1 +1,34 @@
1
- import{requireResolve}from"@flatjs/common";import{mergeBabelOption}from"../../helpers/merge-babel-options.js";import{shouldEnableReactFastRefresh}from"../../helpers/should-enable-react-fast-refresh.js";export const ruleScripts=(e,r,s)=>{const{babelOptions:o={},modularImports:t=[]}=s.loaderOptions,l=mergeBabelOption(t,o);shouldEnableReactFastRefresh(e,r,s)&&(l.plugins?l.plugins.push(requireResolve(import.meta.url,"react-refresh/babel")):l.plugins=[requireResolve(import.meta.url,"react-refresh/babel")]);return{test:/\.(tsx|ts|js|jsx)$/,use:[{loader:requireResolve(import.meta.url,"babel-loader"),options:l}]}};
1
+ import { requireResolve } from '@flatjs/common';
2
+ import { mergeBabelOption } from '../../helpers/merge-babel-options.js';
3
+ import { shouldEnableReactFastRefresh } from '../../helpers/should-enable-react-fast-refresh.js';
4
+ export const ruleScripts = (serveMode, entryMapItem, evolveOptions) => {
5
+ const { babelOptions = {}, modularImports = [] } = evolveOptions.loaderOptions;
6
+ const finnalBabelOptions = mergeBabelOption(modularImports, babelOptions);
7
+ // Indicates current we use `hot` mode for `webpack-dev-server` hot reload true.
8
+ const enabledHmr = shouldEnableReactFastRefresh(serveMode, entryMapItem, evolveOptions);
9
+ // 针对react 自动注入`react-refresh/babel`
10
+ if (enabledHmr) {
11
+ if (finnalBabelOptions.plugins) {
12
+ finnalBabelOptions.plugins.push(requireResolve(import.meta.url, 'react-refresh/babel'));
13
+ }
14
+ else {
15
+ finnalBabelOptions.plugins = [
16
+ requireResolve(import.meta.url, 'react-refresh/babel'),
17
+ ];
18
+ }
19
+ }
20
+ const loader = {
21
+ // use `vue-loader` to handle .vue here.
22
+ // test: /\.(tsx|ts|js|jsx|vue)$/,
23
+ test: /\.(tsx|ts|js|jsx)$/,
24
+ // Don't exclude anythings because of we need to import node_modules from `@flatjs`
25
+ // exclude: /(node_modules|bower_components)/,
26
+ use: [
27
+ {
28
+ loader: requireResolve(import.meta.url, 'babel-loader'),
29
+ options: finnalBabelOptions,
30
+ },
31
+ ],
32
+ };
33
+ return loader;
34
+ };