@flatjs/evolve 2.1.0-next.11 → 2.1.0-next.12
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/constants.js +36 -1
- package/dist/create-webpack/create-externals.js +6 -1
- package/dist/create-webpack/create-optimization.js +43 -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 +37 -1
- package/dist/create-webpack/create-rule-sets.js +20 -1
- package/dist/create-webpack/load-webpack-config.js +57 -1
- package/dist/create-webpack/resolve-public-path.js +15 -1
- package/dist/create-webpack/rule-sets/constants.js +3 -1
- package/dist/create-webpack/rule-sets/rule-assets.js +52 -1
- package/dist/create-webpack/rule-sets/rule-css.js +111 -1
- package/dist/create-webpack/rule-sets/rule-less.js +44 -1
- package/dist/create-webpack/rule-sets/rule-scripts.js +34 -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 +83 -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 +58 -1
- package/dist/dev-server/create-app-page-route.js +13 -1
- package/dist/dev-server/create-dev-server-compiler-task.js +55 -1
- package/dist/dev-server/create-dev-server-entries.js +25 -1
- package/dist/dev-server/create-dev-server.js +24 -1
- package/dist/dev-server/index.js +6 -1
- package/dist/dev-server/middlewares/create-page-middleware.js +33 -1
- package/dist/dev-server/middlewares/create-public-assets-middleware.js +25 -1
- package/dist/dev-server/middlewares/get-all-sorted-modules.js +24 -1
- package/dist/dev-server/middlewares/get-bundle-asset.js +7 -1
- package/dist/dev-server/middlewares/get-dev-server-host-uri.js +5 -1
- package/dist/dev-server/middlewares/get-hmr-runtime-chunks.js +14 -1
- package/dist/dev-server/middlewares/get-normalized-entry-name.js +14 -1
- package/dist/dev-server/middlewares/get-page-main-html.js +49 -1
- package/dist/dev-server/middlewares/get-page-module-html.js +123 -1
- package/dist/dev-server/middlewares/get-project-virtual-path.js +3 -1
- package/dist/dev-server/middlewares/get-runtime-manifest.js +25 -1
- package/dist/dev-server/middlewares/index.js +2 -1
- package/dist/dev-server/middlewares/types.js +1 -1
- package/dist/errors/evolve-build-error.js +10 -1
- package/dist/helpers/allow-px2rem-for-module.js +6 -1
- package/dist/helpers/assert-group-entry-item.js +19 -1
- package/dist/helpers/assert-single-compiler.js +45 -1
- package/dist/helpers/chunk-entry-map.js +21 -1
- package/dist/helpers/delete-object-keys.js +20 -1
- package/dist/helpers/enable-bundle-hashname-for-module.js +6 -1
- package/dist/helpers/filter-actived-entries.js +42 -1
- package/dist/helpers/flat-entry-map.js +11 -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.js +47 -1
- package/dist/helpers/get-max-process-tasks.js +7 -1
- package/dist/helpers/get-pacakge-dir.js +13 -1
- package/dist/helpers/get-runtime-cdn-base.js +21 -1
- package/dist/helpers/index.js +27 -1
- package/dist/helpers/is-deep-equal.js +67 -1
- package/dist/helpers/json-serializer.js +52 -1
- package/dist/helpers/merge-babel-options.js +45 -1
- package/dist/helpers/normalize-check-entry-options.js +28 -1
- package/dist/helpers/normalize-entry-map.js +59 -1
- package/dist/helpers/normalize-group-name.js +16 -1
- package/dist/helpers/normalize-page-proxy.js +9 -1
- package/dist/helpers/normalize-resolve-alias.js +7 -1
- package/dist/helpers/normalize-template-inject-tokens.js +22 -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 +34 -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 +14 -1
- package/dist/helpers/split-to-entry-group.js +139 -1
- package/dist/helpers/verify-group-entry-options.js +21 -1
- package/dist/index.js +5 -1
- package/dist/load-config/index.js +1 -1
- package/dist/load-config/load-evolve-config.js +41 -1
- package/dist/load-config/types.js +1 -1
- package/dist/main/create-thread-worker.js +51 -1
- package/dist/main/env-verify.js +21 -1
- package/dist/main/get-worker-path.js +5 -1
- package/dist/main/index.js +4 -1
- package/dist/main/prepare-build.js +39 -1
- package/dist/main/prepare-serve.js +69 -1
- package/dist/main/prepare-static.js +30 -1
- package/dist/main/start-build-dynamic.js +171 -1
- package/dist/main/start-build-worker.js +44 -1
- package/dist/main/start-build.js +69 -1
- package/dist/main/start-group-entry-build.js +32 -1
- package/dist/main/start-serve.js +34 -1
- package/dist/main/start-static.js +19 -1
- package/dist/minimizer/create-minimizers.js +25 -1
- package/dist/minimizer/default-options.js +14 -1
- package/dist/minimizer/image-minimizer.js +65 -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/circular-dependency/circular-dependency-plugin.js +119 -1
- package/dist/plugins/circular-dependency/index.js +15 -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 +28 -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 +100 -1
- package/dist/plugins/multi-html/index.js +16 -1
- package/dist/plugins/multi-html/multi-html-cdn-plugin.js +83 -1
- package/dist/plugins/multi-html/multi-html-plugin.js +65 -1
- package/dist/plugins/ts-checker/index.js +1 -1
- package/dist/plugins/ts-checker/ts-checker-plugin.js +24 -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.d.ts +30 -3
- package/dist/types/types-loader-options.js +1 -1
- package/dist/types/types-modular-import.js +1 -1
- 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-threads-options.js +1 -1
- package/dist/types/types-webpack.js +1 -1
- package/package.json +2 -2
package/dist/main/start-serve.js
CHANGED
@@ -1 +1,34 @@
|
|
1
|
-
import{logger,requireResolve}from
|
1
|
+
import { logger, requireResolve } 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
|
+
projectCwd,
|
16
|
+
command: 'serve',
|
17
|
+
resolve: requireResolve,
|
18
|
+
};
|
19
|
+
// Try to load evolve configuration from `flatjs-evolve.config.ts`
|
20
|
+
const evolveOptions = await loadEvolveConfig(command, projectCwd, overrideEvolveOptions, configLoaderOptions);
|
21
|
+
const servedEntries = filterActivedEntriesByModule(evolveOptions.entryMap, serveModules);
|
22
|
+
const servedEntryKeys = Object.keys(servedEntries);
|
23
|
+
// Make sure that we have at least one serve entry module.
|
24
|
+
if (!servedEntryKeys.length) {
|
25
|
+
logger.warn(`No served entries providered!`);
|
26
|
+
return [];
|
27
|
+
}
|
28
|
+
logger.info({
|
29
|
+
servedEntries: servedEntryKeys,
|
30
|
+
});
|
31
|
+
// Normalized served entries to make sure we have latested entry options.
|
32
|
+
const normalizedServedEntries = normalizeEvolveEntryMap(servedEntries, evolveOptions.entryMap);
|
33
|
+
return prepareServe(projectCwd, normalizedServedEntries, evolveOptions);
|
34
|
+
};
|
@@ -1 +1,19 @@
|
|
1
|
-
import{requireResolve}from
|
1
|
+
import { requireResolve } from '@flatjs/common';
|
2
|
+
import { loadEvolveConfig } from '../load-config/load-evolve-config.js';
|
3
|
+
import { prepareStatic } from './prepare-static.js';
|
4
|
+
/**
|
5
|
+
* The main entry to start evolve static server to proxy all modules of `production` build
|
6
|
+
* @param projectCwd The Root directory (workspace) of this project.
|
7
|
+
* @param overrideEvolveOptions The overrided evolve options
|
8
|
+
* @param configLoaderOptions Evolve config loader options
|
9
|
+
*/
|
10
|
+
export const startStatic = async (projectCwd, overrideEvolveOptions = {}, configLoaderOptions) => {
|
11
|
+
const command = {
|
12
|
+
projectCwd,
|
13
|
+
command: 'static',
|
14
|
+
resolve: requireResolve,
|
15
|
+
};
|
16
|
+
// Try to load evolve configuration from `flatjs-evolve.config.ts`
|
17
|
+
const evolveOptions = await loadEvolveConfig(command, projectCwd, overrideEvolveOptions, configLoaderOptions);
|
18
|
+
return prepareStatic(projectCwd, evolveOptions);
|
19
|
+
};
|
@@ -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,65 @@
|
|
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
|
+
* Install libpng library & gifsicle tool
|
8
|
+
* macos
|
9
|
+
* =====================
|
10
|
+
* brew install libpng
|
11
|
+
* brew install gifsicle
|
12
|
+
*
|
13
|
+
* centos
|
14
|
+
* =====================
|
15
|
+
* sudo yum install libpng
|
16
|
+
* sudo yum install epel-release
|
17
|
+
* sudo yum install gifsicle
|
18
|
+
* @returns
|
19
|
+
*/
|
20
|
+
export const imageMinimizer = () => {
|
21
|
+
const suggestedPlugins = [
|
22
|
+
// Svgo configuration here https://github.com/svg/svgo#configuration
|
23
|
+
['svgo', {}],
|
24
|
+
['gifsicle', {}],
|
25
|
+
['jpegtran', {}],
|
26
|
+
['pngquant', {}],
|
27
|
+
];
|
28
|
+
const logMessage = [];
|
29
|
+
const availabledPlugins = suggestedPlugins
|
30
|
+
.map((item) => {
|
31
|
+
const moduleId = item[0];
|
32
|
+
try {
|
33
|
+
requireResolve(import.meta.url, `imagemin-${moduleId}`);
|
34
|
+
return item;
|
35
|
+
}
|
36
|
+
catch (err) {
|
37
|
+
if (!logs.get(moduleId)) {
|
38
|
+
logs.set(moduleId, true);
|
39
|
+
const command = chalk(['magenta'])(`"${projectHasYarn() ? 'yarn add' : 'npm install'} imagemin-${moduleId} -D"`);
|
40
|
+
logMessage.push(`Execute ${command} for assets optimization`);
|
41
|
+
}
|
42
|
+
return null;
|
43
|
+
}
|
44
|
+
})
|
45
|
+
.filter(Boolean);
|
46
|
+
if (logMessage.length) {
|
47
|
+
for (const msg of logMessage) {
|
48
|
+
logger.warn(msg, moduleName);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
if (availabledPlugins.length) {
|
52
|
+
return new ImageMinimizerPlugin({
|
53
|
+
minimizer: {
|
54
|
+
// Recommended squoosh options for lossless optimization
|
55
|
+
implementation: ImageMinimizerPlugin.imageminMinify,
|
56
|
+
options: {
|
57
|
+
// Lossless optimization with custom option
|
58
|
+
// Feel free to experiment with options for better result for you
|
59
|
+
plugins: availabledPlugins,
|
60
|
+
},
|
61
|
+
},
|
62
|
+
});
|
63
|
+
}
|
64
|
+
return null;
|
65
|
+
};
|
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 {};
|
@@ -1 +1,119 @@
|
|
1
|
-
import
|
1
|
+
import { relative } from 'node:path';
|
2
|
+
import { mergeOptions } from '@flatjs/common';
|
3
|
+
import Graph from 'tarjan-graph';
|
4
|
+
import webpack from 'webpack';
|
5
|
+
const BASE_ERROR = 'Circular dependency detected:\r\n';
|
6
|
+
const PLUGIN_TITLE = `CircularDependencyPlugin`;
|
7
|
+
export class CircularDependencyPlugin {
|
8
|
+
constructor(options = {}) {
|
9
|
+
this.options = mergeOptions({
|
10
|
+
exclude: /node_modules/,
|
11
|
+
include: /.*/,
|
12
|
+
failOnError: false,
|
13
|
+
allowAsyncCycles: false,
|
14
|
+
projectCwd: process.cwd(),
|
15
|
+
}, options);
|
16
|
+
}
|
17
|
+
apply(compiler) {
|
18
|
+
const cwd = this.options.projectCwd;
|
19
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity
|
20
|
+
compiler.hooks.compilation.tap(PLUGIN_TITLE, (compilation) => {
|
21
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity
|
22
|
+
compilation.hooks.optimizeModules.tap(PLUGIN_TITLE, (modules) => {
|
23
|
+
if (this.options.onStart) {
|
24
|
+
this.options.onStart({ compilation });
|
25
|
+
}
|
26
|
+
const dependencyGraph = new (Graph.default || Graph)();
|
27
|
+
for (const module of modules) {
|
28
|
+
// Iterate over the current modules dependencies
|
29
|
+
const dependedModuleIds = [];
|
30
|
+
for (const dependency of module.dependencies) {
|
31
|
+
if (dependency.constructor &&
|
32
|
+
dependency.constructor.name === 'CommonJsSelfReferenceDependency') {
|
33
|
+
continue;
|
34
|
+
}
|
35
|
+
let depModule = null;
|
36
|
+
if (compilation.moduleGraph) {
|
37
|
+
// handle getting a module for webpack 5
|
38
|
+
depModule = compilation.moduleGraph.getModule(dependency);
|
39
|
+
}
|
40
|
+
else {
|
41
|
+
// handle getting a module for webpack 4
|
42
|
+
depModule = dependency.module;
|
43
|
+
}
|
44
|
+
if (!depModule) {
|
45
|
+
continue;
|
46
|
+
}
|
47
|
+
// ignore dependencies that don't have an associated resource
|
48
|
+
if (!(depModule instanceof webpack.NormalModule) ||
|
49
|
+
!depModule.resource) {
|
50
|
+
continue;
|
51
|
+
}
|
52
|
+
// optionally ignore dependencies that are resolved asynchronously
|
53
|
+
if (this.options.allowAsyncCycles && dependency.weak) {
|
54
|
+
continue;
|
55
|
+
}
|
56
|
+
// the dependency was resolved to the current module due to how webpack internals
|
57
|
+
// setup dependencies like CommonJsSelfReferenceDependency and ModuleDecoratorDependency
|
58
|
+
if (module === depModule) {
|
59
|
+
continue;
|
60
|
+
}
|
61
|
+
dependedModuleIds.push(depModule.identifier());
|
62
|
+
}
|
63
|
+
dependencyGraph.add(module.identifier(), dependedModuleIds);
|
64
|
+
}
|
65
|
+
const cycles = dependencyGraph.getCycles();
|
66
|
+
this.isCyclic(cycles, compilation, cwd);
|
67
|
+
if (this.options.onEnd) {
|
68
|
+
this.options.onEnd({ compilation });
|
69
|
+
}
|
70
|
+
});
|
71
|
+
});
|
72
|
+
}
|
73
|
+
isCyclic(cycles, compilation, cwd) {
|
74
|
+
cycles.forEach((vertices) => {
|
75
|
+
// Convert the array of vertices into an array of module paths
|
76
|
+
const cyclicAbsolutePaths = vertices
|
77
|
+
.slice()
|
78
|
+
.reverse()
|
79
|
+
.map((vertex) => {
|
80
|
+
const module = compilation.findModule(vertex.name);
|
81
|
+
if (!(module instanceof webpack.NormalModule)) {
|
82
|
+
return null;
|
83
|
+
}
|
84
|
+
return module.resource || null;
|
85
|
+
});
|
86
|
+
if (cyclicAbsolutePaths.every((resource) => !resource ||
|
87
|
+
this.options.exclude.test(resource) ||
|
88
|
+
!this.options.include.test(resource))) {
|
89
|
+
// If all modules in the cycle are excluded by the config, don't report an error
|
90
|
+
return;
|
91
|
+
}
|
92
|
+
const cyclicPaths = cyclicAbsolutePaths.map((resource) => relative(cwd, resource));
|
93
|
+
// allow consumers to override all behavior with onDetected
|
94
|
+
if (this.options.onDetected) {
|
95
|
+
try {
|
96
|
+
this.options.onDetected({
|
97
|
+
paths: cyclicPaths.concat([cyclicPaths[0]]),
|
98
|
+
compilation: compilation,
|
99
|
+
});
|
100
|
+
}
|
101
|
+
catch (err) {
|
102
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
103
|
+
compilation.errors.push(err);
|
104
|
+
}
|
105
|
+
return;
|
106
|
+
}
|
107
|
+
// mark warnings or errors on webpack compilation
|
108
|
+
const error = new Error(BASE_ERROR.concat(cyclicPaths.concat([cyclicPaths[0]]).join(' -> ')));
|
109
|
+
if (this.options.failOnError) {
|
110
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
111
|
+
compilation.errors.push(error);
|
112
|
+
}
|
113
|
+
else {
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
115
|
+
compilation.warnings.push(error);
|
116
|
+
}
|
117
|
+
});
|
118
|
+
}
|
119
|
+
}
|
@@ -1 +1,15 @@
|
|
1
|
-
import{CircularDependencyPlugin}from
|
1
|
+
import { CircularDependencyPlugin } from './circular-dependency-plugin.js';
|
2
|
+
/**
|
3
|
+
* Detect modules with circular dependencies when bundling with webpack for `development` mode.
|
4
|
+
* @returns
|
5
|
+
*/
|
6
|
+
export const createCircularDependencyPlugin = (serveMode, evolveOptions) => {
|
7
|
+
if (!serveMode) {
|
8
|
+
return [];
|
9
|
+
}
|
10
|
+
return [
|
11
|
+
new CircularDependencyPlugin({
|
12
|
+
projectCwd: evolveOptions.projectCwd,
|
13
|
+
}),
|
14
|
+
];
|
15
|
+
};
|
@@ -1 +1,173 @@
|
|
1
|
-
import
|
1
|
+
import { rmSync } from 'node:fs';
|
2
|
+
import { relative } from 'node:path';
|
3
|
+
import { fileWalkSync } from '@armit/file-utility';
|
4
|
+
import { logger } from '@flatjs/common';
|
5
|
+
import { moduleName } from '../../constants.js';
|
6
|
+
export class CleanWebpackPlugin {
|
7
|
+
constructor(options = {}) {
|
8
|
+
this.verbose = options.verbose === true || false;
|
9
|
+
this.projectCwd = options.projectCwd || process.cwd();
|
10
|
+
this.cleanStaleWebpackAssets =
|
11
|
+
options.cleanStaleWebpackAssets === true ||
|
12
|
+
options.cleanStaleWebpackAssets === false
|
13
|
+
? options.cleanStaleWebpackAssets
|
14
|
+
: true;
|
15
|
+
this.protectWebpackAssets =
|
16
|
+
options.protectWebpackAssets === true ||
|
17
|
+
options.protectWebpackAssets === false
|
18
|
+
? options.protectWebpackAssets
|
19
|
+
: true;
|
20
|
+
this.cleanAfterEveryBuildPatterns = Array.isArray(options.cleanAfterEveryBuildPatterns)
|
21
|
+
? options.cleanAfterEveryBuildPatterns
|
22
|
+
: [];
|
23
|
+
this.cleanOnceBeforeBuildPatterns = Array.isArray(options.cleanOnceBeforeBuildPatterns)
|
24
|
+
? options.cleanOnceBeforeBuildPatterns
|
25
|
+
: ['**/*'];
|
26
|
+
/**
|
27
|
+
* Store webpack build assets
|
28
|
+
*/
|
29
|
+
this.currentAssets = [];
|
30
|
+
/**
|
31
|
+
* Only used with cleanOnceBeforeBuildPatterns
|
32
|
+
*/
|
33
|
+
this.initialClean = false;
|
34
|
+
this.outputPath = '';
|
35
|
+
this.apply = this.apply.bind(this);
|
36
|
+
this.handleInitial = this.handleInitial.bind(this);
|
37
|
+
this.handleDone = this.handleDone.bind(this);
|
38
|
+
this.removeFiles = this.removeFiles.bind(this);
|
39
|
+
}
|
40
|
+
apply(compiler) {
|
41
|
+
if (!compiler.options.output || !compiler.options.output.path) {
|
42
|
+
logger.warn('clean-webpack-plugin: options.output.path not defined. Plugin disabled...', moduleName);
|
43
|
+
return;
|
44
|
+
}
|
45
|
+
this.outputPath = compiler.options.output.path;
|
46
|
+
/**
|
47
|
+
* webpack 4+ comes with a new plugin system.
|
48
|
+
*
|
49
|
+
* Check for hooks in-order to support old plugin system
|
50
|
+
*/
|
51
|
+
const hooks = compiler.hooks;
|
52
|
+
if (this.cleanOnceBeforeBuildPatterns.length !== 0) {
|
53
|
+
hooks.emit.tap('clean-webpack-plugin', (compilation) => {
|
54
|
+
this.handleInitial(compilation);
|
55
|
+
});
|
56
|
+
}
|
57
|
+
hooks.done.tap('clean-webpack-plugin', (stats) => {
|
58
|
+
this.handleDone(stats);
|
59
|
+
});
|
60
|
+
}
|
61
|
+
/**
|
62
|
+
* Initially remove files from output directory prior to build.
|
63
|
+
*
|
64
|
+
* Only happens once.
|
65
|
+
*
|
66
|
+
* Warning: It is recommended to initially clean your build directory outside of webpack to minimize unexpected behavior.
|
67
|
+
*/
|
68
|
+
handleInitial(compilation) {
|
69
|
+
if (this.initialClean) {
|
70
|
+
return;
|
71
|
+
}
|
72
|
+
/**
|
73
|
+
* Do not remove files if there are compilation errors
|
74
|
+
*
|
75
|
+
* Handle logging inside this.handleDone
|
76
|
+
*/
|
77
|
+
const stats = compilation.getStats();
|
78
|
+
if (stats.hasErrors()) {
|
79
|
+
return;
|
80
|
+
}
|
81
|
+
this.initialClean = true;
|
82
|
+
this.removeFiles(this.cleanOnceBeforeBuildPatterns);
|
83
|
+
}
|
84
|
+
handleDone(stats) {
|
85
|
+
/**
|
86
|
+
* Do nothing if there is a webpack error
|
87
|
+
*/
|
88
|
+
if (stats.hasErrors()) {
|
89
|
+
if (this.verbose) {
|
90
|
+
logger.warn('clean-webpack-plugin: pausing due to webpack errors', moduleName);
|
91
|
+
}
|
92
|
+
return;
|
93
|
+
}
|
94
|
+
/**
|
95
|
+
* Fetch Webpack's output asset files
|
96
|
+
*/
|
97
|
+
const assets = stats.toJson({
|
98
|
+
assets: true,
|
99
|
+
}).assets || [];
|
100
|
+
const assetList = assets.map((asset) => {
|
101
|
+
return asset.name;
|
102
|
+
});
|
103
|
+
/**
|
104
|
+
* Get all files that were in the previous build but not the current
|
105
|
+
*
|
106
|
+
* (relies on del's cwd: outputPath option)
|
107
|
+
*/
|
108
|
+
const staleFiles = this.currentAssets.filter((previousAsset) => {
|
109
|
+
return assetList.includes(previousAsset) === false;
|
110
|
+
});
|
111
|
+
/**
|
112
|
+
* Save assets for next compilation
|
113
|
+
*/
|
114
|
+
this.currentAssets = assetList.sort();
|
115
|
+
const removePatterns = [];
|
116
|
+
/**
|
117
|
+
* Remove unused webpack assets
|
118
|
+
*/
|
119
|
+
if (this.cleanStaleWebpackAssets === true && staleFiles.length !== 0) {
|
120
|
+
removePatterns.push(...staleFiles);
|
121
|
+
}
|
122
|
+
/**
|
123
|
+
* Remove cleanAfterEveryBuildPatterns
|
124
|
+
*/
|
125
|
+
if (this.cleanAfterEveryBuildPatterns.length !== 0) {
|
126
|
+
removePatterns.push(...this.cleanAfterEveryBuildPatterns);
|
127
|
+
}
|
128
|
+
if (removePatterns.length !== 0) {
|
129
|
+
this.removeFiles(removePatterns);
|
130
|
+
}
|
131
|
+
}
|
132
|
+
removeFiles(patterns) {
|
133
|
+
try {
|
134
|
+
const deleted = fileWalkSync(patterns, {
|
135
|
+
absolute: true,
|
136
|
+
unique: true,
|
137
|
+
// Change context to build directory
|
138
|
+
cwd: this.outputPath,
|
139
|
+
dot: true,
|
140
|
+
ignore: this.protectWebpackAssets ? this.currentAssets : [],
|
141
|
+
});
|
142
|
+
for (const filepath of deleted) {
|
143
|
+
rmSync(filepath, {
|
144
|
+
force: true,
|
145
|
+
recursive: true,
|
146
|
+
});
|
147
|
+
}
|
148
|
+
/**
|
149
|
+
* Log if verbose is enabled
|
150
|
+
*/
|
151
|
+
if (this.verbose) {
|
152
|
+
deleted.forEach((file) => {
|
153
|
+
const filename = relative(this.projectCwd, file);
|
154
|
+
const message = 'removed';
|
155
|
+
/**
|
156
|
+
* Use console.warn over .log
|
157
|
+
* https://github.com/webpack/webpack/issues/1904
|
158
|
+
* https://github.com/johnagan/clean-webpack-plugin/issues/11
|
159
|
+
*/
|
160
|
+
logger.debug(`clean-webpack-plugin: ${message} ${filename}`, moduleName);
|
161
|
+
});
|
162
|
+
}
|
163
|
+
}
|
164
|
+
catch (error) {
|
165
|
+
const needsForce = /Cannot delete files\/folders outside the current working directory\./.test(error.message);
|
166
|
+
if (needsForce) {
|
167
|
+
const message = 'clean-webpack-plugin: Cannot delete files/folders outside the current working directory. Can be overridden with the `dangerouslyAllowCleanPatternsOutsideProject` option.';
|
168
|
+
throw new Error(message);
|
169
|
+
}
|
170
|
+
throw error;
|
171
|
+
}
|
172
|
+
}
|
173
|
+
}
|
@@ -1 +1,22 @@
|
|
1
|
-
import{join}from
|
1
|
+
import { join } from 'node:path';
|
2
|
+
import { ensureSlash } from '@flatjs/common';
|
3
|
+
import { CleanWebpackPlugin } from './clean-webpack-plugin.js';
|
4
|
+
/**
|
5
|
+
* Cleaning up the /dist folder for `production` build
|
6
|
+
* @param singleEntryItem
|
7
|
+
* @returns
|
8
|
+
*/
|
9
|
+
export const createCleanWebpackPlugin = (serveMode, entryMapItemList, evolveOptions) => {
|
10
|
+
if (serveMode) {
|
11
|
+
return [];
|
12
|
+
}
|
13
|
+
return [
|
14
|
+
new CleanWebpackPlugin({
|
15
|
+
verbose: true,
|
16
|
+
projectCwd: evolveOptions.projectCwd,
|
17
|
+
cleanOnceBeforeBuildPatterns: entryMapItemList.map((entryMapItem) => {
|
18
|
+
return `${join(ensureSlash(entryMapItem[0], true), '**/*')}`;
|
19
|
+
}),
|
20
|
+
}),
|
21
|
+
];
|
22
|
+
};
|
@@ -1 +1,28 @@
|
|
1
|
-
|
1
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
2
|
+
import { getLastCommitHash, gitBranchName } from '@armit/git';
|
3
|
+
import webpack from 'webpack';
|
4
|
+
/**
|
5
|
+
* The DefinePlugin replaces variables in your code with other values or expressions at compile time.
|
6
|
+
* ```ts
|
7
|
+
* `__SENTRY_DEBUG__`
|
8
|
+
* `process.env.FLAT_BUILD_DATE`
|
9
|
+
* `process.env.FLAT_COMMIT_HASH`
|
10
|
+
* `process.env.FLAT_BRANCH_NAME`
|
11
|
+
* `process.env.FLAT_RELEASE_VERSION`
|
12
|
+
* ```
|
13
|
+
* @returns
|
14
|
+
*/
|
15
|
+
export const createBuiltinDefineVariables = async (serveMode, evolveOptions) => {
|
16
|
+
const commitHash = await getLastCommitHash();
|
17
|
+
const branchName = await gitBranchName();
|
18
|
+
return [
|
19
|
+
new webpack.DefinePlugin({
|
20
|
+
__SENTRY_DEBUG__: serveMode,
|
21
|
+
'process.env.FLAT_BUILD_DATE': JSON.stringify(new Date().toISOString()),
|
22
|
+
'process.env.FLAT_COMMIT_HASH': JSON.stringify(commitHash),
|
23
|
+
'process.env.FLAT_BRANCH_NAME': JSON.stringify(branchName),
|
24
|
+
'process.env.FLAT_RELEASE_VERSION': JSON.stringify(evolveOptions.ci?.releaseVersion || commitHash),
|
25
|
+
...evolveOptions.pluginOptions.definePlugin,
|
26
|
+
}),
|
27
|
+
];
|
28
|
+
};
|
@@ -1 +1 @@
|
|
1
|
-
export*from
|
1
|
+
export * from './define-variable-plugin.js';
|
@@ -1 +1,27 @@
|
|
1
|
-
import htmlWebpackPlugin from
|
1
|
+
import htmlWebpackPlugin from 'html-webpack-plugin';
|
2
|
+
const PLUGIN_PREFIX = `HtmlInjectScriptPlugin`;
|
3
|
+
export class HtmlInjectScriptPlugin {
|
4
|
+
constructor(scripts) {
|
5
|
+
this.scripts = scripts || [];
|
6
|
+
}
|
7
|
+
processScripts() {
|
8
|
+
return this.scripts.filter(Boolean).map((asset) => {
|
9
|
+
return {
|
10
|
+
tagName: 'script',
|
11
|
+
innerHTML: asset,
|
12
|
+
voidTag: false,
|
13
|
+
attributes: {},
|
14
|
+
meta: { plugin: 'html-inject-script-webpack-plugin' },
|
15
|
+
};
|
16
|
+
});
|
17
|
+
}
|
18
|
+
apply(compiler) {
|
19
|
+
compiler.hooks.compilation.tap(`${PLUGIN_PREFIX}_compilation`, (compilation) => {
|
20
|
+
const hooks = htmlWebpackPlugin.getHooks(compilation);
|
21
|
+
hooks.alterAssetTags.tap(`${PLUGIN_PREFIX}_alterAssetTags`, (data) => {
|
22
|
+
data.assetTags.scripts.unshift(...this.processScripts());
|
23
|
+
return data;
|
24
|
+
});
|
25
|
+
});
|
26
|
+
}
|
27
|
+
}
|