weboptimizer 4.0.2 → 4.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browser.d.ts +1 -2
- package/browser.js +4 -4
- package/configurator.d.ts +6 -5
- package/configurator.js +98 -20
- package/ejsLoader.d.ts +5 -5
- package/ejsLoader.js +7 -9
- package/helper.d.ts +3 -3
- package/helper.js +1 -2
- package/index.d.ts +1 -2
- package/index.js +19 -14
- package/package.json +16 -27
- package/plugins/HTMLTransformation.d.ts +2 -2
- package/plugins/HTMLTransformation.js +2 -4
- package/plugins/InPlaceAssetsIntoHTML.d.ts +2 -2
- package/plugins/InPlaceAssetsIntoHTML.js +0 -2
- package/stylelintConfigurator.js +3 -3
- package/type.d.ts +7 -7
- package/type.js +0 -13
- package/webpackConfigurator.d.ts +2 -4
- package/webpackConfigurator.js +109 -55
package/browser.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { Logger } from 'clientnode';
|
|
2
1
|
import { Browser, InitializedBrowser } from './type';
|
|
3
2
|
export declare const browser: Browser;
|
|
4
|
-
export declare const log:
|
|
3
|
+
export declare const log: any;
|
|
5
4
|
/**
|
|
6
5
|
* Provides a generic browser api in node or web contexts.
|
|
7
6
|
* @param replaceWindow - Indicates whether a potential existing window object
|
package/browser.js
CHANGED
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
*/
|
|
18
18
|
// region imports
|
|
19
19
|
import "core-js/modules/es.array.push.js";
|
|
20
|
-
import {
|
|
20
|
+
import { Browser, InitializedBrowser } from "./type.js";
|
|
21
|
+
import { CONSOLE_METHODS, Logger, timeout } from 'clientnode';
|
|
21
22
|
import { DOMWindow, VirtualConsole } from 'jsdom';
|
|
22
23
|
import { LoaderContext } from 'webpack';
|
|
23
|
-
import { LoaderConfiguration } from
|
|
24
|
-
import { Browser, InitializedBrowser } from './type';
|
|
24
|
+
import { LoaderConfiguration } from "./ejsLoader.js";
|
|
25
25
|
// endregion
|
|
26
26
|
// region declaration
|
|
27
27
|
|
|
@@ -98,7 +98,7 @@ if (typeof TARGET_TECHNOLOGY === 'undefined' || TARGET_TECHNOLOGY === 'node')
|
|
|
98
98
|
});
|
|
99
99
|
};
|
|
100
100
|
if (typeof NAME === 'undefined' || NAME === 'webOptimizer') {
|
|
101
|
-
const filePath = path.join(
|
|
101
|
+
const filePath = path.join(import.meta.dirname, 'index.html.ejs');
|
|
102
102
|
/*
|
|
103
103
|
NOTE: We load dependencies now to avoid having file imports
|
|
104
104
|
after test runner has finished to isolate the environment.
|
package/configurator.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import type { ResolvedConfiguration } from './type';
|
|
2
|
+
export declare const require: NodeJS.Require;
|
|
3
|
+
export declare const optionalRequire: <T = unknown>(id: string) => null | T;
|
|
3
4
|
export declare let loadedConfiguration: null | ResolvedConfiguration;
|
|
4
|
-
export declare const log:
|
|
5
|
+
export declare const log: any;
|
|
5
6
|
/**
|
|
6
7
|
* Main entry point to determine current configuration.
|
|
7
8
|
* @param context - Location from where to build current application.
|
|
@@ -12,10 +13,10 @@ export declare const log: Logger;
|
|
|
12
13
|
* @param environment - Environment variables to take into account.
|
|
13
14
|
* @returns Nothing.
|
|
14
15
|
*/
|
|
15
|
-
export declare const load: (context?: string, currentWorkingDirectory?: string, commandLineArguments?: Array<string>, webOptimizerPath?: string, environment?: NodeJS.ProcessEnv) => ResolvedConfiguration
|
|
16
|
+
export declare const load: (context?: string, currentWorkingDirectory?: string, commandLineArguments?: Array<string>, webOptimizerPath?: string, environment?: NodeJS.ProcessEnv) => Promise<ResolvedConfiguration>;
|
|
16
17
|
/**
|
|
17
18
|
* Get cached or determined configuration object.
|
|
18
19
|
* @returns Nothing.
|
|
19
20
|
*/
|
|
20
|
-
export declare const get: () => ResolvedConfiguration
|
|
21
|
+
export declare const get: () => Promise<ResolvedConfiguration>;
|
|
21
22
|
export default get;
|
package/configurator.js
CHANGED
|
@@ -16,21 +16,95 @@
|
|
|
16
16
|
endregion
|
|
17
17
|
*/
|
|
18
18
|
// region imports
|
|
19
|
+
const _rewrite = (specifier, options) => {
|
|
20
|
+
if (typeof specifier !== 'string') {
|
|
21
|
+
throw new TypeError(`rewrite error: expected specifier of type string, not ${typeof specifier}`);
|
|
22
|
+
}
|
|
23
|
+
let replacementMap;
|
|
24
|
+
if (options.replaceExtensions) {
|
|
25
|
+
Object.entries(options.replaceExtensions).some(([target, replacement]) => {
|
|
26
|
+
if (target.startsWith('^') || target.endsWith('$')) {
|
|
27
|
+
const targetRegExp = new RegExp(target);
|
|
28
|
+
const capturingGroups = Array.from(specifier.match(targetRegExp) || []);
|
|
29
|
+
if (capturingGroups.length) {
|
|
30
|
+
replacementMap = [targetRegExp, replacement, capturingGroups];
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
} else if (specifier.endsWith(target)) {
|
|
34
|
+
replacementMap = [target, replacement, []];
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
let finalImportPath = specifier;
|
|
40
|
+
if (replacementMap) {
|
|
41
|
+
const [target, replacement, capturingGroups] = replacementMap;
|
|
42
|
+
finalImportPath = finalImportPath.replace(target, typeof replacement === 'string' ? replacement : replacement({
|
|
43
|
+
specifier,
|
|
44
|
+
capturingGroups,
|
|
45
|
+
filepath: '/__w/weboptimizer/weboptimizer/configurator.ts'
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
const isRelative = finalImportPath.startsWith('./') || finalImportPath.startsWith('.\\') || finalImportPath.startsWith('../') || finalImportPath.startsWith('..\\') || finalImportPath === '.' || finalImportPath === '..';
|
|
49
|
+
if (options.appendExtension && isRelative) {
|
|
50
|
+
const endsWithSlash = /(\/|\\)$/.test(finalImportPath);
|
|
51
|
+
const basenameIsDots = /(^\.?\.(\/|\\)?$)|((\/|\\)\.?\.(\/|\\)?$)/.test(finalImportPath);
|
|
52
|
+
const extensionToAppend = typeof options.appendExtension === 'string' ? options.appendExtension : options.appendExtension({
|
|
53
|
+
specifier,
|
|
54
|
+
capturingGroups: [],
|
|
55
|
+
filepath: '/__w/weboptimizer/weboptimizer/configurator.ts'
|
|
56
|
+
});
|
|
57
|
+
if (extensionToAppend !== undefined) {
|
|
58
|
+
if (basenameIsDots) {
|
|
59
|
+
finalImportPath += `${endsWithSlash ? '' : '/'}index${extensionToAppend}`;
|
|
60
|
+
} else {
|
|
61
|
+
const hasRecognizedExtension = !endsWithSlash && options.recognizedExtensions.some(extension => {
|
|
62
|
+
return finalImportPath.endsWith(extension);
|
|
63
|
+
});
|
|
64
|
+
if (!hasRecognizedExtension) {
|
|
65
|
+
finalImportPath = endsWithSlash ? finalImportPath + `index${extensionToAppend}` : finalImportPath + extensionToAppend;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return finalImportPath;
|
|
71
|
+
},
|
|
72
|
+
_rewrite_options = {
|
|
73
|
+
"appendExtension": ".js",
|
|
74
|
+
"recognizedExtensions": [".js", ".jsx", ".d.ts", ".ts", ".tsx", ".json"]
|
|
75
|
+
};
|
|
19
76
|
import "core-js/modules/es.iterator.constructor.js";
|
|
20
77
|
import "core-js/modules/es.iterator.filter.js";
|
|
21
78
|
import "core-js/modules/es.iterator.map.js";
|
|
79
|
+
import "core-js/modules/es.iterator.some.js";
|
|
22
80
|
import "core-js/modules/es.json.parse.js";
|
|
23
|
-
import { convertCircularObjectToJSON, copy,
|
|
81
|
+
import { convertCircularObjectToJSON, copy, evaluateDynamicData, extend, getUTCTimestamp, importsPromise, isFileSync, isObject, isolatedRequire, isPlainObject, Logger, MAXIMAL_NUMBER_OF_ITERATIONS, modifyObject, optionalImport, parseEncodedObject, removeKeyPrefixes, UTILITY_SCOPE } from 'clientnode';
|
|
24
82
|
import fileSystem, { lstatSync, readFileSync, unlinkSync } from 'fs';
|
|
83
|
+
import { createRequire } from 'node:module';
|
|
25
84
|
import path, { basename, dirname, join, resolve } from 'path';
|
|
26
|
-
import { determineAssetType, determineModuleFilePath, determineModuleLocations, resolveAutoInjection, resolveBuildConfigurationFilePaths, resolveModulesInFolders, normalizeGivenInjection, normalizePaths } from
|
|
27
|
-
import packageConfiguration
|
|
28
|
-
import {
|
|
85
|
+
import { determineAssetType, determineModuleFilePath, determineModuleLocations, resolveAutoInjection, resolveBuildConfigurationFilePaths, resolveModulesInFolders, normalizeGivenInjection, normalizePaths } from "./helper.js";
|
|
86
|
+
import packageConfiguration from './package.json' with { type: 'json' };
|
|
87
|
+
import { SubConfigurationTypes } from "./type.js";
|
|
29
88
|
// endregion
|
|
89
|
+
export const require = createRequire(import.meta.url);
|
|
90
|
+
export const optionalRequire = id => {
|
|
91
|
+
try {
|
|
92
|
+
return require(_rewrite(id, _rewrite_options));
|
|
93
|
+
} catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
const {
|
|
98
|
+
configuration: metaConfiguration
|
|
99
|
+
} = packageConfiguration;
|
|
30
100
|
export let loadedConfiguration = null;
|
|
31
101
|
export const log = new Logger({
|
|
32
102
|
name: 'weboptimizer.configurator'
|
|
33
103
|
});
|
|
104
|
+
|
|
105
|
+
// Wait until optional filesystem modules have been loaded.
|
|
106
|
+
await importsPromise;
|
|
107
|
+
|
|
34
108
|
/**
|
|
35
109
|
* Main entry point to determine current configuration.
|
|
36
110
|
* @param context - Location from where to build current application.
|
|
@@ -41,7 +115,7 @@ export const log = new Logger({
|
|
|
41
115
|
* @param environment - Environment variables to take into account.
|
|
42
116
|
* @returns Nothing.
|
|
43
117
|
*/
|
|
44
|
-
export const load = (context, currentWorkingDirectory = process.cwd(), commandLineArguments = process.argv, webOptimizerPath =
|
|
118
|
+
export const load = async (context, currentWorkingDirectory = process.cwd(), commandLineArguments = process.argv, webOptimizerPath = import.meta.dirname,
|
|
45
119
|
/*
|
|
46
120
|
NOTE: We have to avoid that some pre-processor removes this
|
|
47
121
|
assignment.
|
|
@@ -85,8 +159,11 @@ environment = eval('process.env')) => {
|
|
|
85
159
|
// region load application specific configuration
|
|
86
160
|
let specificConfiguration = {};
|
|
87
161
|
try {
|
|
88
|
-
|
|
89
|
-
|
|
162
|
+
specificConfiguration = (await optionalImport(join(metaConfiguration.default.path.context, 'package.json'), {
|
|
163
|
+
with: {
|
|
164
|
+
type: 'json'
|
|
165
|
+
}
|
|
166
|
+
})).default;
|
|
90
167
|
} catch {
|
|
91
168
|
metaConfiguration.default.path.context = currentWorkingDirectory;
|
|
92
169
|
}
|
|
@@ -174,16 +251,18 @@ environment = eval('process.env')) => {
|
|
|
174
251
|
transformed in place in the following lines of code.
|
|
175
252
|
*/
|
|
176
253
|
const resolvedConfiguration = evaluateDynamicData(configuration, {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
254
|
+
scope: {
|
|
255
|
+
...UTILITY_SCOPE,
|
|
256
|
+
currentPath: currentWorkingDirectory,
|
|
257
|
+
fs: fileSystem,
|
|
258
|
+
optionalRequire,
|
|
259
|
+
packageConfiguration,
|
|
260
|
+
path,
|
|
261
|
+
require: isolatedRequire,
|
|
262
|
+
webOptimizerPath,
|
|
263
|
+
now,
|
|
264
|
+
nowUTCTimestamp: getUTCTimestamp(now)
|
|
265
|
+
}
|
|
187
266
|
});
|
|
188
267
|
// endregion
|
|
189
268
|
// region consolidate file specific build configuration
|
|
@@ -262,9 +341,8 @@ environment = eval('process.env')) => {
|
|
|
262
341
|
* Get cached or determined configuration object.
|
|
263
342
|
* @returns Nothing.
|
|
264
343
|
*/
|
|
265
|
-
export const get = () => {
|
|
344
|
+
export const get = async () => {
|
|
266
345
|
if (loadedConfiguration) return loadedConfiguration;
|
|
267
|
-
|
|
268
|
-
return loadedConfiguration;
|
|
346
|
+
return await load();
|
|
269
347
|
};
|
|
270
348
|
export default get;
|
package/ejsLoader.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Encoding,
|
|
2
|
-
import { Options, TemplateFunction as EJSTemplateFunction } from 'ejs';
|
|
3
|
-
import { LoaderContext } from 'webpack';
|
|
4
|
-
import { Extensions, Replacements } from './type';
|
|
1
|
+
import type { Encoding, Mapping } from 'clientnode';
|
|
2
|
+
import type { Options, TemplateFunction as EJSTemplateFunction } from 'ejs';
|
|
3
|
+
import type { LoaderContext } from 'webpack';
|
|
4
|
+
import type { Extensions, Replacements } from './type';
|
|
5
5
|
export type TemplateFunction = EJSTemplateFunction;
|
|
6
6
|
export type CompilerOptions = Options & {
|
|
7
7
|
encoding: Encoding;
|
|
@@ -24,7 +24,7 @@ export type LoaderConfiguration = Mapping<unknown> & {
|
|
|
24
24
|
replacements: Replacements;
|
|
25
25
|
};
|
|
26
26
|
};
|
|
27
|
-
export declare const log:
|
|
27
|
+
export declare const log: any;
|
|
28
28
|
/**
|
|
29
29
|
* Main transformation function.
|
|
30
30
|
* @param source - Input string to transform.
|
package/ejsLoader.js
CHANGED
|
@@ -15,23 +15,21 @@
|
|
|
15
15
|
See https://creativecommons.org/licenses/by/3.0/deed.de
|
|
16
16
|
endregion
|
|
17
17
|
*/
|
|
18
|
-
// region
|
|
19
|
-
import {
|
|
18
|
+
// region
|
|
19
|
+
import { transformSync as babelTransformSync } from '@babel/core';
|
|
20
20
|
import babelMinifyPreset from 'babel-preset-minify';
|
|
21
|
-
import { convertSubstringInPlainObject, copy, currentRequire, evaluate,
|
|
22
|
-
import ejs
|
|
21
|
+
import { convertSubstringInPlainObject, copy, currentRequire, evaluate, extend, Logger, UTILITY_SCOPE } from 'clientnode';
|
|
22
|
+
import ejs from 'ejs';
|
|
23
23
|
import { readFileSync } from 'fs';
|
|
24
24
|
import { minify as minifyHTML } from 'html-minifier';
|
|
25
25
|
import { extname } from 'path';
|
|
26
|
-
import
|
|
27
|
-
import
|
|
28
|
-
import { determineModuleFilePath } from './helper';
|
|
29
|
-
import { Extensions, Replacements, ResolvedConfiguration } from './type';
|
|
26
|
+
import getConfiguration from "./configurator.js";
|
|
27
|
+
import { determineModuleFilePath } from "./helper.js";
|
|
30
28
|
// endregion
|
|
31
29
|
// region types
|
|
32
30
|
|
|
33
31
|
// endregion
|
|
34
|
-
const configuration = getConfiguration();
|
|
32
|
+
const configuration = await getConfiguration();
|
|
35
33
|
export const log = new Logger({
|
|
36
34
|
name: 'weboptimizer.ejs-loader'
|
|
37
35
|
});
|
package/helper.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Encoding,
|
|
2
|
-
import { BuildConfiguration, Extensions, GivenInjection, GivenInjectionConfiguration, NormalizedGivenInjection, PathConfiguration, PackageDescriptor, Replacements, ResolvedBuildConfiguration, SpecificExtensions } from './type';
|
|
1
|
+
import type { Encoding, Mapping } from 'clientnode';
|
|
2
|
+
import type { BuildConfiguration, Extensions, GivenInjection, GivenInjectionConfiguration, NormalizedGivenInjection, PathConfiguration, PackageDescriptor, Replacements, ResolvedBuildConfiguration, SpecificExtensions } from './type';
|
|
3
3
|
export declare const KNOWN_FILE_EXTENSIONS: Array<string>;
|
|
4
|
-
export declare const log:
|
|
4
|
+
export declare const log: any;
|
|
5
5
|
/**
|
|
6
6
|
* Determines whether given file path is within given list of file locations.
|
|
7
7
|
* @param filePath - Path to file to check.
|
package/helper.js
CHANGED
|
@@ -27,10 +27,9 @@ import "core-js/modules/es.set.is-subset-of.v2.js";
|
|
|
27
27
|
import "core-js/modules/es.set.is-superset-of.v2.js";
|
|
28
28
|
import "core-js/modules/es.set.symmetric-difference.v2.js";
|
|
29
29
|
import "core-js/modules/es.set.union.v2.js";
|
|
30
|
-
import { copy, currentRequire,
|
|
30
|
+
import { copy, currentRequire, escapeRegularExpressions, extend, isAnyMatching, isDirectorySync, isFileSync, isPlainObject, Logger, represent, walkDirectoryRecursivelySync } from 'clientnode';
|
|
31
31
|
import { existsSync, readFileSync } from 'fs';
|
|
32
32
|
import { basename, dirname, extname, join, normalize, resolve, sep, relative } from 'path';
|
|
33
|
-
import { BuildConfiguration, Extensions, GivenInjection, GivenInjectionConfiguration, NormalizedGivenInjection, PathConfiguration, PackageConfiguration, PackageDescriptor, Replacements, ResolvedBuildConfiguration, ResolvedBuildConfigurationItem, SpecificExtensions } from './type';
|
|
34
33
|
// endregion
|
|
35
34
|
// region constants
|
|
36
35
|
export const KNOWN_FILE_EXTENSIONS = ['js', 'ts', 'json', 'css', 'eot', 'gif', 'html', 'ico', 'jpg', 'png', 'ejs', 'svg', 'ttf', 'woff', '.woff2'];
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -23,16 +23,15 @@ import "core-js/modules/es.iterator.constructor.js";
|
|
|
23
23
|
import "core-js/modules/es.iterator.filter.js";
|
|
24
24
|
import "core-js/modules/es.iterator.map.js";
|
|
25
25
|
import "core-js/modules/es.json.stringify.js";
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
26
|
+
import { exec as execChildProcess, spawn as spawnChildProcess } from 'child_process';
|
|
27
|
+
import { CLOSE_EVENT_NAMES, copyDirectoryRecursiveSync, copyFileSync, evaluate, getProcessCloseHandler, handleChildProcess, importsPromise, isDirectory, isDirectorySync, isFile, isFileSync, isPlainObject, Logger, MAXIMAL_NUMBER_OF_ITERATIONS, NOOP, parseEncodedObject, walkDirectoryRecursively } from 'clientnode';
|
|
28
28
|
import { chmodSync, unlinkSync } from 'fs';
|
|
29
29
|
import { writeFile, unlink } from 'fs/promises';
|
|
30
|
-
import
|
|
30
|
+
import globAll from 'glob-all';
|
|
31
31
|
import path, { join, resolve } from 'path';
|
|
32
32
|
import { rimraf as removeDirectoryRecursively, sync as removeDirectoryRecursivelySync } from 'rimraf';
|
|
33
|
-
import { load as loadConfiguration } from
|
|
34
|
-
import { determineAssetType, determineModuleFilePath, determineModuleLocations, isFilePathInLocation, renderFilePathTemplate, resolveBuildConfigurationFilePaths, stripLoader } from
|
|
35
|
-
import { Command, CommandLineArguments, GivenInjection, ResolvedBuildConfiguration, ResolvedBuildConfigurationItem, ResolvedConfiguration } from './type';
|
|
33
|
+
import { load as loadConfiguration } from "./configurator.js";
|
|
34
|
+
import { determineAssetType, determineModuleFilePath, determineModuleLocations, isFilePathInLocation, renderFilePathTemplate, resolveBuildConfigurationFilePaths, stripLoader } from "./helper.js";
|
|
36
35
|
// endregion
|
|
37
36
|
export const log = new Logger({
|
|
38
37
|
name: 'weboptimizer'
|
|
@@ -42,6 +41,10 @@ Logger.configureAllInstances({
|
|
|
42
41
|
});
|
|
43
42
|
// NOTE: Environment variables can only be strings.
|
|
44
43
|
process.env.UV_THREADPOOL_SIZE = '128';
|
|
44
|
+
|
|
45
|
+
// Wait until optional filesystem modules have been loaded.
|
|
46
|
+
await importsPromise;
|
|
47
|
+
|
|
45
48
|
/**
|
|
46
49
|
* Main entry point.
|
|
47
50
|
* @param context - Location from where to build current application.
|
|
@@ -52,14 +55,14 @@ process.env.UV_THREADPOOL_SIZE = '128';
|
|
|
52
55
|
* @param environment - Environment variables to take into account.
|
|
53
56
|
* @returns Nothing.
|
|
54
57
|
*/
|
|
55
|
-
const main = async (context, currentWorkingDirectory = process.cwd(), commandLineArguments = process.argv, webOptimizerPath =
|
|
58
|
+
const main = async (context, currentWorkingDirectory = process.cwd(), commandLineArguments = process.argv, webOptimizerPath = import.meta.dirname,
|
|
56
59
|
/*
|
|
57
60
|
NOTE: We have to avoid that some pre-processor removes this
|
|
58
61
|
assignment.
|
|
59
62
|
*/
|
|
60
63
|
environment = eval('process.env')) => {
|
|
61
64
|
if (environment.PATH && !environment.PATH.includes(':node_modules/.bin')) environment.PATH += ':node_modules/.bin';else environment.PATH = 'node_modules/.bin';
|
|
62
|
-
const configuration = loadConfiguration(context, currentWorkingDirectory, commandLineArguments, webOptimizerPath, environment);
|
|
65
|
+
const configuration = await loadConfiguration(context, currentWorkingDirectory, commandLineArguments, webOptimizerPath, environment);
|
|
63
66
|
let clear = NOOP();
|
|
64
67
|
try {
|
|
65
68
|
// region controller
|
|
@@ -110,7 +113,7 @@ environment = eval('process.env')) => {
|
|
|
110
113
|
*/
|
|
111
114
|
if (possibleArguments.includes(configuration.givenCommandLineArguments[2]) && (!['build', 'build:types', 'lint', 'preinstall', 'test', 'test:browser', 'test:coverage', 'test:coverage:report', 'serve', 'watch'].includes(configuration.givenCommandLineArguments[2]) ||
|
|
112
115
|
/*
|
|
113
|
-
NOTE: If target
|
|
116
|
+
NOTE: If target artifacts are located next to their
|
|
114
117
|
source files, we need to clear them first when running
|
|
115
118
|
dev mode (watching source files and reloading build
|
|
116
119
|
automatically).
|
|
@@ -130,12 +133,14 @@ environment = eval('process.env')) => {
|
|
|
130
133
|
}
|
|
131
134
|
});
|
|
132
135
|
for (const file of await walkDirectoryRecursively(configuration.path.target.base, () => false, configuration.encoding)) if (file.name.startsWith('npm-debug')) await unlink(file.path);
|
|
133
|
-
} else
|
|
136
|
+
} else {
|
|
137
|
+
await removeDirectoryRecursively(configuration.path.target.base);
|
|
138
|
+
}
|
|
134
139
|
if (await isDirectory(configuration.path.apiDocumentation)) await removeDirectoryRecursively(configuration.path.apiDocumentation);
|
|
135
140
|
for (const filePath of configuration.path.tidyUpOnClear) if (filePath) if (isFileSync(filePath))
|
|
136
141
|
// NOTE: Close handler have to be synchronous.
|
|
137
142
|
unlinkSync(filePath);else if (isDirectorySync(filePath)) removeDirectoryRecursivelySync(filePath);
|
|
138
|
-
removeDirectoryRecursivelySync(
|
|
143
|
+
removeDirectoryRecursivelySync(globAll.sync(configuration.path.tidyUpOnClearGlobs));
|
|
139
144
|
}
|
|
140
145
|
// endregion
|
|
141
146
|
// region handle build
|
|
@@ -169,7 +174,7 @@ environment = eval('process.env')) => {
|
|
|
169
174
|
for (const filePath of configuration.path.tidyUp) if (filePath) if (isFileSync(filePath))
|
|
170
175
|
// NOTE: Close handler have to be synchronous.
|
|
171
176
|
unlinkSync(filePath);else if (isDirectorySync(filePath)) removeDirectoryRecursivelySync(filePath);
|
|
172
|
-
removeDirectoryRecursivelySync(
|
|
177
|
+
removeDirectoryRecursivelySync(globAll.sync(configuration.path.tidyUpGlobs));
|
|
173
178
|
};
|
|
174
179
|
closeEventHandlers.push(tidyUp);
|
|
175
180
|
|
|
@@ -276,7 +281,7 @@ environment = eval('process.env')) => {
|
|
|
276
281
|
finished = true;
|
|
277
282
|
};
|
|
278
283
|
for (const closeEventName of CLOSE_EVENT_NAMES) process.on(closeEventName, closeHandler);
|
|
279
|
-
if (
|
|
284
|
+
if (import.meta.main && (configuration.givenCommandLineArguments.length < 3 || !possibleArguments.includes(configuration.givenCommandLineArguments[2]))) log.info(`Give one of "${possibleArguments.join('", "')}" as command`, 'line argument. You can provide a json string as second', 'parameter to dynamically overwrite some configurations.\n');
|
|
280
285
|
// endregion
|
|
281
286
|
// region forward nested return codes
|
|
282
287
|
try {
|
|
@@ -291,5 +296,5 @@ environment = eval('process.env')) => {
|
|
|
291
296
|
}
|
|
292
297
|
return clear;
|
|
293
298
|
};
|
|
294
|
-
if (
|
|
299
|
+
if (import.meta.main) void main();
|
|
295
300
|
export default main;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "weboptimizer",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.4",
|
|
4
4
|
"description": "A generic web optimizer, (module) bundler and development environment.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"webpack",
|
|
@@ -88,12 +88,14 @@
|
|
|
88
88
|
"@babel/core": "^8.0.1",
|
|
89
89
|
"@babel/plugin-proposal-decorators": "^8.0.2",
|
|
90
90
|
"@babel/plugin-transform-class-properties": "^8.0.1",
|
|
91
|
+
"@babel/plugin-transform-proto-to-assign": "^8.0.1",
|
|
91
92
|
"@babel/preset-env": "^8.0.2",
|
|
92
93
|
"@babel/preset-typescript": "^8.0.1",
|
|
93
94
|
"babel-loader": "^10.1.1",
|
|
94
95
|
"babel-plugin-polyfill-corejs3": "^1.0.0",
|
|
96
|
+
"babel-plugin-transform-rewrite-imports": "^1.5.4",
|
|
95
97
|
"babel-preset-minify": "^0.5.2",
|
|
96
|
-
"clientnode": "4.0.
|
|
98
|
+
"clientnode": "4.0.1430",
|
|
97
99
|
"core-js": "^3.49.0",
|
|
98
100
|
"ejs": "^6.0.1",
|
|
99
101
|
"exports-loader": "^5.0.0",
|
|
@@ -107,7 +109,7 @@
|
|
|
107
109
|
"rimraf": "^6.1.3",
|
|
108
110
|
"script-loader": "^0.7.2",
|
|
109
111
|
"typescript": "^6.0.3",
|
|
110
|
-
"webpack": "^5.108.
|
|
112
|
+
"webpack": "^5.108.3",
|
|
111
113
|
"webpack-cli": "^7.1.0",
|
|
112
114
|
"webpack-sources": "^3.5.0"
|
|
113
115
|
},
|
|
@@ -121,17 +123,17 @@
|
|
|
121
123
|
"@types/html-minifier": "^4.0.6",
|
|
122
124
|
"@types/html-minifier-terser": "^7.0.2",
|
|
123
125
|
"@types/imagemin": "^9.0.1",
|
|
124
|
-
"@types/node": "^26.0
|
|
126
|
+
"@types/node": "^26.1.0",
|
|
125
127
|
"@types/postcss-import": "^14.0.3",
|
|
126
128
|
"@types/postcss-url": "^10.0.4",
|
|
127
129
|
"@types/webpack-env": "^1.18.8",
|
|
128
130
|
"@types/webpack-sources": "^3.2.3",
|
|
129
|
-
"@typescript-eslint/parser": "^8.62.
|
|
131
|
+
"@typescript-eslint/parser": "^8.62.1",
|
|
130
132
|
"css-loader": "^7.1.4",
|
|
131
133
|
"cssnano": "^8.0.2",
|
|
132
|
-
"eslint": "^10.
|
|
134
|
+
"eslint": "^10.6.0",
|
|
133
135
|
"eslint-config-google": "^0.14.0",
|
|
134
|
-
"eslint-plugin-jsdoc": "^63.0.
|
|
136
|
+
"eslint-plugin-jsdoc": "^63.0.10",
|
|
135
137
|
"favicons": "^7.3.0",
|
|
136
138
|
"favicons-webpack-plugin": "^6.0.1",
|
|
137
139
|
"globals": "^17.7.0",
|
|
@@ -141,11 +143,11 @@
|
|
|
141
143
|
"mini-css-extract-plugin": "^2.10.2",
|
|
142
144
|
"mkdirp": "^3.0.1",
|
|
143
145
|
"node-fetch": "^3.3.2",
|
|
144
|
-
"postcss": "^8.5.
|
|
146
|
+
"postcss": "^8.5.16",
|
|
145
147
|
"postcss-fontpath": "^1.0.0",
|
|
146
148
|
"postcss-import": "^16.1.1",
|
|
147
149
|
"postcss-loader": "^8.2.1",
|
|
148
|
-
"postcss-preset-env": "^11.3.
|
|
150
|
+
"postcss-preset-env": "^11.3.2",
|
|
149
151
|
"postcss-sprites": "^4.2.1",
|
|
150
152
|
"postcss-url": "^10.1.4",
|
|
151
153
|
"shx": "^0.4.0",
|
|
@@ -154,7 +156,7 @@
|
|
|
154
156
|
"stylelint-config-standard": "^40.0.0",
|
|
155
157
|
"stylelint-config-standard-scss": "^17.0.0",
|
|
156
158
|
"terser-webpack-plugin": "^5.6.1",
|
|
157
|
-
"typescript-eslint": "^8.62.
|
|
159
|
+
"typescript-eslint": "^8.62.1",
|
|
158
160
|
"typescript-plugin-css-modules": "^5.2.0",
|
|
159
161
|
"web-documentation": "^1.0.42",
|
|
160
162
|
"workbox-webpack-plugin": "^7.4.1"
|
|
@@ -1188,28 +1190,15 @@
|
|
|
1188
1190
|
}
|
|
1189
1191
|
],
|
|
1190
1192
|
[
|
|
1191
|
-
"
|
|
1193
|
+
"babel-plugin-polyfill-corejs3",
|
|
1192
1194
|
{
|
|
1193
|
-
"
|
|
1195
|
+
"method": "usage-global"
|
|
1194
1196
|
}
|
|
1195
|
-
]
|
|
1196
|
-
[
|
|
1197
|
-
"@babel/plugin-transform-class-properties"
|
|
1198
|
-
],
|
|
1199
|
-
[
|
|
1200
|
-
"transform-modern-regexp",
|
|
1201
|
-
{
|
|
1202
|
-
"features": [
|
|
1203
|
-
"dotAll",
|
|
1204
|
-
"namedCapturingGroups"
|
|
1205
|
-
]
|
|
1206
|
-
}
|
|
1207
|
-
],
|
|
1208
|
-
"babel-plugin-polyfill-corejs3"
|
|
1197
|
+
]
|
|
1209
1198
|
],
|
|
1210
1199
|
"presets": {
|
|
1211
1200
|
"#": "NOTE: We have to disable module export/import transformation to allow tree shaking by the final (minimizer).",
|
|
1212
|
-
"__evaluate__": "[['@babel/preset-env', {
|
|
1201
|
+
"__evaluate__": "[['@babel/preset-env', {targets: self.generic.isWeb ? {browsers: self.generic.supportedBrowsers, node: packageConfiguration.engines.node.replace(/>?=?([0-9]+)/, '$1')} : {node: packageConfiguration.engines.node.replace(/>?=?([0-9]+)/, '$1')}}], '@babel/preset-typescript'].concat((self.debug || !self.module.optimizer.babelMinify.module || 2 < self.givenCommandLineArguments.length && self.givenCommandLineArguments[2] === 'document') ? [] : [['minify', self.module.optimizer.babelMinify.module]])"
|
|
1213
1202
|
}
|
|
1214
1203
|
},
|
|
1215
1204
|
"regularExpression": "\\.[jt]sx?(?:\\?.*)?$"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Compiler } from 'webpack';
|
|
2
|
-
import { HTMLTransformationOptions } from '../type';
|
|
1
|
+
import type { Compiler } from 'webpack';
|
|
2
|
+
import type { HTMLTransformationOptions } from '../type';
|
|
3
3
|
export declare class HTMLTransformation {
|
|
4
4
|
private defaultOptions;
|
|
5
5
|
private options;
|
|
@@ -20,12 +20,10 @@ import "core-js/modules/es.array.push.js";
|
|
|
20
20
|
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
21
21
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
22
22
|
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
23
|
-
import { copy, extend
|
|
23
|
+
import { copy, extend } from 'clientnode';
|
|
24
24
|
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
|
25
25
|
import { JSDOM as DOM } from 'jsdom';
|
|
26
|
-
import
|
|
27
|
-
import ejsLoader, { LoaderConfiguration as EJSLoaderConfiguration } from '../ejsLoader';
|
|
28
|
-
import { HTMLTransformationOptions, HTMLWebpackPluginBeforeEmitData, WebpackLoader } from '../type';
|
|
26
|
+
import ejsLoader from "../ejsLoader.js";
|
|
29
27
|
// endregion
|
|
30
28
|
|
|
31
29
|
export class HTMLTransformation {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Compiler } from 'webpack';
|
|
2
|
-
import { InPlaceAssetsIntoHTMLOptions } from '../type';
|
|
1
|
+
import type { Compiler } from 'webpack';
|
|
2
|
+
import type { InPlaceAssetsIntoHTMLOptions } from '../type';
|
|
3
3
|
export declare class InPlaceAssetsIntoHTML {
|
|
4
4
|
private defaultOptions;
|
|
5
5
|
private options;
|
|
@@ -23,9 +23,7 @@ import "core-js/modules/es.iterator.some.js";
|
|
|
23
23
|
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
24
24
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
25
25
|
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
26
|
-
import { Compilation, Compiler } from 'webpack';
|
|
27
26
|
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
|
28
|
-
import { InPlaceAssetConfiguration, InPlaceAssetsIntoHTMLOptions, WebpackAssets, WebpackBaseAssets } from '../type';
|
|
29
27
|
// endregion
|
|
30
28
|
|
|
31
29
|
export class InPlaceAssetsIntoHTML {
|
package/stylelintConfigurator.js
CHANGED
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
endregion
|
|
17
17
|
*/
|
|
18
18
|
// region imports
|
|
19
|
-
import getConfiguration from
|
|
20
|
-
import { ResolvedConfiguration } from
|
|
19
|
+
import getConfiguration from "./configurator.js";
|
|
20
|
+
import { ResolvedConfiguration } from "./type.js";
|
|
21
21
|
// endregion
|
|
22
|
-
const configuration = getConfiguration();
|
|
22
|
+
const configuration = await getConfiguration();
|
|
23
23
|
module.exports = configuration.stylelint;
|
|
24
24
|
export default module.exports;
|
package/type.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { AnyFunction, Encoding, Mapping, PlainObject, SecondParameter } from 'clientnode';
|
|
1
|
+
import type { AnyFunction, Encoding, Mapping, PlainObject, SecondParameter } from 'clientnode';
|
|
2
2
|
import type FaviconWebpackPlugin from 'favicons-webpack-plugin';
|
|
3
|
-
import { FaviconWebpackPlugionOptions as FaviconWebpackPluginOptions } from 'favicons-webpack-plugin/src/options';
|
|
4
|
-
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
|
3
|
+
import type { FaviconWebpackPlugionOptions as FaviconWebpackPluginOptions } from 'favicons-webpack-plugin/src/options';
|
|
4
|
+
import type HtmlWebpackPlugin from 'html-webpack-plugin';
|
|
5
5
|
import type ImageMinimizerWebpackPlugin from 'image-minimizer-webpack-plugin';
|
|
6
|
-
import { PluginOptions as ImageMinimizerOptions } from 'image-minimizer-webpack-plugin';
|
|
7
|
-
import { JSDOM } from 'jsdom';
|
|
6
|
+
import type { PluginOptions as ImageMinimizerOptions } from 'image-minimizer-webpack-plugin';
|
|
7
|
+
import type { JSDOM } from 'jsdom';
|
|
8
8
|
import type MiniCSSExtractPlugin from 'mini-css-extract-plugin';
|
|
9
9
|
import type TerserWebpackPlugin from 'terser-webpack-plugin';
|
|
10
|
-
import { DefinePlugin as WebpackDefinePlugin, Configuration as BaseWebpackConfiguration, IgnorePlugin as WebpackIgnorePlugin, library as webpackLibrary, ModuleOptions as WebpackModuleOptions, RuleSetRule as WebpackRuleSetRule, RuleSetUseItem as WebpackRuleSetUseItem, WebpackOptionsNormalized } from 'webpack';
|
|
11
|
-
import { WebpackPartial as WorkboxBaseCommonOptions, BasePartial as WorkboxCommonOptions, WebpackGenerateSWOptions as WorkboxGenerateSWOptions, WebpackInjectManifestOptions as WorkboxInjectManifestOptions } from 'workbox-build';
|
|
10
|
+
import type { DefinePlugin as WebpackDefinePlugin, Configuration as BaseWebpackConfiguration, IgnorePlugin as WebpackIgnorePlugin, library as webpackLibrary, ModuleOptions as WebpackModuleOptions, RuleSetRule as WebpackRuleSetRule, RuleSetUseItem as WebpackRuleSetUseItem, WebpackOptionsNormalized } from 'webpack';
|
|
11
|
+
import type { WebpackPartial as WorkboxBaseCommonOptions, BasePartial as WorkboxCommonOptions, WebpackGenerateSWOptions as WorkboxGenerateSWOptions, WebpackInjectManifestOptions as WorkboxInjectManifestOptions } from 'workbox-build';
|
|
12
12
|
import type OfflinePlugin from 'workbox-webpack-plugin';
|
|
13
13
|
export interface Browser {
|
|
14
14
|
debug: boolean;
|
package/type.js
CHANGED
|
@@ -16,31 +16,18 @@
|
|
|
16
16
|
endregion
|
|
17
17
|
*/
|
|
18
18
|
// region imports
|
|
19
|
-
import { AnyFunction, Encoding, Mapping, PlainObject, SecondParameter } from 'clientnode';
|
|
20
|
-
import { FaviconWebpackPlugionOptions as FaviconWebpackPluginOptions } from 'favicons-webpack-plugin/src/options';
|
|
21
|
-
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
|
22
|
-
import { PluginOptions as ImageMinimizerOptions } from 'image-minimizer-webpack-plugin';
|
|
23
|
-
import { JSDOM } from 'jsdom';
|
|
24
|
-
import { DefinePlugin as WebpackDefinePlugin, Configuration as BaseWebpackConfiguration, IgnorePlugin as WebpackIgnorePlugin, library as webpackLibrary, ModuleOptions as WebpackModuleOptions, RuleSetRule as WebpackRuleSetRule, RuleSetUseItem as WebpackRuleSetUseItem, WebpackOptionsNormalized } from 'webpack';
|
|
25
|
-
import { WebpackPartial as WorkboxBaseCommonOptions, BasePartial as WorkboxCommonOptions, WebpackGenerateSWOptions as WorkboxGenerateSWOptions, WebpackInjectManifestOptions as WorkboxInjectManifestOptions } from 'workbox-build';
|
|
26
|
-
|
|
27
19
|
// endregion
|
|
28
20
|
// region exports
|
|
29
21
|
/// region generic
|
|
30
|
-
|
|
31
22
|
/// endregion
|
|
32
23
|
/// region injection
|
|
33
|
-
|
|
34
24
|
/// endregion
|
|
35
25
|
/// region configuration
|
|
36
26
|
// region plugins
|
|
37
|
-
|
|
38
27
|
// endregion
|
|
39
28
|
//// region path
|
|
40
|
-
|
|
41
29
|
//// endregion
|
|
42
30
|
//// region build
|
|
43
|
-
|
|
44
31
|
export const SubConfigurationTypes = ['debug', 'document', 'test', 'test:browser'];
|
|
45
32
|
export const TaskTypes = ['build', 'serve', ...SubConfigurationTypes];
|
|
46
33
|
//// endregion
|
package/webpackConfigurator.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export declare const log: Logger;
|
|
4
|
-
export declare const optionalRequire: <T = unknown>(id: string) => null | T;
|
|
1
|
+
import type { WebpackConfiguration } from './type';
|
|
2
|
+
export declare const log: any;
|
|
5
3
|
export declare let webpackConfiguration: WebpackConfiguration;
|
|
6
4
|
export default webpackConfiguration;
|
package/webpackConfigurator.js
CHANGED
|
@@ -16,54 +16,107 @@
|
|
|
16
16
|
endregion
|
|
17
17
|
*/
|
|
18
18
|
// region imports
|
|
19
|
+
const _rewrite = (specifier, options) => {
|
|
20
|
+
if (typeof specifier !== 'string') {
|
|
21
|
+
throw new TypeError(`rewrite error: expected specifier of type string, not ${typeof specifier}`);
|
|
22
|
+
}
|
|
23
|
+
let replacementMap;
|
|
24
|
+
if (options.replaceExtensions) {
|
|
25
|
+
Object.entries(options.replaceExtensions).some(([target, replacement]) => {
|
|
26
|
+
if (target.startsWith('^') || target.endsWith('$')) {
|
|
27
|
+
const targetRegExp = new RegExp(target);
|
|
28
|
+
const capturingGroups = Array.from(specifier.match(targetRegExp) || []);
|
|
29
|
+
if (capturingGroups.length) {
|
|
30
|
+
replacementMap = [targetRegExp, replacement, capturingGroups];
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
} else if (specifier.endsWith(target)) {
|
|
34
|
+
replacementMap = [target, replacement, []];
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
let finalImportPath = specifier;
|
|
40
|
+
if (replacementMap) {
|
|
41
|
+
const [target, replacement, capturingGroups] = replacementMap;
|
|
42
|
+
finalImportPath = finalImportPath.replace(target, typeof replacement === 'string' ? replacement : replacement({
|
|
43
|
+
specifier,
|
|
44
|
+
capturingGroups,
|
|
45
|
+
filepath: '/__w/weboptimizer/weboptimizer/webpackConfigurator.ts'
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
const isRelative = finalImportPath.startsWith('./') || finalImportPath.startsWith('.\\') || finalImportPath.startsWith('../') || finalImportPath.startsWith('..\\') || finalImportPath === '.' || finalImportPath === '..';
|
|
49
|
+
if (options.appendExtension && isRelative) {
|
|
50
|
+
const endsWithSlash = /(\/|\\)$/.test(finalImportPath);
|
|
51
|
+
const basenameIsDots = /(^\.?\.(\/|\\)?$)|((\/|\\)\.?\.(\/|\\)?$)/.test(finalImportPath);
|
|
52
|
+
const extensionToAppend = typeof options.appendExtension === 'string' ? options.appendExtension : options.appendExtension({
|
|
53
|
+
specifier,
|
|
54
|
+
capturingGroups: [],
|
|
55
|
+
filepath: '/__w/weboptimizer/weboptimizer/webpackConfigurator.ts'
|
|
56
|
+
});
|
|
57
|
+
if (extensionToAppend !== undefined) {
|
|
58
|
+
if (basenameIsDots) {
|
|
59
|
+
finalImportPath += `${endsWithSlash ? '' : '/'}index${extensionToAppend}`;
|
|
60
|
+
} else {
|
|
61
|
+
const hasRecognizedExtension = !endsWithSlash && options.recognizedExtensions.some(extension => {
|
|
62
|
+
return finalImportPath.endsWith(extension);
|
|
63
|
+
});
|
|
64
|
+
if (!hasRecognizedExtension) {
|
|
65
|
+
finalImportPath = endsWithSlash ? finalImportPath + `index${extensionToAppend}` : finalImportPath + extensionToAppend;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return finalImportPath;
|
|
71
|
+
},
|
|
72
|
+
_rewrite_options = {
|
|
73
|
+
"appendExtension": ".js",
|
|
74
|
+
"recognizedExtensions": [".js", ".jsx", ".d.ts", ".ts", ".tsx", ".json"]
|
|
75
|
+
};
|
|
19
76
|
import "core-js/modules/es.array.push.js";
|
|
20
|
-
import "core-js/modules/es.array.unshift.js";
|
|
21
77
|
import "core-js/modules/es.iterator.constructor.js";
|
|
22
78
|
import "core-js/modules/es.iterator.filter.js";
|
|
23
79
|
import "core-js/modules/es.iterator.map.js";
|
|
24
|
-
import
|
|
25
|
-
import {
|
|
80
|
+
import "core-js/modules/es.iterator.some.js";
|
|
81
|
+
import { convertToValidVariableName, evaluate, escapeRegularExpressions, extend, importsPromise, isFileSync, isObject, isPlainObject, Logger, mask, optionalImport, represent } from 'clientnode';
|
|
26
82
|
import { extname, join, relative, resolve } from 'path';
|
|
27
|
-
import { Transformer as PostcssTransformer } from 'postcss';
|
|
28
|
-
import PostcssNode from 'postcss/lib/node';
|
|
29
83
|
import util from 'util';
|
|
30
|
-
import
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
84
|
+
import webpack from 'webpack';
|
|
85
|
+
const {
|
|
86
|
+
Compilation,
|
|
87
|
+
ContextReplacementPlugin,
|
|
88
|
+
DefinePlugin,
|
|
89
|
+
HotModuleReplacementPlugin,
|
|
90
|
+
IgnorePlugin,
|
|
91
|
+
NormalModuleReplacementPlugin,
|
|
92
|
+
ProvidePlugin
|
|
93
|
+
} = webpack;
|
|
94
|
+
import webpackSources from 'webpack-sources';
|
|
95
|
+
const {
|
|
96
|
+
RawSource: WebpackRawSource
|
|
97
|
+
} = webpackSources;
|
|
98
|
+
import getConfiguration, { require } from "./configurator.js";
|
|
99
|
+
import { determineAssetType, determineExternalRequest, determineModuleFilePath, getClosestPackageDescriptor, isFilePathInLocation, normalizePaths, stripLoader } from "./helper.js";
|
|
100
|
+
import InPlaceAssetsIntoHTML from "./plugins/InPlaceAssetsIntoHTML.js";
|
|
101
|
+
import HTMLTransformation from "./plugins/HTMLTransformation.js";
|
|
102
|
+
|
|
103
|
+
// Wait until optional filesystem modules have been loaded.
|
|
104
|
+
await importsPromise;
|
|
105
|
+
|
|
106
|
+
/// region optional imports
|
|
107
|
+
const postcssCSSnano = await optionalImport('cssnano');
|
|
108
|
+
const postcssFontpath = await optionalImport('postcss-fontpath');
|
|
109
|
+
const postcssImport = await optionalImport('postcss-import');
|
|
110
|
+
const postcssSprites = await optionalImport('postcss-sprites');
|
|
111
|
+
const updateRule = (await optionalImport('postcss-sprites/lib/core'))?.updateRule;
|
|
112
|
+
const postcssURL = await optionalImport('postcss-url');
|
|
113
|
+
/// endregion
|
|
39
114
|
export const log = new Logger({
|
|
40
115
|
name: 'weboptimizer.webpack-configurator'
|
|
41
116
|
});
|
|
42
117
|
Logger.configureAllInstances({
|
|
43
118
|
level: ['debug', 'development'].includes(process.env.NODE_ENV ?? '') ? 'debug' : 'warn'
|
|
44
119
|
});
|
|
45
|
-
/// region optional imports
|
|
46
|
-
// NOTE: Has to be defined here to ensure to resolve from here.
|
|
47
|
-
const currentRequire =
|
|
48
|
-
/*
|
|
49
|
-
typeof __non_webpack_require__ === 'function' ?
|
|
50
|
-
__non_webpack_require__ :
|
|
51
|
-
*/
|
|
52
|
-
eval(`typeof require === 'undefined' ? null : require`);
|
|
53
|
-
export const optionalRequire = id => {
|
|
54
|
-
try {
|
|
55
|
-
return currentRequire ? currentRequire(id) : null;
|
|
56
|
-
} catch {
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
const postcssCSSnano = optionalRequire('cssnano');
|
|
61
|
-
const postcssFontpath = optionalRequire('postcss-fontpath');
|
|
62
|
-
const postcssImport = optionalRequire('postcss-import');
|
|
63
|
-
const postcssSprites = optionalRequire('postcss-sprites');
|
|
64
|
-
const updateRule = optionalRequire('postcss-sprites/lib/core')?.updateRule;
|
|
65
|
-
const postcssURL = optionalRequire('postcss-url');
|
|
66
|
-
/// endregion
|
|
67
120
|
const pluginNameResourceMapping = {
|
|
68
121
|
Favicon: 'favicons-webpack-plugin',
|
|
69
122
|
ImageMinimizer: 'image-minimizer-webpack-plugin',
|
|
@@ -74,11 +127,13 @@ const pluginNameResourceMapping = {
|
|
|
74
127
|
};
|
|
75
128
|
const plugins = {};
|
|
76
129
|
for (const [name, alias] of Object.entries(pluginNameResourceMapping)) {
|
|
77
|
-
const plugin =
|
|
78
|
-
if (plugin)
|
|
130
|
+
const plugin = await optionalImport(alias);
|
|
131
|
+
if (plugin) {
|
|
132
|
+
if ('default' in plugin) plugins[name] = plugin.default;else plugins[name] = plugin;
|
|
133
|
+
} else log.debug(`Optional webpack plugin "${name}" not available.`);
|
|
79
134
|
}
|
|
80
135
|
// endregion
|
|
81
|
-
const configuration = getConfiguration();
|
|
136
|
+
const configuration = await getConfiguration();
|
|
82
137
|
Logger.configureAllInstances({
|
|
83
138
|
level: configuration.debug ? 'debug' : 'warn'
|
|
84
139
|
});
|
|
@@ -169,14 +224,14 @@ pluginInstances.push({
|
|
|
169
224
|
}
|
|
170
225
|
});
|
|
171
226
|
///// endregion
|
|
172
|
-
///// region in-place configured assets in the main
|
|
227
|
+
///// region in-place configured assets in the main HTML file
|
|
173
228
|
if (plugins.HTML && htmlAvailable && !['serve', 'test:browser'].includes(configuration.givenCommandLineArguments[2]) && configuration.inPlace.cascadingStyleSheet && Object.keys(configuration.inPlace.cascadingStyleSheet).length || configuration.inPlace.javaScript && Object.keys(configuration.inPlace.javaScript).length) pluginInstances.push(new InPlaceAssetsIntoHTML({
|
|
174
229
|
cascadingStyleSheet: configuration.inPlace.cascadingStyleSheet,
|
|
175
230
|
javaScript: configuration.inPlace.javaScript,
|
|
176
231
|
htmlPlugin: plugins.HTML
|
|
177
232
|
}));
|
|
178
233
|
///// endregion
|
|
179
|
-
///// region mark empty
|
|
234
|
+
///// region mark empty JavaScript modules as dummy
|
|
180
235
|
if (!(configuration.needed.javaScript || configuration.needed.javaScriptExtension || configuration.needed.typeScript || configuration.needed.typeScriptExtension)) configuration.files.compose.javaScript = resolve(configuration.path.target.asset.javaScript, '.__dummy__.compiled.js');
|
|
181
236
|
///// endregion
|
|
182
237
|
///// region extract cascading style sheets
|
|
@@ -191,7 +246,7 @@ if (configuration.injection.external.modules === '__implicit__')
|
|
|
191
246
|
We only want to process modules from local context in library mode,
|
|
192
247
|
since a concrete project using this library should combine all assets
|
|
193
248
|
(and de-duplicate them) for optimal bundling results.
|
|
194
|
-
NOTE: Only native
|
|
249
|
+
NOTE: Only native JavaScript and json modules will be marked as
|
|
195
250
|
external dependency.
|
|
196
251
|
*/
|
|
197
252
|
configuration.injection.external.modules = ({
|
|
@@ -257,7 +312,7 @@ if (configuration.injection.external.modules === '__implicit__')
|
|
|
257
312
|
};
|
|
258
313
|
///// endregion
|
|
259
314
|
//// endregion
|
|
260
|
-
//// region apply final
|
|
315
|
+
//// region apply final HTML modifications/fixes
|
|
261
316
|
if (htmlAvailable && plugins.HTML) pluginInstances.push(new HTMLTransformation({
|
|
262
317
|
hashAlgorithm: configuration.hashAlgorithm,
|
|
263
318
|
htmlPlugin: plugins.HTML,
|
|
@@ -268,8 +323,7 @@ if (htmlAvailable && plugins.HTML) pluginInstances.push(new HTMLTransformation({
|
|
|
268
323
|
for (const contextReplacement of module.replacements.context) pluginInstances.push(new ContextReplacementPlugin(...contextReplacement.map(value => {
|
|
269
324
|
const evaluated = evaluate(value, {
|
|
270
325
|
configuration,
|
|
271
|
-
|
|
272
|
-
__filename
|
|
326
|
+
metaImport: import.meta
|
|
273
327
|
});
|
|
274
328
|
if (evaluated.error) throw new Error('Error occurred during processing given context ' + `replacement: ${evaluated.error}`);
|
|
275
329
|
return evaluated.result;
|
|
@@ -279,7 +333,7 @@ for (const contextReplacement of module.replacements.context) pluginInstances.pu
|
|
|
279
333
|
/*
|
|
280
334
|
NOTE: Redundancies usually occur when symlinks aren't converted to their
|
|
281
335
|
real paths since real paths can be de-duplicated by webpack but if two
|
|
282
|
-
linked modules share the same transitive dependency webpack
|
|
336
|
+
linked modules share the same transitive dependency webpack won't recognize
|
|
283
337
|
them as same dependency.
|
|
284
338
|
*/
|
|
285
339
|
if (module.enforceDeduplication) {
|
|
@@ -444,7 +498,7 @@ const scope = {
|
|
|
444
498
|
configuration,
|
|
445
499
|
isFilePathInDependencies,
|
|
446
500
|
loader,
|
|
447
|
-
require
|
|
501
|
+
require
|
|
448
502
|
};
|
|
449
503
|
const evaluateAnThrow = (object, givenOptions = {}) => {
|
|
450
504
|
const options = {
|
|
@@ -486,7 +540,7 @@ const cssUse = module.preprocessor.cascadingStyleSheet.additional.pre.map(create
|
|
|
486
540
|
options: module.cascadingStyleSheet.options || {}
|
|
487
541
|
}, module.preprocessor.cascadingStyleSheet.loader ? {
|
|
488
542
|
loader: module.preprocessor.cascadingStyleSheet.loader,
|
|
489
|
-
options: extend(true,
|
|
543
|
+
options: extend(true, (await optionalImport('postcss')) ? {
|
|
490
544
|
postcssOptions: {
|
|
491
545
|
/*
|
|
492
546
|
NOTE: Some plugins like "postcss-import" are
|
|
@@ -583,7 +637,7 @@ const genericLoader = {
|
|
|
583
637
|
}, module.preprocessor.javaScript.additional.post.map(createEvaluateMapper('script')))
|
|
584
638
|
},
|
|
585
639
|
// endregion
|
|
586
|
-
// region
|
|
640
|
+
// region HTML template
|
|
587
641
|
html: {
|
|
588
642
|
// NOTE: This is only for the main entry template.
|
|
589
643
|
main: {
|
|
@@ -778,7 +832,7 @@ const genericLoader = {
|
|
|
778
832
|
extend(loader, genericLoader);
|
|
779
833
|
if (configuration.files.compose.cascadingStyleSheet && plugins.MiniCSSExtract) {
|
|
780
834
|
/*
|
|
781
|
-
NOTE: We have to remove the client side
|
|
835
|
+
NOTE: We have to remove the client side JavaScript hmr style loader
|
|
782
836
|
first.
|
|
783
837
|
*/
|
|
784
838
|
loader.style.use.shift();
|
|
@@ -805,7 +859,7 @@ if (htmlAvailable && configuration.debug && configuration.development.server.liv
|
|
|
805
859
|
// endregion
|
|
806
860
|
// region plugins
|
|
807
861
|
for (const pluginConfiguration of configuration.plugins) {
|
|
808
|
-
const plugin =
|
|
862
|
+
const plugin = await optionalImport(pluginConfiguration.name.module);
|
|
809
863
|
if (plugin) pluginInstances.push(new plugin[pluginConfiguration.name.initializer](...pluginConfiguration.parameters));else log.warn(`Configured plugin module "${pluginConfiguration.name.module}"`, 'could not be loaded.');
|
|
810
864
|
}
|
|
811
865
|
// endregion
|
|
@@ -828,9 +882,9 @@ if (!module.optimizer.minimizer) {
|
|
|
828
882
|
// region configuration
|
|
829
883
|
let customConfiguration = {};
|
|
830
884
|
if (configuration.path.configuration.json) try {
|
|
831
|
-
require.resolve(configuration.path.configuration.json);
|
|
885
|
+
require.resolve(_rewrite(configuration.path.configuration.json, _rewrite_options));
|
|
832
886
|
try {
|
|
833
|
-
customConfiguration =
|
|
887
|
+
customConfiguration = require(_rewrite(configuration.path.configuration.json, _rewrite_options));
|
|
834
888
|
} catch (error) {
|
|
835
889
|
log.debug('Importing provided json webpack configuration file path', `under "${configuration.path.configuration.json}" failed:`, represent(error));
|
|
836
890
|
}
|
|
@@ -941,8 +995,8 @@ if (!Array.isArray(module.skipParseRegularExpressions) || module.skipParseRegula
|
|
|
941
995
|
noParse: module.skipParseRegularExpressions
|
|
942
996
|
};
|
|
943
997
|
if (configuration.path.configuration.javaScript) try {
|
|
944
|
-
require.resolve(configuration.path.configuration.javaScript);
|
|
945
|
-
const result =
|
|
998
|
+
require.resolve(_rewrite(configuration.path.configuration.javaScript, _rewrite_options));
|
|
999
|
+
const result = await optionalImport(configuration.path.configuration.javaScript);
|
|
946
1000
|
if (isPlainObject(result)) {
|
|
947
1001
|
if (Object.prototype.hasOwnProperty.call(result, 'replaceWebOptimizer')) webpackConfiguration = result.replaceWebOptimizer;else extend(true, webpackConfiguration, result);
|
|
948
1002
|
} else log.debug('Failed to load given JavaScript configuration file path', `"${configuration.path.configuration.javaScript}".`);
|