@flatjs/evolve 1.8.1-next.66 → 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 +20 -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
@@ -3,10 +3,18 @@ export declare const defaultHtmlPluginConfig: Required<MultiHtmlCDNEntryItem>;
|
|
3
3
|
type Json = undefined | null | boolean | number | string | Json[] | {
|
4
4
|
[prop: string]: Json;
|
5
5
|
};
|
6
|
+
export type HtmlPluginConfigConfigData = {
|
7
|
+
mode: 'development' | 'production';
|
8
|
+
/**
|
9
|
+
* The random `cdn` for config via `env` template
|
10
|
+
*/
|
11
|
+
envCdn: string;
|
12
|
+
};
|
13
|
+
export type HtmlPluginConfigTokenType<T extends Json> = T | ((configData: HtmlPluginConfigConfigData) => T);
|
6
14
|
/**
|
7
15
|
* 获取html plugin 模版相关定义字段.
|
8
16
|
* @param preferredValue 用户首选的值, 如果返回为undefined, 将使用默认值
|
9
17
|
* @returns
|
10
18
|
*/
|
11
|
-
export declare const getHtmlPluginConfig: <T extends Json>(key: keyof typeof defaultHtmlPluginConfig,
|
19
|
+
export declare const getHtmlPluginConfig: <T extends Json>(key: keyof typeof defaultHtmlPluginConfig, configData: HtmlPluginConfigConfigData, preferredValue?: HtmlPluginConfigTokenType<T> | undefined) => T;
|
12
20
|
export {};
|
@@ -1 +1,47 @@
|
|
1
|
-
import{polyfill,viewportScripts}from
|
1
|
+
import { polyfill, viewportScripts } from '../constants.js';
|
2
|
+
import { getPackageDir } from './get-pacakge-dir.js';
|
3
|
+
export const defaultHtmlPluginConfig = {
|
4
|
+
// The page title
|
5
|
+
title: '',
|
6
|
+
// The page favicon url地址
|
7
|
+
favicon: '',
|
8
|
+
// The customized html tags should be inject to `<header />`
|
9
|
+
headBeforeHtmlTags: [],
|
10
|
+
// Allow us customized inline scripts into compiled html template.
|
11
|
+
inlineScripts: [],
|
12
|
+
// The ordered styles will be injected start of html head.
|
13
|
+
headBeforeStyles: [],
|
14
|
+
// The ordered scripts will be injected before html head.
|
15
|
+
headBeforeScripts: [...polyfill],
|
16
|
+
// The ordered scripts will be injected end of html body.
|
17
|
+
bodyAfterScripts: [],
|
18
|
+
// `allowPx2rem` default is true
|
19
|
+
viewport: viewportScripts,
|
20
|
+
// avoid use cdn `me`, `dev`, `ntv`
|
21
|
+
excludeCdnEnvs: ['me', 'dev', 'ntv'],
|
22
|
+
// `minify` is true, `dev` always don't minify.
|
23
|
+
htmlMinify: true,
|
24
|
+
// Default use It must be an absolute path.
|
25
|
+
templatePath: getPackageDir('templates/html-plugin/index-{0}.html'),
|
26
|
+
};
|
27
|
+
/**
|
28
|
+
* 获取html plugin 模版相关定义字段.
|
29
|
+
* @param preferredValue 用户首选的值, 如果返回为undefined, 将使用默认值
|
30
|
+
* @returns
|
31
|
+
*/
|
32
|
+
export const getHtmlPluginConfig = (key, configData, preferredValue) => {
|
33
|
+
let userValue;
|
34
|
+
if (typeof preferredValue !== 'undefined') {
|
35
|
+
userValue =
|
36
|
+
typeof preferredValue === 'function'
|
37
|
+
? preferredValue(configData)
|
38
|
+
: preferredValue;
|
39
|
+
}
|
40
|
+
if (typeof userValue === 'undefined') {
|
41
|
+
const defaultValue = defaultHtmlPluginConfig[key];
|
42
|
+
return typeof defaultValue === 'function'
|
43
|
+
? defaultValue(configData)
|
44
|
+
: defaultValue;
|
45
|
+
}
|
46
|
+
return userValue;
|
47
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const getMaxProcessTasks: (totalTasks: number, maxProcesses?: string | number) => number;
|
@@ -0,0 +1,7 @@
|
|
1
|
+
import { cpus } from 'node:os';
|
2
|
+
export const getMaxProcessTasks = (totalTasks, maxProcesses) => {
|
3
|
+
const maxCpu = Math.max(1, typeof maxProcesses === 'string' && maxProcesses.endsWith('%')
|
4
|
+
? Math.round((cpus().length * Number(maxProcesses.slice(0, -1))) / 100)
|
5
|
+
: Number(maxProcesses));
|
6
|
+
return totalTasks > maxCpu ? maxCpu : totalTasks;
|
7
|
+
};
|
@@ -1 +1,13 @@
|
|
1
|
-
import{join}from
|
1
|
+
import { join } from 'node:path';
|
2
|
+
import { getDirname } from '@armit/file-utility';
|
3
|
+
import { searchPackageDir } from '@armit/package';
|
4
|
+
export const getPackageDir = (...paths) => {
|
5
|
+
const dir = getDirname(import.meta.url);
|
6
|
+
const packageDir = searchPackageDir({
|
7
|
+
cwd: dir,
|
8
|
+
});
|
9
|
+
if (!packageDir) {
|
10
|
+
throw new Error('Could not resolve package root for `flatjs/evolve`');
|
11
|
+
}
|
12
|
+
return join(packageDir, ...paths);
|
13
|
+
};
|
package/dist/helpers/index.js
CHANGED
@@ -1 +1,15 @@
|
|
1
|
-
export*from
|
1
|
+
export * from './allow-px2rem-for-module.js';
|
2
|
+
export * from './assert-only-single-entry-item.js';
|
3
|
+
export * from './chunk-entry-map.js';
|
4
|
+
export * from './enable-bundle-hashname-for-module.js';
|
5
|
+
export * from './get-bundle-file-name.js';
|
6
|
+
export * from './get-html-plugin-config.js';
|
7
|
+
export * from './get-pacakge-dir.js';
|
8
|
+
export * from './merge-babel-options.js';
|
9
|
+
export * from './normalize-entry-map.js';
|
10
|
+
export * from './open-page.js';
|
11
|
+
export * from './print-log.js';
|
12
|
+
export * from './refresh-evolve-mock-options.js';
|
13
|
+
export * from './script-injects.js';
|
14
|
+
export * from './should-enable-react-fast-refresh.js';
|
15
|
+
export * from './split-to-multi-compiler.js';
|
@@ -1 +1,45 @@
|
|
1
|
-
import{logger,requireResolve}from
|
1
|
+
import { logger, requireResolve } from '@flatjs/common';
|
2
|
+
import { reactBabelPreset, vueBabelPreset } from '@flatjs/evolve-preset-babel';
|
3
|
+
import babelMerge from 'babel-merge';
|
4
|
+
import { moduleName } from '../constants.js';
|
5
|
+
export const mergeBabelOption = (modularImports = [], options = { usePreset: 'react' }) => {
|
6
|
+
const babelImports = modularImports.map((importItem) => {
|
7
|
+
return [
|
8
|
+
requireResolve('babel-plugin-import'),
|
9
|
+
{
|
10
|
+
transformToDefaultImport: false,
|
11
|
+
libraryDirectory: 'dist',
|
12
|
+
...importItem,
|
13
|
+
},
|
14
|
+
importItem.libraryName,
|
15
|
+
];
|
16
|
+
});
|
17
|
+
const { usePreset = 'react', ...overrideBabelOption } = options;
|
18
|
+
const baseBabelOption = usePreset === 'react'
|
19
|
+
? reactBabelPreset()
|
20
|
+
: usePreset === 'vue'
|
21
|
+
? vueBabelPreset()
|
22
|
+
: reactBabelPreset();
|
23
|
+
let mergedBabelOption = {};
|
24
|
+
try {
|
25
|
+
mergedBabelOption = babelMerge(baseBabelOption, overrideBabelOption);
|
26
|
+
// babelMerge only the last one will be retained, since there are multiple `babel-plugin-import` plugins with the same plugin id.
|
27
|
+
// https://github.com/ant-design/babel-plugin-import
|
28
|
+
if (mergedBabelOption.plugins) {
|
29
|
+
mergedBabelOption.plugins.unshift(...babelImports);
|
30
|
+
}
|
31
|
+
else {
|
32
|
+
mergedBabelOption.plugins = babelImports;
|
33
|
+
}
|
34
|
+
}
|
35
|
+
catch (err) {
|
36
|
+
logger.error(err, moduleName);
|
37
|
+
}
|
38
|
+
const finalBabelOptions = {
|
39
|
+
...mergedBabelOption,
|
40
|
+
babelrc: false,
|
41
|
+
// Turns out the compact option is set to auto by default which removes "superfluous whitespace characters and line terminators [...] on input sizes >100KB".
|
42
|
+
compact: false,
|
43
|
+
};
|
44
|
+
return finalBabelOptions;
|
45
|
+
};
|
@@ -1 +1,38 @@
|
|
1
|
-
import
|
1
|
+
import { join } from 'node:path';
|
2
|
+
import _ from 'lodash';
|
3
|
+
/**
|
4
|
+
* Make sure that we have correct `virtualPath` for each webpack `entry`
|
5
|
+
* @param entryName the entryName defined via `flatjs-evolve.config.ts`.
|
6
|
+
* @param evolveOptions
|
7
|
+
* @returns
|
8
|
+
*/
|
9
|
+
export const normalizeEvolveEntryName = (entryName, projectVirtualPath) => {
|
10
|
+
const servedEntryName = entryName.replace(/^\//, '');
|
11
|
+
const virtualPath = projectVirtualPath.replace(/^\//, '');
|
12
|
+
const withVirtualPath = servedEntryName.startsWith(virtualPath);
|
13
|
+
// Make sure that we have correct `virtualPath` for each webpack `entry`
|
14
|
+
const finalEntryName = withVirtualPath
|
15
|
+
? servedEntryName
|
16
|
+
: join(virtualPath, servedEntryName);
|
17
|
+
return finalEntryName.replace(/\/$/, '');
|
18
|
+
};
|
19
|
+
/**
|
20
|
+
* Normalize flatjs.evolve entry map definition data.
|
21
|
+
* Merge default entry item configuration values.
|
22
|
+
* @param activedEntryMap actived entries
|
23
|
+
* @param definedEntryMap defined entries in flatjs.evolve.js
|
24
|
+
*/
|
25
|
+
export const normalizeEvolveEntryMap = (activedEntryMap = {}, definedEntryMap = {}) => {
|
26
|
+
const newActivedEntries = {};
|
27
|
+
for (const [entryKey, itemConfig] of Object.entries(definedEntryMap)) {
|
28
|
+
// Setup default entry options.
|
29
|
+
const defaultEntryItemConfig = {
|
30
|
+
options: {},
|
31
|
+
};
|
32
|
+
if (activedEntryMap[entryKey]) {
|
33
|
+
newActivedEntries[entryKey] = _.merge({}, defaultEntryItemConfig, itemConfig, activedEntryMap[entryKey]);
|
34
|
+
}
|
35
|
+
_.merge(itemConfig, defaultEntryItemConfig);
|
36
|
+
}
|
37
|
+
return newActivedEntries;
|
38
|
+
};
|
@@ -1 +1,15 @@
|
|
1
|
-
import opn from
|
1
|
+
import opn from 'better-opn';
|
2
|
+
/**
|
3
|
+
* A better opn. Reuse the same tab on Chrome for
|
4
|
+
* @example
|
5
|
+
* `http://xxx.domain.com:3001/pages`
|
6
|
+
* @param openUrl the page url try to open.
|
7
|
+
*/
|
8
|
+
export const openPage = (openUrl) => {
|
9
|
+
try {
|
10
|
+
opn(openUrl);
|
11
|
+
}
|
12
|
+
catch (err) {
|
13
|
+
console.warn(`Unable to open browser. If you are running in a headless environment\n`);
|
14
|
+
}
|
15
|
+
};
|
@@ -1 +1,49 @@
|
|
1
|
-
import{logger}from
|
1
|
+
import { logger } from '@flatjs/common';
|
2
|
+
import { moduleName } from '../constants.js';
|
3
|
+
export const printInfo = (message, silent = false) => {
|
4
|
+
if (!silent) {
|
5
|
+
logger.info(message, moduleName);
|
6
|
+
}
|
7
|
+
};
|
8
|
+
export const printError = (message) => {
|
9
|
+
logger.error(message, moduleName);
|
10
|
+
};
|
11
|
+
const formatCompilerError = (errors, formattedMessages = []) => {
|
12
|
+
if (!errors) {
|
13
|
+
return formattedMessages;
|
14
|
+
}
|
15
|
+
if (typeof errors === 'string') {
|
16
|
+
formattedMessages.push(errors);
|
17
|
+
}
|
18
|
+
else if (Array.isArray(errors)) {
|
19
|
+
for (const error of errors) {
|
20
|
+
formatCompilerError(error, formattedMessages);
|
21
|
+
}
|
22
|
+
}
|
23
|
+
else if (typeof errors === 'object') {
|
24
|
+
// Only need to show `stack` or `message`
|
25
|
+
const onlyOneMsg = errors.stack || errors.message;
|
26
|
+
delete errors.stack;
|
27
|
+
delete errors.message;
|
28
|
+
const newErrors = {
|
29
|
+
...errors,
|
30
|
+
_newMsg: onlyOneMsg,
|
31
|
+
};
|
32
|
+
for (const [, value] of Object.entries(newErrors)) {
|
33
|
+
formatCompilerError(value, formattedMessages);
|
34
|
+
}
|
35
|
+
}
|
36
|
+
return formattedMessages;
|
37
|
+
};
|
38
|
+
/**
|
39
|
+
* Do not use `logger` to print webpack compiler error, cause of it may have it's message formatting.
|
40
|
+
* @param errors
|
41
|
+
* @returns
|
42
|
+
*/
|
43
|
+
export const printCompilerError = (errors) => {
|
44
|
+
const newErrors = formatCompilerError(errors, []);
|
45
|
+
for (const message of newErrors) {
|
46
|
+
console.log(message);
|
47
|
+
}
|
48
|
+
return newErrors;
|
49
|
+
};
|
@@ -1 +1,23 @@
|
|
1
|
-
import{loadMockConfig}
|
1
|
+
import { loadMockConfig } from '@flatjs/mock';
|
2
|
+
import _ from 'lodash';
|
3
|
+
export const refreshEvolveMockOptions = async (projectCwd, evolveOptions, configLoaderOptions) => {
|
4
|
+
const devServer = evolveOptions.devServer;
|
5
|
+
const esmLoaderOptions = configLoaderOptions?.esmLoaderOptions;
|
6
|
+
const externals = esmLoaderOptions?.externals || [];
|
7
|
+
// Try to load mock configuration from `flatjs-mock.config.ts`
|
8
|
+
const newMockOptions = await loadMockConfig(projectCwd, (devServer?.mockOptions || {}), _.merge({}, configLoaderOptions, {
|
9
|
+
configFile: 'flatjs-mock',
|
10
|
+
esmLoaderOptions: {
|
11
|
+
// load `flatjs-mock.config.ts` it will always import { defineConfig } from `@flatjs/mock`
|
12
|
+
externals: [...externals, '@flatjs/mock'],
|
13
|
+
},
|
14
|
+
}));
|
15
|
+
// we always has `devServer` config node.
|
16
|
+
if (devServer) {
|
17
|
+
devServer.mockOptions = newMockOptions || {};
|
18
|
+
if (devServer.mockOptions && !devServer.mockOptions.https) {
|
19
|
+
devServer.mockOptions.https = devServer?.https;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
return evolveOptions;
|
23
|
+
};
|
@@ -1 +1,20 @@
|
|
1
|
-
import{fileWalk}from
|
1
|
+
import { fileWalk } from '@armit/file-utility';
|
2
|
+
import { arrayUnique } from '@flatjs/common';
|
3
|
+
/**
|
4
|
+
* Transform all entry files via `entryMap`
|
5
|
+
* @param projectCwd The project root directory
|
6
|
+
* @param entryMap The evolve entryMap definition
|
7
|
+
* @returns The absolute entry input files.
|
8
|
+
*/
|
9
|
+
export const resolveEntryMapInputFiles = async (projectCwd, entryMap) => {
|
10
|
+
const pattern = [];
|
11
|
+
for (const [, config] of Object.entries(entryMap)) {
|
12
|
+
const entries = config.entry.map((s) => s.replace(/.(?:js|jsx|tsx|ts)$/, '') + '.*');
|
13
|
+
pattern.push(...entries);
|
14
|
+
}
|
15
|
+
const walkPattern = arrayUnique(pattern);
|
16
|
+
return await fileWalk(walkPattern, {
|
17
|
+
cwd: projectCwd,
|
18
|
+
absolute: true,
|
19
|
+
});
|
20
|
+
};
|
@@ -1 +1,39 @@
|
|
1
|
-
export function httpUrlJoin(
|
1
|
+
export function httpUrlJoin(first = '', second = '') {
|
2
|
+
return first.replace(/\/$/, '') + '/' + second.replace(/^\//, '');
|
3
|
+
}
|
4
|
+
/**
|
5
|
+
* To extract the best matched CDN configuration url address, either use URL `query.env` or customize the `envRresolver`
|
6
|
+
* @param cdnConfig List of pre-configured cdn urls for each environment
|
7
|
+
* @param envResolver Get the specific environment variable by the currently requested host url address.
|
8
|
+
* @returns Returns the best matching address with a suffix (`/`)
|
9
|
+
*/
|
10
|
+
export function cdnFinder(cdnConfig, envResolver) {
|
11
|
+
// eslint-disable-next-line regexp/no-unused-capturing-group
|
12
|
+
const regex = /[?&]env(=([^&#]*)|&|#|$)/;
|
13
|
+
const locationHref = window.location.href;
|
14
|
+
const results = regex.exec(locationHref);
|
15
|
+
let env = results && results[2]
|
16
|
+
? decodeURIComponent(results[2].replace(/\+/g, ' '))
|
17
|
+
: 'prod';
|
18
|
+
// If we have customized cdn resolver using it first.
|
19
|
+
env = (envResolver && envResolver(locationHref)) || env;
|
20
|
+
const matchedCdnList = cdnConfig[env] || cdnConfig['prod'] || [];
|
21
|
+
const matchedCdn = matchedCdnList[Math.floor(Math.random() * matchedCdnList.length)];
|
22
|
+
// ensure has endfix slash
|
23
|
+
return matchedCdn.replace(/\/$/, '') + '/';
|
24
|
+
}
|
25
|
+
export function findEnvCdn(cdnConfig = {}, env = 'prod') {
|
26
|
+
const matchedCdnList = cdnConfig[env] || cdnConfig['prod'] || [];
|
27
|
+
return matchedCdnList[Math.floor(Math.random() * matchedCdnList.length)];
|
28
|
+
}
|
29
|
+
export function injectFederationScripts(cdnConfig, cdnResolver = function cdnResolver() {
|
30
|
+
return undefined;
|
31
|
+
}) {
|
32
|
+
return `window.evolveFetchMicroWidgets = function () {
|
33
|
+
var cdnConfig = ${JSON.stringify(cdnConfig)};
|
34
|
+
var cdnResolver = ${cdnResolver.toString()};
|
35
|
+
var cdnFinder = ${cdnFinder.toString()};
|
36
|
+
return (cdnFinder(cdnConfig, cdnResolver) || '').replace(/\\/$/, '');
|
37
|
+
}
|
38
|
+
`;
|
39
|
+
}
|
@@ -1 +1,8 @@
|
|
1
|
-
export const shouldEnableReactFastRefresh=(
|
1
|
+
export const shouldEnableReactFastRefresh = (serveMode, entryMapItem, evolveOptions) => {
|
2
|
+
const entryItemOption = entryMapItem[1];
|
3
|
+
const hasModuleFederation = !!entryItemOption.options?.moduleFederation;
|
4
|
+
// Inject `react-refresh` if we are using preset `react`
|
5
|
+
return (serveMode &&
|
6
|
+
evolveOptions.loaderOptions.babelOptions?.usePreset === 'react' &&
|
7
|
+
!hasModuleFederation);
|
8
|
+
};
|
@@ -1 +1,22 @@
|
|
1
|
-
import{mergeOptions}from
|
1
|
+
import { mergeOptions } from '@flatjs/common';
|
2
|
+
import { normalizeEvolveEntryName } from './normalize-entry-map.js';
|
3
|
+
/**
|
4
|
+
* Split the `webpack` to make sure that we have separated compiler process for each module
|
5
|
+
* @param webpackConfig `Omit<Configuration, 'entry'>` webpack final configuration
|
6
|
+
*/
|
7
|
+
export function splitToMultiCompilerConfigs(servedEntries, webpackConfig, evolveOptions) {
|
8
|
+
const result = [];
|
9
|
+
for (const [entryName, entryItem] of Object.entries(servedEntries)) {
|
10
|
+
// Make sure that we have correct `virtualPath` for each webpack `entry`
|
11
|
+
const normalizedEntryName = normalizeEvolveEntryName(entryName, evolveOptions.projectVirtualPath);
|
12
|
+
result.push({
|
13
|
+
[normalizedEntryName]: entryItem.entry,
|
14
|
+
});
|
15
|
+
}
|
16
|
+
return result.map((newEntry) => {
|
17
|
+
return mergeOptions(webpackConfig, {
|
18
|
+
name: Object.keys(newEntry)[0],
|
19
|
+
entry: newEntry,
|
20
|
+
});
|
21
|
+
});
|
22
|
+
}
|
package/dist/index.js
CHANGED
@@ -1 +1,5 @@
|
|
1
|
-
export*from
|
1
|
+
export * from './define-config/index.js';
|
2
|
+
export * from './load-config/index.js';
|
3
|
+
export * from './main/index.js';
|
4
|
+
export * from './types/types-options.js';
|
5
|
+
export * from './types/types-entry-map.js';
|
@@ -1 +1 @@
|
|
1
|
-
export*from
|
1
|
+
export * from './load-evolve-config.js';
|
@@ -1 +1,35 @@
|
|
1
|
-
import{mergeOptions,logger,searchConfig
|
1
|
+
import { mergeOptions, logger, searchConfig, } from '@flatjs/common';
|
2
|
+
import { configFileName, moduleName } from '../constants.js';
|
3
|
+
import { defaultEvolveOptions } from '../default-options.js';
|
4
|
+
import { refreshEvolveMockOptions } from '../helpers/refresh-evolve-mock-options.js';
|
5
|
+
export const loadEvolveConfig = async (configEnv, projectCwd, overrideOptions = {}, configLoaderOptions = {
|
6
|
+
configFile: configFileName,
|
7
|
+
esmLoaderOptions: {
|
8
|
+
externals: ['@flatjs/evolve', '@flatjs/mock'],
|
9
|
+
},
|
10
|
+
}) => {
|
11
|
+
const { configFile, esmLoaderOptions } = configLoaderOptions;
|
12
|
+
const data = await searchConfig(configFile, projectCwd, {
|
13
|
+
esm: {
|
14
|
+
...esmLoaderOptions,
|
15
|
+
projectCwd,
|
16
|
+
},
|
17
|
+
});
|
18
|
+
let localData = {};
|
19
|
+
if (typeof data?.config === 'function') {
|
20
|
+
localData = data?.config(configEnv);
|
21
|
+
}
|
22
|
+
else {
|
23
|
+
localData = data?.config || {};
|
24
|
+
}
|
25
|
+
// Merge user local config with default configure options.
|
26
|
+
const localConfigOptions = mergeOptions(defaultEvolveOptions, localData);
|
27
|
+
const mergedConfigOptions = mergeOptions(localConfigOptions, overrideOptions);
|
28
|
+
const finalData = mergeOptions(mergedConfigOptions, { projectCwd });
|
29
|
+
// We don't need to load mocks configuration from `flatjs-mock.config.js` while `build` phase.
|
30
|
+
const latestEvolveOptions = configEnv.command === 'build'
|
31
|
+
? finalData
|
32
|
+
: await refreshEvolveMockOptions(projectCwd, finalData, configLoaderOptions);
|
33
|
+
logger.debug(`Load evolve config:\n${JSON.stringify(latestEvolveOptions, null, 2)}`, moduleName);
|
34
|
+
return latestEvolveOptions;
|
35
|
+
};
|
package/dist/main/env-verify.js
CHANGED
@@ -1 +1,21 @@
|
|
1
|
-
import{illegalPackageChecker,keepPackageDepsUpToDateForNonMonoRepo}from
|
1
|
+
import { illegalPackageChecker, keepPackageDepsUpToDateForNonMonoRepo, } from '@armit/package';
|
2
|
+
export const envVerify = async (projectCwd, evolveOptions) => {
|
3
|
+
const { packageInstallChecker, needVerifyPackages } = evolveOptions;
|
4
|
+
if (packageInstallChecker !== false && packageInstallChecker?.enabled) {
|
5
|
+
// Verify local install node modules
|
6
|
+
await illegalPackageChecker({
|
7
|
+
cwd: projectCwd,
|
8
|
+
modules: packageInstallChecker?.detectModules,
|
9
|
+
throwError: packageInstallChecker?.throwError,
|
10
|
+
showAllInstalledGraph: packageInstallChecker?.showAllInstalledGraph,
|
11
|
+
});
|
12
|
+
}
|
13
|
+
if (needVerifyPackages !== false) {
|
14
|
+
// Keep package deps up to date for non-monorepo
|
15
|
+
await keepPackageDepsUpToDateForNonMonoRepo({
|
16
|
+
cwd: projectCwd,
|
17
|
+
autoUpgrade: true,
|
18
|
+
needVerifyPackages: needVerifyPackages || {},
|
19
|
+
});
|
20
|
+
}
|
21
|
+
};
|
package/dist/main/index.js
CHANGED
@@ -1 +1,4 @@
|
|
1
|
-
export*from
|
1
|
+
export * from './start-build.js';
|
2
|
+
export * from './start-serve.js';
|
3
|
+
export * from './start-static.js';
|
4
|
+
export * from './start-build-dynamic.js';
|
@@ -1,13 +1,9 @@
|
|
1
|
-
import { type
|
1
|
+
import { type EntryMapItem } from '../types/types-entry-map.js';
|
2
2
|
import { type FlatEvolveOptions } from '../types/types-options.js';
|
3
|
-
|
4
|
-
name?: string;
|
5
|
-
warningStats?: unknown;
|
6
|
-
};
|
3
|
+
import { type EvolveBuildResult } from './start-one-entry-build.js';
|
7
4
|
/**
|
8
5
|
* The main entry to start an evolve `build`
|
9
|
-
* @param
|
6
|
+
* @param entryMapItem The `entryMapItem` for one entry build task
|
10
7
|
* @param evolveOptions FlatEvolveOptions
|
11
|
-
* @param clearCache The value indicates if we need to clear webpack cache resources.
|
12
8
|
*/
|
13
|
-
export declare const prepareBuild: (
|
9
|
+
export declare const prepareBuild: (entryMapItem: EntryMapItem, evolveOptions: FlatEvolveOptions) => Promise<EvolveBuildResult>;
|
@@ -1 +1,38 @@
|
|
1
|
-
import{
|
1
|
+
import { ensureSlash, mergeOptions } from '@flatjs/common';
|
2
|
+
import { EvolveBuildError } from '../errors/evolve-build-error.js';
|
3
|
+
import { printCompilerError } from '../helpers/print-log.js';
|
4
|
+
import { startOneEntryBuild, } from './start-one-entry-build.js';
|
5
|
+
/**
|
6
|
+
* The main entry to start an evolve `build`
|
7
|
+
* @param entryMapItem The `entryMapItem` for one entry build task
|
8
|
+
* @param evolveOptions FlatEvolveOptions
|
9
|
+
*/
|
10
|
+
export const prepareBuild = async (entryMapItem, evolveOptions) => {
|
11
|
+
const [entryKey, entryConfig] = entryMapItem;
|
12
|
+
// Fetch all configuration cdn
|
13
|
+
const cdnPath = evolveOptions.multiHtmlCdn?.prod || [];
|
14
|
+
if (!cdnPath.length) {
|
15
|
+
throw new Error(`No CDN config for env:"prod", moduleName: ${entryKey}`);
|
16
|
+
}
|
17
|
+
// Random choose one to publicPath
|
18
|
+
const cdnPublicPath = ensureSlash(cdnPath[Math.floor(Math.random() * cdnPath.length)], true);
|
19
|
+
// Construct single entry map item to build.
|
20
|
+
const toBuildEntryMapItem = {
|
21
|
+
[entryKey]: entryConfig,
|
22
|
+
};
|
23
|
+
try {
|
24
|
+
const useRelativeAssetPath = entryConfig.options?.useRelativeAssetPath;
|
25
|
+
const buildEvolveOptions = mergeOptions(evolveOptions, {
|
26
|
+
webpack: {
|
27
|
+
// Only for `assets` used at styling files (e.g.`xxx.less`)
|
28
|
+
publicPath: useRelativeAssetPath ? 'auto' : cdnPublicPath,
|
29
|
+
},
|
30
|
+
});
|
31
|
+
return await startOneEntryBuild(toBuildEntryMapItem, buildEvolveOptions);
|
32
|
+
}
|
33
|
+
catch (err) {
|
34
|
+
const formattedErrors = printCompilerError(err);
|
35
|
+
// Need re-throw error, in order to third API can capture this error.
|
36
|
+
throw new EvolveBuildError(`BUILD_ERROR`, formattedErrors);
|
37
|
+
}
|
38
|
+
};
|
@@ -1 +1,36 @@
|
|
1
|
-
import{urlJoin}from
|
1
|
+
import { urlJoin } from '@flatjs/common';
|
2
|
+
import { attachMockMiddlewares } from '@flatjs/mock';
|
3
|
+
import { createAppPageRoute, createDevServer, createDevServerCompilerTasks, createDevServerEntries, } from '../dev-server/index.js';
|
4
|
+
import { openPage } from '../helpers/index.js';
|
5
|
+
import { envVerify } from './env-verify.js';
|
6
|
+
/**
|
7
|
+
* The main entry to start evolve serve
|
8
|
+
* @param projectCwd The Root directory (workspace) of this project.
|
9
|
+
* @param servedEntries All normalized webpack entries we have served.
|
10
|
+
* @param evolveOptions FlatEvolveOptions
|
11
|
+
*/
|
12
|
+
export const prepareServe = async (projectCwd, servedEntries, evolveOptions) => {
|
13
|
+
// Verify if we have an correct project local environment.
|
14
|
+
await envVerify(projectCwd, evolveOptions);
|
15
|
+
// Create pure dev server.
|
16
|
+
const { app, devPort, devHostUri } = await createDevServer(evolveOptions);
|
17
|
+
// Attach core handlers for mock
|
18
|
+
await attachMockMiddlewares(app, {
|
19
|
+
...evolveOptions.devServer?.mockOptions,
|
20
|
+
projectCwd,
|
21
|
+
});
|
22
|
+
// Create dev-server configurationn for all servedEntries.
|
23
|
+
const servedDevServerEntries = await createDevServerEntries(devPort, servedEntries, evolveOptions);
|
24
|
+
// Create new route `/pages*`,`*` to pure dev server
|
25
|
+
createAppPageRoute(projectCwd, app, devHostUri, servedDevServerEntries, evolveOptions);
|
26
|
+
const mainPage = urlJoin(devHostUri, ['/pages']);
|
27
|
+
// Open page via browser
|
28
|
+
if (evolveOptions.devServer?.autoOpen) {
|
29
|
+
openPage(mainPage);
|
30
|
+
}
|
31
|
+
// Create dev-server compiler tasks
|
32
|
+
const serveTasks = await createDevServerCompilerTasks(projectCwd, mainPage, servedDevServerEntries, evolveOptions);
|
33
|
+
return Promise.all(serveTasks).then(() => {
|
34
|
+
return app;
|
35
|
+
});
|
36
|
+
};
|
@@ -1 +1,28 @@
|
|
1
|
-
import{chalk,logger,urlJoin}from
|
1
|
+
import { chalk, logger, urlJoin } from '@flatjs/common';
|
2
|
+
import { attachMockMiddlewares } from '@flatjs/mock';
|
3
|
+
import { createAppPageRoute } from '../dev-server/create-app-page-route.js';
|
4
|
+
import { createDevServer } from '../dev-server/create-dev-server.js';
|
5
|
+
import { openPage } from '../helpers/open-page.js';
|
6
|
+
/**
|
7
|
+
* The main entry to start evolve serve
|
8
|
+
* @param projectCwd The Root directory (workspace) of this project.
|
9
|
+
* @param evolveOptions FlatEvolveOptions
|
10
|
+
*/
|
11
|
+
export const prepareStatic = async (projectCwd, evolveOptions) => {
|
12
|
+
// Create pure dev server.
|
13
|
+
const { app, devHostUri } = await createDevServer(evolveOptions);
|
14
|
+
// Attach core handlers for mock
|
15
|
+
await attachMockMiddlewares(app, {
|
16
|
+
...evolveOptions.devServer?.mockOptions,
|
17
|
+
projectCwd,
|
18
|
+
});
|
19
|
+
// Create new route `/pages*`,`*` to pure dev server
|
20
|
+
createAppPageRoute(projectCwd, app, devHostUri, {}, evolveOptions);
|
21
|
+
const mainPage = urlJoin(devHostUri, ['/pages']);
|
22
|
+
// Open page via browser
|
23
|
+
if (evolveOptions.devServer?.autoOpen) {
|
24
|
+
openPage(mainPage);
|
25
|
+
}
|
26
|
+
logger.info(`${'static page'.padEnd(12, ' ')} ➩ ${chalk(['cyan'])(mainPage)}`);
|
27
|
+
};
|
28
|
+
// Start up main page proxy server.
|