@flatjs/evolve 1.8.1-next.65 → 1.8.1-next.67
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +30 -0
- package/dist/constants.js +17 -1
- package/dist/create-webpack/create-externals.js +6 -1
- package/dist/create-webpack/create-optimization.js +29 -1
- package/dist/create-webpack/create-output.js +35 -1
- package/dist/create-webpack/create-performance.js +7 -1
- package/dist/create-webpack/create-plugins.js +78 -1
- package/dist/create-webpack/create-resolve.js +31 -1
- package/dist/create-webpack/create-rule-sets.js +16 -1
- package/dist/create-webpack/load-webpack-config.js +55 -1
- package/dist/create-webpack/rule-sets/constants.js +3 -1
- package/dist/create-webpack/rule-sets/rule-assets.js +44 -1
- package/dist/create-webpack/rule-sets/rule-css.js +84 -1
- package/dist/create-webpack/rule-sets/rule-less.js +45 -1
- package/dist/create-webpack/rule-sets/rule-scripts.js +27 -1
- package/dist/create-webpack/rule-sets/rule-svg-icon.js +25 -1
- package/dist/create-webpack/rule-sets/rule-utils.js +10 -1
- package/dist/create-webpack/types.js +1 -1
- package/dist/default-options.js +79 -1
- package/dist/define-config/define-config.js +4 -1
- package/dist/define-config/index.js +1 -1
- package/dist/dev-server/add-compiler-to-dev-server.js +47 -1
- package/dist/dev-server/create-app-page-route.js +11 -1
- package/dist/dev-server/create-dev-server-compiler-tasks.js +51 -1
- package/dist/dev-server/create-dev-server-entries.js +27 -1
- package/dist/dev-server/create-dev-server.js +23 -1
- package/dist/dev-server/index.js +6 -1
- package/dist/dev-server/middlewares/create-page-middleware.js +164 -1
- package/dist/dev-server/middlewares/create-public-assets-middleware.js +25 -1
- package/dist/dev-server/middlewares/index.js +2 -1
- package/dist/errors/evolve-build-error.js +10 -1
- package/dist/helpers/allow-px2rem-for-module.js +6 -1
- package/dist/helpers/assert-only-single-entry-item.js +23 -1
- package/dist/helpers/chunk-entry-map.js +21 -1
- package/dist/helpers/enable-bundle-hashname-for-module.js +6 -1
- package/dist/helpers/filter-actived-entries.d.ts +1 -1
- package/dist/helpers/filter-actived-entries.js +41 -1
- package/dist/helpers/get-bundle-file-name.js +23 -1
- package/dist/helpers/get-git-root.js +4 -1
- package/dist/helpers/get-html-plugin-config.d.ts +9 -1
- package/dist/helpers/get-html-plugin-config.js +47 -1
- package/dist/helpers/get-max-process-tasks.d.ts +1 -0
- package/dist/helpers/get-max-process-tasks.js +7 -0
- package/dist/helpers/get-pacakge-dir.js +13 -1
- package/dist/helpers/index.js +15 -1
- package/dist/helpers/merge-babel-options.js +45 -1
- package/dist/helpers/normalize-entry-map.js +38 -1
- package/dist/helpers/open-page.js +15 -1
- package/dist/helpers/print-log.js +49 -1
- package/dist/helpers/refresh-evolve-mock-options.js +23 -1
- package/dist/helpers/resolve-entry-map-input-files.js +20 -1
- package/dist/helpers/script-injects.js +39 -1
- package/dist/helpers/should-enable-react-fast-refresh.js +8 -1
- package/dist/helpers/split-to-multi-compiler.js +22 -1
- package/dist/index.js +5 -1
- package/dist/load-config/index.js +1 -1
- package/dist/load-config/load-evolve-config.js +35 -1
- package/dist/main/env-verify.js +21 -1
- package/dist/main/index.js +4 -1
- package/dist/main/prepare-build.d.ts +4 -8
- package/dist/main/prepare-build.js +38 -1
- package/dist/main/prepare-serve.js +36 -1
- package/dist/main/prepare-static.js +28 -1
- package/dist/main/start-build-dynamic.d.ts +2 -1
- package/dist/main/start-build-dynamic.js +144 -1
- package/dist/main/start-build-worker.d.ts +14 -0
- package/dist/main/start-build-worker.js +41 -0
- package/dist/main/start-build.d.ts +1 -8
- package/dist/main/start-build.js +49 -1
- package/dist/main/start-one-entry-build.d.ts +13 -0
- package/dist/main/start-one-entry-build.js +35 -0
- package/dist/main/start-serve.js +32 -1
- package/dist/main/start-static.js +16 -1
- package/dist/minimizer/create-minimizers.js +25 -1
- package/dist/minimizer/default-options.js +14 -1
- package/dist/minimizer/image-minimizer.js +56 -1
- package/dist/minimizer/index.js +1 -1
- package/dist/minimizer/terser-minimizer.js +15 -3
- package/dist/minimizer/types.js +1 -1
- package/dist/plugins/clean-webpack/clean-webpack-plugin.js +173 -1
- package/dist/plugins/clean-webpack/index.js +22 -1
- package/dist/plugins/define-variable/define-variable-plugin.js +21 -1
- package/dist/plugins/define-variable/index.js +1 -1
- package/dist/plugins/html-inject-scripts/plugin-html-inject-script.js +27 -1
- package/dist/plugins/module-federation/external-template-remotes.js +92 -1
- package/dist/plugins/module-federation/index.js +1 -1
- package/dist/plugins/module-federation/module-federation.js +98 -1
- package/dist/plugins/multi-html/index.js +15 -1
- package/dist/plugins/multi-html/multi-html-cdn-plugin.js +84 -1
- package/dist/plugins/multi-html/multi-html-plugin.js +70 -1
- package/dist/types/index.js +8 -1
- package/dist/types/types-ci.js +1 -1
- package/dist/types/types-dev-server.js +1 -1
- package/dist/types/types-entry-map.js +1 -1
- package/dist/types/types-federation.js +1 -1
- package/dist/types/types-loader-options.js +1 -1
- package/dist/types/types-modular-import.js +1 -1
- package/dist/types/types-multi-html.d.ts +6 -5
- package/dist/types/types-multi-html.js +1 -1
- package/dist/types/types-options.js +1 -1
- package/dist/types/types-plugin-options.js +1 -1
- package/dist/types/types-webpack.d.ts +1 -1
- package/dist/types/types-webpack.js +1 -1
- package/package.json +14 -12
- package/templates/html-plugin/index-dev.html +31 -38
- package/templates/html-plugin/index-inte.html +31 -38
- package/templates/html-plugin/index-inte2.html +31 -38
- package/templates/html-plugin/index-inte3.html +31 -38
- package/templates/html-plugin/index-inte4.html +31 -38
- package/templates/html-plugin/index-me.html +31 -38
- package/templates/html-plugin/index-prod.html +31 -38
- package/templates/html-plugin/index-rc.html +31 -38
- package/templates/html-plugin/index-uat.html +31 -38
- package/templates/module.html +40 -55
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,35 @@
|
|
1
1
|
# @flatjs/evolve
|
2
2
|
|
3
|
+
## 1.8.1-next.67
|
4
|
+
|
5
|
+
### Patch Changes
|
6
|
+
|
7
|
+
- 4086027: Expose `html-templte` token can be `function` or `primitve`
|
8
|
+
- b9ccc8a: refactor `build` to support `worker-threads`
|
9
|
+
- 86254d0: refactor evolve omit `unneed` mock config load
|
10
|
+
- 97b9523: bump version
|
11
|
+
- Updated dependencies [9c38501]
|
12
|
+
- Updated dependencies [372f3c9]
|
13
|
+
- Updated dependencies [97b9523]
|
14
|
+
- Updated dependencies [33289bc]
|
15
|
+
- Updated dependencies [1d1cb5e]
|
16
|
+
- Updated dependencies [7d6aa36]
|
17
|
+
- @flatjs/common@1.8.1-next.30
|
18
|
+
- @flatjs/forge-postcss-plugin-pixel@1.8.1-next.30
|
19
|
+
- @flatjs/evolve-preset-babel@1.8.1-next.15
|
20
|
+
- @flatjs/graph@1.8.1-next.36
|
21
|
+
- @flatjs/mock@1.8.1-next.55
|
22
|
+
|
23
|
+
## 1.8.1-next.66
|
24
|
+
|
25
|
+
### Patch Changes
|
26
|
+
|
27
|
+
- c8b6937: Update `loading` message with newline
|
28
|
+
- 2204384: formatting evolve building messages
|
29
|
+
- Updated dependencies [929b998]
|
30
|
+
- Updated dependencies [728d0e1]
|
31
|
+
- @flatjs/mock@1.8.1-next.54
|
32
|
+
|
3
33
|
## 1.8.1-next.65
|
4
34
|
|
5
35
|
### Patch Changes
|
package/dist/constants.js
CHANGED
@@ -1 +1,17 @@
|
|
1
|
-
export const moduleName=
|
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
|
+
];
|
@@ -1 +1,6 @@
|
|
1
|
-
import{mergeOptions}from
|
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,29 @@
|
|
1
|
-
import{createMinimizers}from
|
1
|
+
import { createMinimizers } from '../minimizer/index.js';
|
2
|
+
export const createOptimization = (serveMode, webpackOptions) => {
|
3
|
+
const webpackOptimization = {
|
4
|
+
nodeEnv: serveMode ? 'development' : 'production',
|
5
|
+
chunkIds: 'named',
|
6
|
+
moduleIds: 'named',
|
7
|
+
// This is true in production mode. Tell webpack to minimize the bundle using the TerserPlugin
|
8
|
+
minimize: webpackOptions?.minimizer !== false && !serveMode,
|
9
|
+
// Note: the `minimizer` will executed must be wait until `minimize` is `true`
|
10
|
+
minimizer: createMinimizers(serveMode, webpackOptions),
|
11
|
+
// Disabled WARNING in webpack while chunk exceed the recommended size limit for `serve`
|
12
|
+
splitChunks: {
|
13
|
+
// It is recommended to set splitChunks.name to false for production builds
|
14
|
+
// so that it doesn't change names unnecessarily.
|
15
|
+
name: false,
|
16
|
+
// include all types of chunks
|
17
|
+
// chunks: 'async',
|
18
|
+
chunks: 'all',
|
19
|
+
// 2.3841858(MB)
|
20
|
+
minSize: 2500000,
|
21
|
+
// disable vendors~loadsh.js...
|
22
|
+
cacheGroups: {
|
23
|
+
default: false,
|
24
|
+
defaultVendors: false,
|
25
|
+
},
|
26
|
+
},
|
27
|
+
};
|
28
|
+
return webpackOptimization;
|
29
|
+
};
|
@@ -1 +1,35 @@
|
|
1
|
-
import{join
|
1
|
+
import { join } from 'node:path';
|
2
|
+
import { ensureSlash } from '@flatjs/common';
|
3
|
+
import { getBundleFileName } from '../helpers/get-bundle-file-name.js';
|
4
|
+
export const createOutput = async (serveMode, evolveOptions) => {
|
5
|
+
const { projectCwd, webpack } = evolveOptions;
|
6
|
+
let publicPath = 'auto';
|
7
|
+
// If we have customized publicPath, should be converted to `https://cdn.example.com/assets/`, `/assets/`
|
8
|
+
if (webpack?.publicPath && webpack.publicPath !== 'auto') {
|
9
|
+
publicPath = ensureSlash(webpack.publicPath, true);
|
10
|
+
}
|
11
|
+
// Allow us dynamic return `outputDir`, e.g dev_xxxx, we can create built directory via `branchName`
|
12
|
+
const outputDir = typeof webpack?.outputDir === 'function'
|
13
|
+
? await webpack.outputDir()
|
14
|
+
: webpack?.outputDir || 'public';
|
15
|
+
const webpackOutput = {
|
16
|
+
// Formatting devtool sourcemap template file.
|
17
|
+
devtoolModuleFilenameTemplate: ({ namespace, resourcePath }) => {
|
18
|
+
return `webpack:///${join(namespace, resourcePath)}`;
|
19
|
+
},
|
20
|
+
// Replace output.ecmaVersion with output.environment and more detailed
|
21
|
+
environment: {},
|
22
|
+
// Include comments with information about the modules, Disable it can improved performance.
|
23
|
+
pathinfo: false,
|
24
|
+
// The output directory as an absolute path.
|
25
|
+
path: join(projectCwd, outputDir),
|
26
|
+
// The publicPath specifies the public URL address of the output files when referenced in a browser.
|
27
|
+
publicPath,
|
28
|
+
// Specifies the name of each output file on disk. You must not specify an absolute path here!
|
29
|
+
filename: `[name]/${getBundleFileName('js', serveMode, webpack?.enableBundleHashName)}`,
|
30
|
+
// hotUpdateMainFilename: '[runtime].[fullhash].hot-update.json',
|
31
|
+
// The filename of non-entry chunks as relative path inside the output.path directory.
|
32
|
+
chunkFilename: `[id].[contenthash].js`,
|
33
|
+
};
|
34
|
+
return webpackOutput;
|
35
|
+
};
|
@@ -1 +1,7 @@
|
|
1
|
-
export const createPerformance=(
|
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
|
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 ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
|
5
|
+
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
6
|
+
import webpack from 'webpack';
|
7
|
+
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
8
|
+
import { enableBundleHashNameForModule } from '../helpers/enable-bundle-hashname-for-module.js';
|
9
|
+
import { getBundleFileName } from '../helpers/get-bundle-file-name.js';
|
10
|
+
import { shouldEnableReactFastRefresh } from '../helpers/should-enable-react-fast-refresh.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
|
+
export const createPlugins = async (serveMode, entryMapItem, evolveOptions) => {
|
16
|
+
const [entryName, entryItemOption] = entryMapItem;
|
17
|
+
const bundleHashNameEnabled = enableBundleHashNameForModule(evolveOptions, entryItemOption?.options);
|
18
|
+
const builtInPlugins = [
|
19
|
+
// Because TS will may generate .js and .d.ts files, you should ignore these files,
|
20
|
+
// otherwise watchers may go into an infinite watch loop.
|
21
|
+
new webpack.WatchIgnorePlugin({
|
22
|
+
paths: [/\.d\.[cm]ts$/],
|
23
|
+
}),
|
24
|
+
// Case Sensitive Paths for OSX
|
25
|
+
new CaseSensitivePathsPlugin(),
|
26
|
+
// For css minify extractor
|
27
|
+
new MiniCssExtractPlugin({
|
28
|
+
// Options similar to the same options in webpackOptions.output
|
29
|
+
// both options are optional
|
30
|
+
filename: `[name]/${getBundleFileName('css', serveMode, bundleHashNameEnabled)}`,
|
31
|
+
// the chunkFilename option can be a function for webpack@5
|
32
|
+
chunkFilename: '[id].[contenthash].css',
|
33
|
+
}),
|
34
|
+
// create builtin DefinePlugin
|
35
|
+
...(await createBuiltinDefineVariables(serveMode, evolveOptions)),
|
36
|
+
// clean webpack plugin
|
37
|
+
...createCleanWebpackPlugin(serveMode, entryMapItem, evolveOptions),
|
38
|
+
// Put ModuleFederationPlugin before html webpack plugin.
|
39
|
+
...createModuleFederationPlugin(serveMode, entryMapItem, evolveOptions),
|
40
|
+
// Create all need html plugins
|
41
|
+
...createHtmlPlugins(serveMode, entryMapItem, evolveOptions),
|
42
|
+
];
|
43
|
+
const { analyzer, loaderOptions } = evolveOptions;
|
44
|
+
// FIXME: how to handle .vue?, disabled tsChecker for Vue now!
|
45
|
+
const itemEntries = entryMapItem[1].entry || [];
|
46
|
+
const isVueEntryItem = itemEntries.find((s) => /.vue$/.test(s));
|
47
|
+
// Runs typescript type checker and linter on separate process.
|
48
|
+
if (loaderOptions.runTsChecker && !isVueEntryItem) {
|
49
|
+
builtInPlugins.push(new ForkTsCheckerWebpackPlugin({
|
50
|
+
async: serveMode,
|
51
|
+
typescript: {
|
52
|
+
context: evolveOptions.projectCwd,
|
53
|
+
memoryLimit: 2048 * 4,
|
54
|
+
},
|
55
|
+
}));
|
56
|
+
}
|
57
|
+
// Analyze an existing bundle, if allowed.
|
58
|
+
if (analyzer) {
|
59
|
+
builtInPlugins.push(new BundleAnalyzerPlugin({
|
60
|
+
analyzerPort: 'auto',
|
61
|
+
analyzerMode: 'server',
|
62
|
+
...analyzer,
|
63
|
+
}));
|
64
|
+
}
|
65
|
+
// Indicates current we use `hot` mode for `webpack-dev-server` hot reload true.
|
66
|
+
const enableHmr = shouldEnableReactFastRefresh(serveMode, entryMapItem, evolveOptions);
|
67
|
+
if (enableHmr) {
|
68
|
+
builtInPlugins.push(new ReactRefreshWebpackPlugin({
|
69
|
+
// Always use webpack-dev-server `client` overlay!
|
70
|
+
overlay: false,
|
71
|
+
}));
|
72
|
+
}
|
73
|
+
if (!enableHmr && serveMode) {
|
74
|
+
logger.warn(`The HMR has disabled cause of ("${entryName}":"moduleFederation")`);
|
75
|
+
}
|
76
|
+
const extraPlugins = evolveOptions.webpack?.plugins || [];
|
77
|
+
return builtInPlugins.concat(extraPlugins);
|
78
|
+
};
|
@@ -1 +1,31 @@
|
|
1
|
-
|
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
|
+
new TsconfigPathsPlugin({
|
25
|
+
configFile: join(projectCwd, 'tsconfig.json'),
|
26
|
+
extensions: ['.ts', '.tsx', '.js'],
|
27
|
+
}),
|
28
|
+
],
|
29
|
+
};
|
30
|
+
return mergeOptions(resolve, webpackOptions?.resolve || {});
|
31
|
+
};
|
@@ -1 +1,16 @@
|
|
1
|
-
import{ruleAssets}from
|
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, entryMapItem, evolveOptions) => {
|
7
|
+
const rules = [
|
8
|
+
ruleSvgIcon(),
|
9
|
+
ruleAssets(entryMapItem, evolveOptions),
|
10
|
+
ruleCss(serveMode, entryMapItem, evolveOptions),
|
11
|
+
ruleLess(serveMode, entryMapItem, evolveOptions),
|
12
|
+
ruleScripts(serveMode, entryMapItem, evolveOptions),
|
13
|
+
];
|
14
|
+
const extraRuleSets = evolveOptions.webpack?.ruleSets || [];
|
15
|
+
return rules.concat(extraRuleSets);
|
16
|
+
};
|
@@ -1 +1,55 @@
|
|
1
|
-
import{assertOnlySingleEntryItem}from
|
1
|
+
import { assertOnlySingleEntryItem } from '../helpers/assert-only-single-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 singleEntryItem = assertOnlySingleEntryItem(entryMap, evolveOptions);
|
20
|
+
const moduleRules = createRuleSets(serveMode, singleEntryItem, evolveOptions);
|
21
|
+
const plugins = await createPlugins(serveMode, singleEntryItem, evolveOptions);
|
22
|
+
const output = await createOutput(serveMode, evolveOptions);
|
23
|
+
const webpackConfig = {
|
24
|
+
mode,
|
25
|
+
plugins,
|
26
|
+
watchOptions,
|
27
|
+
output,
|
28
|
+
// The base directory, an absolute path, for resolving entry points and loaders from configuration.
|
29
|
+
// The context is an absolute string to the directory that contains the entry files.
|
30
|
+
context: projectCwd,
|
31
|
+
target: webpack?.target ?? ['web', 'es5'],
|
32
|
+
resolve: createResolve(projectCwd, webpack),
|
33
|
+
module: { rules: moduleRules },
|
34
|
+
devtool: serveMode ? 'eval-source-map' : webpack?.sourceMap || false,
|
35
|
+
// It's globally external configurations for all entries, if we need to specificed externals for each entry.
|
36
|
+
// Simply move it into entry options.
|
37
|
+
externals: createExternals(webpack?.externals, singleEntryItem),
|
38
|
+
performance: createPerformance(serveMode, webpack?.performance),
|
39
|
+
optimization: createOptimization(serveMode, webpack),
|
40
|
+
// Setup logging level for `infrastructure` like. `webpack-dev-server`
|
41
|
+
infrastructureLogging: webpack?.infrastructureLogging ?? {
|
42
|
+
level: 'warn',
|
43
|
+
},
|
44
|
+
stats: webpack?.stats ?? {
|
45
|
+
preset: 'minimal',
|
46
|
+
},
|
47
|
+
cache: {
|
48
|
+
// Use `filesystem` cache to improve performance for `production` build
|
49
|
+
// Default cache directory is `node_modules/.cache`
|
50
|
+
// type: serveMode ? 'memory' : 'filesystem',
|
51
|
+
type: 'memory',
|
52
|
+
},
|
53
|
+
};
|
54
|
+
return webpackConfig;
|
55
|
+
};
|
@@ -1 +1,3 @@
|
|
1
|
-
export const ICON_PATH_REGEX
|
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,44 @@
|
|
1
|
-
import
|
1
|
+
import { dirname, join, relative, resolve } from 'node:path';
|
2
|
+
import { FONT_PATH_REGEX, IMAGE_PATH_REGEX } from './constants.js';
|
3
|
+
import { isIconSvg } from './rule-utils.js';
|
4
|
+
const getEntryAssetFileName = (filename, entryMapItem, evolveOptions) => {
|
5
|
+
const [entryName, entryConfig] = entryMapItem;
|
6
|
+
const { projectCwd, projectVirtualPath } = evolveOptions;
|
7
|
+
let assetBase = dirname(join(projectVirtualPath, filename.replace(/^src/, '')));
|
8
|
+
const entryDirs = entryConfig.entry.map((file) => dirname(join(projectCwd, file)));
|
9
|
+
const assetAbsName = resolve(projectCwd, filename);
|
10
|
+
const matchedEntryDir = entryDirs.find((s) => assetAbsName.startsWith(s));
|
11
|
+
if (matchedEntryDir) {
|
12
|
+
assetBase = dirname(join(entryName, relative(matchedEntryDir, assetAbsName)));
|
13
|
+
}
|
14
|
+
return `${assetBase}/[name]-[contenthash:8][ext]`;
|
15
|
+
};
|
16
|
+
/**
|
17
|
+
* Preparing image loader for normal pictures except stored in folder `icons`
|
18
|
+
* Webpack@5 don't need `file-loader`, `raw-loader`, `url-loader` provider us `asset-modules`
|
19
|
+
* https://webpack.js.org/guides/asset-modules/
|
20
|
+
* @param entryItem The available entries, `development` it contains multiple enties, `production` only one entry in once build.
|
21
|
+
*/
|
22
|
+
export const ruleAssets = (entryItem, evolveOptions) => {
|
23
|
+
const loader = {
|
24
|
+
type: 'asset',
|
25
|
+
test(resource) {
|
26
|
+
return (FONT_PATH_REGEX.test(resource) ||
|
27
|
+
(IMAGE_PATH_REGEX.test(resource) && !isIconSvg(resource)));
|
28
|
+
},
|
29
|
+
generator: {
|
30
|
+
// Rule.generator.filename is the same as output.assetModuleFilename and works only with asset and asset/resource module types.
|
31
|
+
filename({ filename }) {
|
32
|
+
return getEntryAssetFileName(filename, entryItem, evolveOptions);
|
33
|
+
},
|
34
|
+
},
|
35
|
+
parser: {
|
36
|
+
// Now webpack will automatically choose between resource and inline by following
|
37
|
+
// a default condition: a file with size less than 8kb will be treated as a inline module type and resource module type otherwise.
|
38
|
+
dataUrlCondition: {
|
39
|
+
maxSize: evolveOptions.loaderOptions.assetDataUrlMaxSize, // 4 * 1024, // 4kb
|
40
|
+
},
|
41
|
+
},
|
42
|
+
};
|
43
|
+
return loader;
|
44
|
+
};
|
@@ -1 +1,84 @@
|
|
1
|
-
import{forgePostcssPluginPixel}from
|
1
|
+
import { forgePostcssPluginPixel, } from '@flatjs/forge-postcss-plugin-pixel';
|
2
|
+
import cssnano from 'cssnano';
|
3
|
+
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
4
|
+
import { allowPx2remForModule } from '../../helpers/allow-px2rem-for-module.js';
|
5
|
+
/**
|
6
|
+
* Normalize postcss-loader options.
|
7
|
+
* @param serveMode The value indicates if we are in `built` or `serve` mode.
|
8
|
+
* @param pixelOptions The pixel options of `postcss` plugin
|
9
|
+
* @param cssnanoOptions The configuration rules for `cssnano`
|
10
|
+
*/
|
11
|
+
const getPostcssOptions = (serveMode, pixelOptions = {}, postcssOptions = {}) => {
|
12
|
+
// Use cssnano to minify css styles.
|
13
|
+
// https://cssnano.co/docs/config-file
|
14
|
+
const postCssPlugins = [
|
15
|
+
...(postcssOptions.plugins || []),
|
16
|
+
cssnano({
|
17
|
+
// https://www.npmjs.com/package/cssnano-preset-default
|
18
|
+
// Note Advanced optimisations for cssnano; may or may not break your CSS!
|
19
|
+
// `Antd` was broken while use `advanced` preset.:(
|
20
|
+
preset: [
|
21
|
+
'default',
|
22
|
+
{
|
23
|
+
discardComments: {
|
24
|
+
removeAll: !serveMode,
|
25
|
+
},
|
26
|
+
// throw new error `Please provide a proper feature name. Cannot find css-initial-value`
|
27
|
+
// disable this plugin `postcss-reduce-initial` via reduceInitial: false
|
28
|
+
// disable this plugin `postcss-minify-font-values` via minifyFontValues:false
|
29
|
+
reduceInitial: false,
|
30
|
+
// minifyFontValues: false,
|
31
|
+
normalizeWhitespace: !serveMode,
|
32
|
+
// allow us override cssnano configuration rules.
|
33
|
+
...postcssOptions.cssnanoOptions,
|
34
|
+
},
|
35
|
+
],
|
36
|
+
}),
|
37
|
+
];
|
38
|
+
if (pixelOptions !== false) {
|
39
|
+
postCssPlugins.push(forgePostcssPluginPixel(pixelOptions));
|
40
|
+
}
|
41
|
+
return {
|
42
|
+
plugins: postCssPlugins,
|
43
|
+
};
|
44
|
+
};
|
45
|
+
/**
|
46
|
+
* Actually, style-loader is the one that is responsible for CSS HMR
|
47
|
+
* https://github.com/webpack-contrib/style-loader/blob/master/src/index.js#L31-L42
|
48
|
+
* @param serveMode
|
49
|
+
* @param entryMapItem
|
50
|
+
* @param evolveOptions `builtin` loaders
|
51
|
+
*/
|
52
|
+
export const ruleCss = (serveMode, entryMapItem, evolveOptions) => {
|
53
|
+
const ruleSet = {
|
54
|
+
test: /\.css$/i,
|
55
|
+
use: [
|
56
|
+
{
|
57
|
+
loader: MiniCssExtractPlugin.loader,
|
58
|
+
options: {
|
59
|
+
// https://github.com/webpack-contrib/mini-css-extract-plugin/releases/tag/v1.0.0
|
60
|
+
esModule: true,
|
61
|
+
},
|
62
|
+
},
|
63
|
+
{ loader: 'css-loader', options: { sourceMap: serveMode } },
|
64
|
+
],
|
65
|
+
};
|
66
|
+
// The value indicates we will enable px2rem using `@flatjs/forge-postcss-plugin-pixel`
|
67
|
+
const { pixelOptions, postcssOptions } = evolveOptions.loaderOptions;
|
68
|
+
const isAllowPx2Rem = allowPx2remForModule(entryMapItem, evolveOptions);
|
69
|
+
if (Array.isArray(ruleSet.use)) {
|
70
|
+
const postCssOption = getPostcssOptions(serveMode, isAllowPx2Rem ? pixelOptions : false, postcssOptions);
|
71
|
+
ruleSet.use.push({
|
72
|
+
loader: 'postcss-loader',
|
73
|
+
options: {
|
74
|
+
postcssOptions: {
|
75
|
+
...postCssOption,
|
76
|
+
// Removes the need to lookup and load external config files ( `postcss.config.cjs`...) multiple times during compilation.
|
77
|
+
config: false,
|
78
|
+
},
|
79
|
+
sourceMap: serveMode,
|
80
|
+
},
|
81
|
+
});
|
82
|
+
}
|
83
|
+
return ruleSet;
|
84
|
+
};
|
@@ -1 +1,45 @@
|
|
1
|
-
import{requireResolve}from
|
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
|
+
* style: resolve(projectCwd, './src/style'),
|
18
|
+
* theme: resolve(projectCwd, './src/layout/theme'),
|
19
|
+
* },
|
20
|
+
* },
|
21
|
+
* },
|
22
|
+
* `@import '~theme/default.less';` at `style.less`
|
23
|
+
*
|
24
|
+
* ```
|
25
|
+
*/
|
26
|
+
export const ruleLess = (serveMode, entryMapItem, evolveOptions) => {
|
27
|
+
const ruleSet = ruleCss(serveMode, entryMapItem, evolveOptions);
|
28
|
+
ruleSet.test = /\.less$/i;
|
29
|
+
// The Options for Less.
|
30
|
+
const lessOptions = evolveOptions.loaderOptions.lessOptions;
|
31
|
+
if (Array.isArray(ruleSet.use)) {
|
32
|
+
ruleSet.use.push({
|
33
|
+
loader: requireResolve('less-loader'),
|
34
|
+
options: {
|
35
|
+
sourceMap: serveMode,
|
36
|
+
lessOptions: {
|
37
|
+
sourceMap: serveMode,
|
38
|
+
javascriptEnabled: true,
|
39
|
+
...lessOptions,
|
40
|
+
},
|
41
|
+
},
|
42
|
+
});
|
43
|
+
}
|
44
|
+
return ruleSet;
|
45
|
+
};
|
@@ -1 +1,27 @@
|
|
1
|
-
import{requireResolve}from
|
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
|
+
// 针对react 自动注入`react-refresh/babel`
|
8
|
+
if (shouldEnableReactFastRefresh(serveMode, entryMapItem, evolveOptions)) {
|
9
|
+
if (finnalBabelOptions.plugins) {
|
10
|
+
finnalBabelOptions.plugins.push(requireResolve('react-refresh/babel'));
|
11
|
+
}
|
12
|
+
else {
|
13
|
+
finnalBabelOptions.plugins = [requireResolve('react-refresh/babel')];
|
14
|
+
}
|
15
|
+
}
|
16
|
+
const loader = {
|
17
|
+
// use `vue-loader` to handle .vue here.
|
18
|
+
// test: /\.(tsx|ts|js|jsx|vue)$/,
|
19
|
+
test: /\.(tsx|ts|js|jsx)$/,
|
20
|
+
// Don't exclude anythings because of we need to import node_modules from `@flatjs`
|
21
|
+
// exclude: /(node_modules|bower_components)/,
|
22
|
+
use: [
|
23
|
+
{ loader: requireResolve('babel-loader'), options: finnalBabelOptions },
|
24
|
+
],
|
25
|
+
};
|
26
|
+
return loader;
|
27
|
+
};
|
@@ -1 +1,25 @@
|
|
1
|
-
import{getDirname}from
|
1
|
+
import { getDirname } from '@armit/file-utility';
|
2
|
+
import { isIconSvg } from './rule-utils.js';
|
3
|
+
/**
|
4
|
+
* Preparing svg loader for `icons`
|
5
|
+
* Note we must be put all *.svg into folder `icons`
|
6
|
+
*/
|
7
|
+
export const ruleSvgIcon = () => {
|
8
|
+
const loader = {
|
9
|
+
test(resource) {
|
10
|
+
return isIconSvg(resource);
|
11
|
+
},
|
12
|
+
use: [
|
13
|
+
{
|
14
|
+
// FIXME: we need to always keep the directory structures here to make sure correct loader path resolve.
|
15
|
+
loader: getDirname(import.meta.url, '../../loaders/loader-icon.cjs'),
|
16
|
+
options: {
|
17
|
+
svgo: {
|
18
|
+
plugins: [{ name: 'removeTitle' }, { name: 'removeDimensions' }],
|
19
|
+
},
|
20
|
+
},
|
21
|
+
},
|
22
|
+
],
|
23
|
+
};
|
24
|
+
return loader;
|
25
|
+
};
|
@@ -1 +1,10 @@
|
|
1
|
-
import{ICON_PATH_REGEX}from
|
1
|
+
import { ICON_PATH_REGEX } from './constants.js';
|
2
|
+
/**
|
3
|
+
* Causeof we expose a component <Icon /> from `@wove/react` it can be optimized via icon-loader.
|
4
|
+
* limitation assets match `svg-icons/**\/*.svg` to icon loader resolver.
|
5
|
+
* @param resource
|
6
|
+
* @returns
|
7
|
+
*/
|
8
|
+
export const isIconSvg = (resource) => {
|
9
|
+
return ICON_PATH_REGEX.test(resource) && resource.endsWith('.svg');
|
10
|
+
};
|
@@ -1 +1 @@
|
|
1
|
-
export{};
|
1
|
+
export {};
|