@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
@@ -1,6 +1,7 @@
|
|
1
1
|
import { type PartialDeep } from 'type-fest';
|
2
2
|
import { type ConfigLoaderOptions } from '../load-config/load-evolve-config.js';
|
3
3
|
import { type FlatEvolveOptions } from '../types/types-options.js';
|
4
|
+
import { type EvolveBuildResult } from './start-one-entry-build.js';
|
4
5
|
export declare function getBuildEntryFiles(projectCwd: string, diffFiles: string[], allEntryInputs: string[]): Promise<string[]>;
|
5
6
|
/**
|
6
7
|
* Dynamic check which entry modules need to build.
|
@@ -16,4 +17,4 @@ export declare function dynamicCheckBuildEntryMap(projectCwd: string, earlyCommi
|
|
16
17
|
* @param earlyCommit The diff based earlier commit hash
|
17
18
|
* @param lastCommit If is omitted, it will have the same effect as using HEAD instead.
|
18
19
|
*/
|
19
|
-
export declare const startDynamicBuild: (projectCwd: string, earlyCommit?: string, lastCommit?: string, overrideEvolveOptions?: PartialDeep<FlatEvolveOptions>, configLoaderOptions?: ConfigLoaderOptions) => Promise<
|
20
|
+
export declare const startDynamicBuild: (projectCwd: string, earlyCommit?: string, lastCommit?: string, overrideEvolveOptions?: PartialDeep<FlatEvolveOptions>, configLoaderOptions?: ConfigLoaderOptions) => Promise<EvolveBuildResult[]>;
|
@@ -1 +1,144 @@
|
|
1
|
-
import
|
1
|
+
import { isAbsolute, join } from 'node:path';
|
2
|
+
import { pathToFileURL } from 'node:url';
|
3
|
+
import { getDirname } from '@armit/file-utility';
|
4
|
+
import { getDiffFiles, getCommitIdOfBranch } from '@armit/git';
|
5
|
+
import { createThreadPool } from '@armit/worker-threads';
|
6
|
+
import { arraysIntersect, chalk, logger } from '@flatjs/common';
|
7
|
+
import { traverseGraph } from '@flatjs/graph';
|
8
|
+
import Listr from 'listr';
|
9
|
+
import { filterActivedEntriesByEntryInputs, filterActivedEntriesByModule, } from '../helpers/filter-actived-entries.js';
|
10
|
+
import { getGitRoot } from '../helpers/get-git-root.js';
|
11
|
+
import { getMaxProcessTasks } from '../helpers/get-max-process-tasks.js';
|
12
|
+
import { resolveEntryMapInputFiles } from '../helpers/resolve-entry-map-input-files.js';
|
13
|
+
import { loadEvolveConfig, } from '../load-config/load-evolve-config.js';
|
14
|
+
import { envVerify } from './env-verify.js';
|
15
|
+
export async function getBuildEntryFiles(projectCwd, diffFiles, allEntryInputs) {
|
16
|
+
const toBuildEntryFiles = [];
|
17
|
+
const entryInputsPendingToCheck = [];
|
18
|
+
for (const entryInput of allEntryInputs) {
|
19
|
+
// If entry have been existed in diff files, need to rebuild.
|
20
|
+
if (diffFiles.includes(entryInput)) {
|
21
|
+
toBuildEntryFiles.push(entryInput);
|
22
|
+
}
|
23
|
+
else {
|
24
|
+
entryInputsPendingToCheck.push(entryInput);
|
25
|
+
}
|
26
|
+
}
|
27
|
+
// If there has pedding entry inputs to check.
|
28
|
+
if (entryInputsPendingToCheck.length) {
|
29
|
+
const graphDeps = await traverseGraph({
|
30
|
+
input: entryInputsPendingToCheck,
|
31
|
+
projectCwd,
|
32
|
+
treeNodeFilter: () => true,
|
33
|
+
});
|
34
|
+
if (!graphDeps) {
|
35
|
+
return toBuildEntryFiles;
|
36
|
+
}
|
37
|
+
logger.debug(`DependencyGraph:\n${JSON.stringify(graphDeps, null, 2)}`);
|
38
|
+
for (const entryInputToCheck of entryInputsPendingToCheck) {
|
39
|
+
const dependsFiles = graphDeps[entryInputToCheck] || [];
|
40
|
+
if (arraysIntersect(dependsFiles, diffFiles)) {
|
41
|
+
toBuildEntryFiles.push(entryInputToCheck);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
return toBuildEntryFiles;
|
46
|
+
}
|
47
|
+
/**
|
48
|
+
* Dynamic check which entry modules need to build.
|
49
|
+
* @returns
|
50
|
+
*/
|
51
|
+
export async function dynamicCheckBuildEntryMap(projectCwd, earlyCommit, lastCommit, overrideEvolveOptions, configLoaderOptions) {
|
52
|
+
const command = {
|
53
|
+
command: 'build',
|
54
|
+
};
|
55
|
+
// 1. Try to load evolve configuration from `flatjs-evolve.config.ts`
|
56
|
+
const newEvolveOptions = await loadEvolveConfig(command, projectCwd, overrideEvolveOptions, configLoaderOptions);
|
57
|
+
// 2. Check if we have fixed build modules.
|
58
|
+
if (newEvolveOptions.ci?.fixedBuildModules &&
|
59
|
+
newEvolveOptions.ci?.fixedBuildModules.length) {
|
60
|
+
logger.info('Use `fixedBuildModules` configuration to build...');
|
61
|
+
const buildEntries = filterActivedEntriesByModule(newEvolveOptions.entryMap, newEvolveOptions.ci?.fixedBuildModules);
|
62
|
+
return { buildEntries, newEvolveOptions };
|
63
|
+
}
|
64
|
+
logger.info('Dynamicly checking code changed modules ...');
|
65
|
+
// 3. Resolve diff files based on specificed branch.
|
66
|
+
// Check if we have fixed `early commit` if no resolve based on `Branch` from evolve config file.
|
67
|
+
if (!earlyCommit) {
|
68
|
+
const basedBranch = newEvolveOptions.ci?.basedBranch || 'master';
|
69
|
+
// Try resolve based branch commit hash.
|
70
|
+
logger.info(`Resolving base branch "${basedBranch}" commit hash ...`);
|
71
|
+
earlyCommit = await getCommitIdOfBranch(basedBranch);
|
72
|
+
}
|
73
|
+
// `packages/evolve/tests/main/fixtures/src/home/index.ts` without repo cwd.
|
74
|
+
let diffFiles = earlyCommit
|
75
|
+
? await getDiffFiles(earlyCommit, lastCommit)
|
76
|
+
: [];
|
77
|
+
const gitRoot = getGitRoot(projectCwd);
|
78
|
+
if (!gitRoot) {
|
79
|
+
throw new Error(`No .git root (${projectCwd}) found`);
|
80
|
+
}
|
81
|
+
// Hack diff files with git repo root dir.
|
82
|
+
diffFiles = diffFiles.map((diffFile) => {
|
83
|
+
return isAbsolute(diffFile) ? diffFile : join(gitRoot, diffFile);
|
84
|
+
});
|
85
|
+
logger.debug(`Diff files: \n${JSON.stringify(diffFiles, null, 2)}`);
|
86
|
+
// No code changed here.
|
87
|
+
if (!diffFiles.length) {
|
88
|
+
logger.warn('It seems that there are no code files changed.');
|
89
|
+
return {
|
90
|
+
buildEntries: {},
|
91
|
+
newEvolveOptions,
|
92
|
+
};
|
93
|
+
}
|
94
|
+
// 4. Resolve entry input files.
|
95
|
+
const allEntryInputs = await resolveEntryMapInputFiles(projectCwd, newEvolveOptions.entryMap);
|
96
|
+
// 5. Flag changed entries (with absolute filepath)
|
97
|
+
const toBuildEntryFiles = await getBuildEntryFiles(projectCwd, diffFiles, allEntryInputs);
|
98
|
+
logger.debug(`To build entry files: \n${JSON.stringify(toBuildEntryFiles, null, 2)}`);
|
99
|
+
// 6. Filter entry map items which need to build.
|
100
|
+
const buildEntries = await filterActivedEntriesByEntryInputs(projectCwd, newEvolveOptions.entryMap, toBuildEntryFiles);
|
101
|
+
return { buildEntries, newEvolveOptions };
|
102
|
+
}
|
103
|
+
/**
|
104
|
+
* The main entry to start an evolve `build` with automatically detect modules which have been changed between two commits.
|
105
|
+
* @param projectCwd The Root directory (workspace) of this project.
|
106
|
+
* @param earlyCommit The diff based earlier commit hash
|
107
|
+
* @param lastCommit If is omitted, it will have the same effect as using HEAD instead.
|
108
|
+
*/
|
109
|
+
export const startDynamicBuild = async (projectCwd, earlyCommit, lastCommit, overrideEvolveOptions = {}, configLoaderOptions) => {
|
110
|
+
// 1. Fetch all changed files betwwen two `commit`
|
111
|
+
const { buildEntries, newEvolveOptions } = await dynamicCheckBuildEntryMap(projectCwd, earlyCommit, lastCommit, overrideEvolveOptions, configLoaderOptions);
|
112
|
+
await envVerify(projectCwd, newEvolveOptions);
|
113
|
+
const buildEntryKeys = Object.keys(buildEntries);
|
114
|
+
// Make sure that we have at least one build entry module.
|
115
|
+
if (!buildEntryKeys.length) {
|
116
|
+
logger.warn(`No build entries providered!`);
|
117
|
+
return [];
|
118
|
+
}
|
119
|
+
logger.info(`Start dynamic build:\n${JSON.stringify({ buildEntries: buildEntryKeys }, null, 2)}`);
|
120
|
+
const workerSize = getMaxProcessTasks(buildEntryKeys.length, newEvolveOptions.maxProcesses);
|
121
|
+
const workerPath = pathToFileURL(getDirname(import.meta.url, './start-build-worker.js')).toString();
|
122
|
+
const worker = await createThreadPool(workerPath, {
|
123
|
+
size: workerSize,
|
124
|
+
});
|
125
|
+
const buildTasks = new Listr([], {
|
126
|
+
concurrent: true,
|
127
|
+
exitOnError: true,
|
128
|
+
});
|
129
|
+
const buildResults = [];
|
130
|
+
for (const [entryKey] of Object.entries(buildEntries)) {
|
131
|
+
buildTasks.add({
|
132
|
+
title: `Build module ${chalk(['magenta'])(entryKey)} ...`,
|
133
|
+
task: async () => {
|
134
|
+
const buildResult = await worker.startBuildWorker(projectCwd, entryKey, overrideEvolveOptions, configLoaderOptions);
|
135
|
+
buildResults.push(buildResult);
|
136
|
+
},
|
137
|
+
});
|
138
|
+
}
|
139
|
+
if (buildTasks.tasks.length) {
|
140
|
+
await buildTasks.run();
|
141
|
+
}
|
142
|
+
worker.pool.terminate();
|
143
|
+
return buildResults;
|
144
|
+
};
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { type PartialDeep } from 'type-fest';
|
2
|
+
import { type ConfigLoaderOptions } from '../load-config/load-evolve-config.js';
|
3
|
+
import { type FlatEvolveOptions } from '../types/types-options.js';
|
4
|
+
import { type EvolveBuildResult } from './start-one-entry-build.js';
|
5
|
+
/**
|
6
|
+
* FIXME: The main entry to start an evolve `build`, NOTE: avoid pass configuration with `function` here.
|
7
|
+
* If you need to call build api avoid `worker` you can directly call `prepareBuild`
|
8
|
+
* @internal
|
9
|
+
* @param projectCwd The Root directory (workspace) of this project.
|
10
|
+
* @param entryKey The `entryKey` for one entry build task
|
11
|
+
* @param overrideEvolveOptions The overrided evolve options, NOTE: avoid pass configuration with `function` here.
|
12
|
+
* @param configLoaderOptions Evolve config loader options, NOTE: avoid pass configuration with `function` here.
|
13
|
+
*/
|
14
|
+
export declare const startBuildWorker: (projectCwd: string, entryKey: string, overrideEvolveOptions?: PartialDeep<FlatEvolveOptions>, configLoaderOptions?: ConfigLoaderOptions) => Promise<EvolveBuildResult>;
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import { filterActivedEntriesByModule } from '../helpers/filter-actived-entries.js';
|
2
|
+
import { normalizeEvolveEntryMap } from '../helpers/normalize-entry-map.js';
|
3
|
+
import { loadEvolveConfig, } from '../load-config/load-evolve-config.js';
|
4
|
+
import { prepareBuild } from './prepare-build.js';
|
5
|
+
/**
|
6
|
+
* FIXME: The main entry to start an evolve `build`, NOTE: avoid pass configuration with `function` here.
|
7
|
+
* If you need to call build api avoid `worker` you can directly call `prepareBuild`
|
8
|
+
* @internal
|
9
|
+
* @param projectCwd The Root directory (workspace) of this project.
|
10
|
+
* @param entryKey The `entryKey` for one entry build task
|
11
|
+
* @param overrideEvolveOptions The overrided evolve options, NOTE: avoid pass configuration with `function` here.
|
12
|
+
* @param configLoaderOptions Evolve config loader options, NOTE: avoid pass configuration with `function` here.
|
13
|
+
*/
|
14
|
+
export const startBuildWorker = async (projectCwd, entryKey, overrideEvolveOptions = {}, configLoaderOptions) => {
|
15
|
+
const command = {
|
16
|
+
command: 'build',
|
17
|
+
};
|
18
|
+
// Try to load evolve configuration from `flatjs-evolve.config.ts`
|
19
|
+
// FIXME: Cause of `worker-theads` do not support pass configuration with `function` reference.
|
20
|
+
const newEvolveOptions = await loadEvolveConfig(command, projectCwd, overrideEvolveOptions, configLoaderOptions);
|
21
|
+
// FIXME: Cause of `worker threads` we need avoid pass entryItem config directly
|
22
|
+
// because we have some config node item with `function`
|
23
|
+
// It will break `worker threads` comunication, e.g below shown.
|
24
|
+
// DataCloneError: function (url) {
|
25
|
+
// if (url.indexOf('dev.flatjs.com') > 0) return 'me';
|
26
|
+
// if (url.indexOf('.qa.') > 0) retur...<omitted>... } could not be cloned.
|
27
|
+
// at new DOMException (node:internal/per_context/domexception:53:5)
|
28
|
+
// So we need to re cacalculate the build entry via `entryKey`
|
29
|
+
const buildOneEntry = filterActivedEntriesByModule(newEvolveOptions.entryMap, [
|
30
|
+
// Make sure that the entryKey is correct match.
|
31
|
+
new RegExp(`^${entryKey}$`),
|
32
|
+
]);
|
33
|
+
const buildEntryKeys = Object.keys(buildOneEntry);
|
34
|
+
// Make sure that we have at least one build entry module.
|
35
|
+
if (!buildEntryKeys.length) {
|
36
|
+
throw new Error(`No build entry resolved via "${entryKey}" on "startBuildWorker"!`);
|
37
|
+
}
|
38
|
+
const normalizedBuildOneEntry = normalizeEvolveEntryMap(buildOneEntry, newEvolveOptions.entryMap);
|
39
|
+
const buildEntryConfig = normalizedBuildOneEntry[entryKey];
|
40
|
+
return prepareBuild([entryKey, buildEntryConfig], newEvolveOptions);
|
41
|
+
};
|
@@ -1,12 +1,5 @@
|
|
1
1
|
import { type PartialDeep } from 'type-fest';
|
2
2
|
import { type ConfigLoaderOptions } from '../load-config/load-evolve-config.js';
|
3
3
|
import { type FlatEvolveOptions } from '../types/types-options.js';
|
4
|
-
import { type EvolveBuildResult } from './
|
5
|
-
/**
|
6
|
-
* The main entry to start an evolve `build`
|
7
|
-
* @param projectCwd The Root directory (workspace) of this project.
|
8
|
-
* @param buildModules The filter pattern to detect modules we want to build.
|
9
|
-
* @param overrideEvolveOptions The overrided evolve options
|
10
|
-
* @param configLoaderOptions Evolve config loader options
|
11
|
-
*/
|
4
|
+
import { type EvolveBuildResult } from './start-one-entry-build.js';
|
12
5
|
export declare const startBuild: (projectCwd: string, buildModules: string[], overrideEvolveOptions?: PartialDeep<FlatEvolveOptions>, configLoaderOptions?: ConfigLoaderOptions) => Promise<EvolveBuildResult[]>;
|
package/dist/main/start-build.js
CHANGED
@@ -1 +1,49 @@
|
|
1
|
-
import
|
1
|
+
import { pathToFileURL } from 'node:url';
|
2
|
+
import { getDirname } from '@armit/file-utility';
|
3
|
+
import { createThreadPool } from '@armit/worker-threads';
|
4
|
+
import { chalk, logger } from '@flatjs/common';
|
5
|
+
import Listr from 'listr';
|
6
|
+
import { filterActivedEntriesByModule } from '../helpers/filter-actived-entries.js';
|
7
|
+
import { getMaxProcessTasks } from '../helpers/get-max-process-tasks.js';
|
8
|
+
import { loadEvolveConfig, } from '../load-config/load-evolve-config.js';
|
9
|
+
import { envVerify } from './env-verify.js';
|
10
|
+
export const startBuild = async (projectCwd, buildModules, overrideEvolveOptions = {}, configLoaderOptions) => {
|
11
|
+
const command = {
|
12
|
+
command: 'build',
|
13
|
+
};
|
14
|
+
// Try to load evolve configuration from `flatjs-evolve.config.ts`
|
15
|
+
const newEvolveOptions = await loadEvolveConfig(command, projectCwd, overrideEvolveOptions, configLoaderOptions);
|
16
|
+
await envVerify(projectCwd, newEvolveOptions);
|
17
|
+
const buildEntries = filterActivedEntriesByModule(newEvolveOptions.entryMap, buildModules);
|
18
|
+
const buildEntryKeys = Object.keys(buildEntries);
|
19
|
+
// Make sure that we have at least one build entry module.
|
20
|
+
if (!buildEntryKeys.length) {
|
21
|
+
logger.warn(`No build entries providered!`);
|
22
|
+
return [];
|
23
|
+
}
|
24
|
+
logger.info(`Start standard build:\n${JSON.stringify({ buildEntries: buildEntryKeys }, null, 2)}`);
|
25
|
+
const workerSize = getMaxProcessTasks(buildEntryKeys.length, newEvolveOptions.maxProcesses);
|
26
|
+
const workerPath = pathToFileURL(getDirname(import.meta.url, './start-build-worker.js')).toString();
|
27
|
+
const worker = await createThreadPool(workerPath, {
|
28
|
+
size: workerSize,
|
29
|
+
});
|
30
|
+
const buildTasks = new Listr([], {
|
31
|
+
concurrent: true,
|
32
|
+
exitOnError: true,
|
33
|
+
});
|
34
|
+
const buildResults = [];
|
35
|
+
for (const [entryKey] of Object.entries(buildEntries)) {
|
36
|
+
buildTasks.add({
|
37
|
+
title: `Build module ${chalk(['magenta'])(entryKey)} ...`,
|
38
|
+
task: async () => {
|
39
|
+
const buildResult = await worker.startBuildWorker(projectCwd, entryKey, overrideEvolveOptions, configLoaderOptions);
|
40
|
+
buildResults.push(buildResult);
|
41
|
+
},
|
42
|
+
});
|
43
|
+
}
|
44
|
+
if (buildTasks.tasks.length) {
|
45
|
+
await buildTasks.run();
|
46
|
+
}
|
47
|
+
worker.pool.terminate();
|
48
|
+
return buildResults;
|
49
|
+
};
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { type EvolveEntryMap } from '../types/types-entry-map.js';
|
2
|
+
import { type FlatEvolveOptions } from '../types/types-options.js';
|
3
|
+
export type EvolveBuildResult = {
|
4
|
+
name?: string;
|
5
|
+
warningStats?: unknown;
|
6
|
+
};
|
7
|
+
/**
|
8
|
+
* The helpers to build one entry at a time
|
9
|
+
* @param singleBuildEntry The single entry
|
10
|
+
* @param buildPublicPath
|
11
|
+
* @param evolveOptions
|
12
|
+
*/
|
13
|
+
export declare const startOneEntryBuild: (singleBuildEntry: EvolveEntryMap, evolveOptions: FlatEvolveOptions) => Promise<EvolveBuildResult>;
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import webpack from 'webpack';
|
2
|
+
import { loadWebpackConfig } from '../create-webpack/load-webpack-config.js';
|
3
|
+
import { splitToMultiCompilerConfigs } from '../helpers/split-to-multi-compiler.js';
|
4
|
+
/**
|
5
|
+
* The helpers to build one entry at a time
|
6
|
+
* @param singleBuildEntry The single entry
|
7
|
+
* @param buildPublicPath
|
8
|
+
* @param evolveOptions
|
9
|
+
*/
|
10
|
+
export const startOneEntryBuild = async (singleBuildEntry, evolveOptions) => {
|
11
|
+
// Try to load webpack configuration
|
12
|
+
const webpackConfig = await loadWebpackConfig('production', singleBuildEntry, evolveOptions);
|
13
|
+
const compilerConfigs = splitToMultiCompilerConfigs(singleBuildEntry, webpackConfig, evolveOptions);
|
14
|
+
if (compilerConfigs.length > 1) {
|
15
|
+
throw new Error('startOneEntryBuild() only support `compiler` at a time');
|
16
|
+
}
|
17
|
+
const currCompiler = compilerConfigs[0];
|
18
|
+
// Run the single build.
|
19
|
+
return new Promise((resolve, reject) => {
|
20
|
+
webpack(currCompiler, (err, stats) => {
|
21
|
+
if (err) {
|
22
|
+
// Handle errors here
|
23
|
+
return reject(err);
|
24
|
+
}
|
25
|
+
const statsJson = stats?.toJson();
|
26
|
+
if (statsJson?.errors?.length) {
|
27
|
+
return reject(statsJson.errors);
|
28
|
+
}
|
29
|
+
if (evolveOptions.rejectWarnings && statsJson?.warnings?.length) {
|
30
|
+
return reject(statsJson.warnings);
|
31
|
+
}
|
32
|
+
resolve({ name: currCompiler.name, warningStats: statsJson?.warnings });
|
33
|
+
});
|
34
|
+
});
|
35
|
+
};
|
package/dist/main/start-serve.js
CHANGED
@@ -1 +1,32 @@
|
|
1
|
-
import{logger}from
|
1
|
+
import { logger } from '@flatjs/common';
|
2
|
+
import { filterActivedEntriesByModule } from '../helpers/filter-actived-entries.js';
|
3
|
+
import { normalizeEvolveEntryMap } from '../helpers/normalize-entry-map.js';
|
4
|
+
import { loadEvolveConfig, } from '../load-config/load-evolve-config.js';
|
5
|
+
import { prepareServe } from './prepare-serve.js';
|
6
|
+
/**
|
7
|
+
* The main entry to start evolve serve
|
8
|
+
* @param projectCwd The Root directory (workspace) of this project.
|
9
|
+
* @param serveModules The filter pattern to detect modules we want to serve.
|
10
|
+
* @param overrideEvolveOptions The overrided evolve options
|
11
|
+
* @param configLoaderOptions Evolve config loader options
|
12
|
+
*/
|
13
|
+
export const startServe = async (projectCwd, serveModules, overrideEvolveOptions = {}, configLoaderOptions) => {
|
14
|
+
const command = {
|
15
|
+
command: 'serve',
|
16
|
+
};
|
17
|
+
// Try to load evolve configuration from `flatjs-evolve.config.ts`
|
18
|
+
const evolveOptions = await loadEvolveConfig(command, projectCwd, overrideEvolveOptions, configLoaderOptions);
|
19
|
+
const servedEntries = filterActivedEntriesByModule(evolveOptions.entryMap, serveModules);
|
20
|
+
const servedEntryKeys = Object.keys(servedEntries);
|
21
|
+
// Make sure that we have at least one serve entry module.
|
22
|
+
if (!servedEntryKeys.length) {
|
23
|
+
logger.warn(`No served entries providered!`);
|
24
|
+
return [];
|
25
|
+
}
|
26
|
+
logger.info({
|
27
|
+
servedEntries: servedEntryKeys,
|
28
|
+
});
|
29
|
+
// Normalized served entries to make sure we have latested entry options.
|
30
|
+
const normalizedServedEntries = normalizeEvolveEntryMap(servedEntries, evolveOptions.entryMap);
|
31
|
+
return prepareServe(projectCwd, normalizedServedEntries, evolveOptions);
|
32
|
+
};
|
@@ -1 +1,16 @@
|
|
1
|
-
import{loadEvolveConfig}from
|
1
|
+
import { loadEvolveConfig, } from '../load-config/load-evolve-config.js';
|
2
|
+
import { prepareStatic } from './prepare-static.js';
|
3
|
+
/**
|
4
|
+
* The main entry to start evolve static server to proxy all modules of `production` build
|
5
|
+
* @param projectCwd The Root directory (workspace) of this project.
|
6
|
+
* @param overrideEvolveOptions The overrided evolve options
|
7
|
+
* @param configLoaderOptions Evolve config loader options
|
8
|
+
*/
|
9
|
+
export const startStatic = async (projectCwd, overrideEvolveOptions = {}, configLoaderOptions) => {
|
10
|
+
const command = {
|
11
|
+
command: 'static',
|
12
|
+
};
|
13
|
+
// Try to load evolve configuration from `flatjs-evolve.config.ts`
|
14
|
+
const evolveOptions = await loadEvolveConfig(command, projectCwd, overrideEvolveOptions, configLoaderOptions);
|
15
|
+
return prepareStatic(projectCwd, evolveOptions);
|
16
|
+
};
|
@@ -1 +1,25 @@
|
|
1
|
-
import{logger}from
|
1
|
+
import { logger } from '@flatjs/common';
|
2
|
+
import { moduleName } from '../constants.js';
|
3
|
+
import { printInfo } from '../helpers/print-log.js';
|
4
|
+
import { imageMinimizer } from './image-minimizer.js';
|
5
|
+
import { terserMinimizer } from './terser-minimizer.js';
|
6
|
+
export const createMinimizers = (serveMode, webpackOptions) => {
|
7
|
+
const minimizers = [];
|
8
|
+
if (serveMode) {
|
9
|
+
logger.debug('Ignore minimizer plugin for `serve` mode', moduleName);
|
10
|
+
return minimizers;
|
11
|
+
}
|
12
|
+
if (webpackOptions?.minimizer === false) {
|
13
|
+
printInfo('Note `minimizer` has been disabled for now');
|
14
|
+
return minimizers;
|
15
|
+
}
|
16
|
+
if (webpackOptions?.minimizer?.imageMin) {
|
17
|
+
const imageMinPlugin = imageMinimizer();
|
18
|
+
if (imageMinPlugin) {
|
19
|
+
minimizers.push(imageMinPlugin);
|
20
|
+
}
|
21
|
+
}
|
22
|
+
const terserPlugin = terserMinimizer(webpackOptions?.minimizer?.terserOptions || {});
|
23
|
+
minimizers.push(terserPlugin);
|
24
|
+
return minimizers;
|
25
|
+
};
|
@@ -1 +1,14 @@
|
|
1
|
-
export const defaultTerserOptions=
|
1
|
+
export const defaultTerserOptions = {
|
2
|
+
ecma: undefined,
|
3
|
+
parse: {},
|
4
|
+
compress: {},
|
5
|
+
// Note `mangle.properties` is `false` by default.
|
6
|
+
mangle: true,
|
7
|
+
module: false,
|
8
|
+
output: undefined,
|
9
|
+
toplevel: false,
|
10
|
+
ie8: false,
|
11
|
+
keep_classnames: undefined,
|
12
|
+
keep_fnames: false,
|
13
|
+
safari10: false,
|
14
|
+
};
|
@@ -1 +1,56 @@
|
|
1
|
-
import{projectHasYarn}from
|
1
|
+
import { projectHasYarn } from '@armit/package';
|
2
|
+
import { chalk, logger, requireResolve } from '@flatjs/common';
|
3
|
+
import ImageMinimizerPlugin from 'image-minimizer-webpack-plugin';
|
4
|
+
import { moduleName } from '../constants.js';
|
5
|
+
const logs = new Map();
|
6
|
+
/**
|
7
|
+
* brew install libpng
|
8
|
+
* brew install gifsicle
|
9
|
+
* @returns
|
10
|
+
*/
|
11
|
+
export const imageMinimizer = () => {
|
12
|
+
const suggestedPlugins = [
|
13
|
+
// Svgo configuration here https://github.com/svg/svgo#configuration
|
14
|
+
['svgo', {}],
|
15
|
+
['gifsicle', {}],
|
16
|
+
['jpegtran', {}],
|
17
|
+
['pngquant', {}],
|
18
|
+
];
|
19
|
+
const logMessage = [];
|
20
|
+
const availabledPlugins = suggestedPlugins
|
21
|
+
.map((item) => {
|
22
|
+
const moduleId = item[0];
|
23
|
+
try {
|
24
|
+
requireResolve(`imagemin-${moduleId}`);
|
25
|
+
return item;
|
26
|
+
}
|
27
|
+
catch (err) {
|
28
|
+
if (!logs.get(moduleId)) {
|
29
|
+
logs.set(moduleId, true);
|
30
|
+
const command = chalk(['magenta'])(`"${projectHasYarn() ? 'yarn add' : 'npm install'} imagemin-${moduleId} -D"`);
|
31
|
+
logMessage.push(`Execute ${command} for assets optimization`);
|
32
|
+
}
|
33
|
+
return null;
|
34
|
+
}
|
35
|
+
})
|
36
|
+
.filter(Boolean);
|
37
|
+
if (logMessage.length) {
|
38
|
+
for (const msg of logMessage) {
|
39
|
+
logger.warn(msg, moduleName);
|
40
|
+
}
|
41
|
+
}
|
42
|
+
if (availabledPlugins.length) {
|
43
|
+
return new ImageMinimizerPlugin({
|
44
|
+
minimizer: {
|
45
|
+
// Recommended squoosh options for lossless optimization
|
46
|
+
implementation: ImageMinimizerPlugin.imageminMinify,
|
47
|
+
options: {
|
48
|
+
// Lossless optimization with custom option
|
49
|
+
// Feel free to experiment with options for better result for you
|
50
|
+
plugins: availabledPlugins,
|
51
|
+
},
|
52
|
+
},
|
53
|
+
});
|
54
|
+
}
|
55
|
+
return null;
|
56
|
+
};
|
package/dist/minimizer/index.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export*from
|
1
|
+
export * from './create-minimizers.js';
|
@@ -1,3 +1,15 @@
|
|
1
|
-
import{mergeOptions}from
|
2
|
-
|
3
|
-
|
1
|
+
import { mergeOptions } from '@flatjs/common';
|
2
|
+
import TerserPlugin from 'terser-webpack-plugin';
|
3
|
+
import { defaultTerserOptions } from './default-options.js';
|
4
|
+
/**
|
5
|
+
* https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
|
6
|
+
*/
|
7
|
+
export const terserMinimizer = (terserOptions) => {
|
8
|
+
return new TerserPlugin({
|
9
|
+
parallel: true,
|
10
|
+
// Disable Extract all or some (use /^\**!|@preserve|@license|@cc_on/i RegExp) comments.
|
11
|
+
extractComments: false,
|
12
|
+
// Terser minify options.
|
13
|
+
terserOptions: mergeOptions(defaultTerserOptions, terserOptions),
|
14
|
+
});
|
15
|
+
};
|
package/dist/minimizer/types.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export{};
|
1
|
+
export {};
|