weboptimizer 4.0.3 → 4.0.5

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 CHANGED
@@ -1,5 +1,5 @@
1
- import { Logger } from 'clientnode';
2
1
  import { Browser, InitializedBrowser } from './type';
2
+ import { Logger } from 'clientnode';
3
3
  export declare const browser: Browser;
4
4
  export declare const log: Logger;
5
5
  /**
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 { CONSOLE_METHODS, Logger, ProcedureFunction, timeout } from 'clientnode';
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
24
  import { LoaderConfiguration } from "./ejsLoader.js";
24
- import { Browser, InitializedBrowser } from "./type.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(__dirname, 'index.html.ejs');
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,9 @@
1
1
  import type { ResolvedConfiguration } from './type';
2
- import clientnode from 'clientnode';
2
+ import { Logger } from 'clientnode';
3
+ export declare const require: NodeJS.Require;
4
+ export declare const optionalRequire: <T = unknown>(id: string) => null | T;
3
5
  export declare let loadedConfiguration: null | ResolvedConfiguration;
4
- export declare const log: clientnode.Logger;
6
+ export declare const log: Logger;
5
7
  /**
6
8
  * Main entry point to determine current configuration.
7
9
  * @param context - Location from where to build current application.
@@ -12,10 +14,10 @@ export declare const log: clientnode.Logger;
12
14
  * @param environment - Environment variables to take into account.
13
15
  * @returns Nothing.
14
16
  */
15
- export declare const load: (context?: string, currentWorkingDirectory?: string, commandLineArguments?: Array<string>, webOptimizerPath?: string, environment?: NodeJS.ProcessEnv) => ResolvedConfiguration;
17
+ export declare const load: (context?: string, currentWorkingDirectory?: string, commandLineArguments?: Array<string>, webOptimizerPath?: string, environment?: NodeJS.ProcessEnv) => Promise<ResolvedConfiguration>;
16
18
  /**
17
19
  * Get cached or determined configuration object.
18
20
  * @returns Nothing.
19
21
  */
20
- export declare const get: () => ResolvedConfiguration;
22
+ export declare const get: () => Promise<ResolvedConfiguration>;
21
23
  export default get;
package/configurator.js CHANGED
@@ -16,36 +16,84 @@
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 clientnode from 'clientnode';
24
- const {
25
- convertCircularObjectToJSON,
26
- copy,
27
- currentRequire,
28
- evaluateDynamicData,
29
- extend,
30
- getUTCTimestamp,
31
- isFileSync,
32
- isObject,
33
- isolatedRequire,
34
- isPlainObject,
35
- Logger,
36
- MAXIMAL_NUMBER_OF_ITERATIONS,
37
- modifyObject,
38
- optionalRequire,
39
- parseEncodedObject,
40
- removeKeyPrefixes,
41
- UTILITY_SCOPE
42
- } = clientnode;
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';
43
82
  import fileSystem, { lstatSync, readFileSync, unlinkSync } from 'fs';
83
+ import { createRequire } from 'node:module';
44
84
  import path, { basename, dirname, join, resolve } from 'path';
45
85
  import { determineAssetType, determineModuleFilePath, determineModuleLocations, resolveAutoInjection, resolveBuildConfigurationFilePaths, resolveModulesInFolders, normalizeGivenInjection, normalizePaths } from "./helper.js";
46
86
  import packageConfiguration from './package.json' with { type: 'json' };
47
87
  import { SubConfigurationTypes } from "./type.js";
48
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
+ };
49
97
  const {
50
98
  configuration: metaConfiguration
51
99
  } = packageConfiguration;
@@ -53,6 +101,10 @@ export let loadedConfiguration = null;
53
101
  export const log = new Logger({
54
102
  name: 'weboptimizer.configurator'
55
103
  });
104
+
105
+ // Wait until optional filesystem modules have been loaded.
106
+ await importsPromise;
107
+
56
108
  /**
57
109
  * Main entry point to determine current configuration.
58
110
  * @param context - Location from where to build current application.
@@ -63,7 +115,7 @@ export const log = new Logger({
63
115
  * @param environment - Environment variables to take into account.
64
116
  * @returns Nothing.
65
117
  */
66
- export const load = (context, currentWorkingDirectory = process.cwd(), commandLineArguments = process.argv, webOptimizerPath = __dirname,
118
+ export const load = async (context, currentWorkingDirectory = process.cwd(), commandLineArguments = process.argv, webOptimizerPath = import.meta.dirname,
67
119
  /*
68
120
  NOTE: We have to avoid that some pre-processor removes this
69
121
  assignment.
@@ -107,8 +159,11 @@ environment = eval('process.env')) => {
107
159
  // region load application specific configuration
108
160
  let specificConfiguration = {};
109
161
  try {
110
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
111
- specificConfiguration = currentRequire(join(metaConfiguration.default.path.context, 'package'));
162
+ specificConfiguration = (await optionalImport(join(metaConfiguration.default.path.context, 'package.json'), {
163
+ with: {
164
+ type: 'json'
165
+ }
166
+ })).default;
112
167
  } catch {
113
168
  metaConfiguration.default.path.context = currentWorkingDirectory;
114
169
  }
@@ -196,16 +251,18 @@ environment = eval('process.env')) => {
196
251
  transformed in place in the following lines of code.
197
252
  */
198
253
  const resolvedConfiguration = evaluateDynamicData(configuration, {
199
- ...UTILITY_SCOPE,
200
- currentPath: currentWorkingDirectory,
201
- fs: fileSystem,
202
- packageConfiguration,
203
- optionalRequire,
204
- path,
205
- require: isolatedRequire,
206
- webOptimizerPath,
207
- now,
208
- nowUTCTimestamp: getUTCTimestamp(now)
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
+ }
209
266
  });
210
267
  // endregion
211
268
  // region consolidate file specific build configuration
@@ -239,7 +296,7 @@ environment = eval('process.env')) => {
239
296
  file: resolvedConfiguration.extensions.file.internal
240
297
  }, resolvedConfiguration.path.context,
241
298
  /*
242
- NOTE: We doesn't use
299
+ NOTE: We don't use
243
300
  "resolvedConfiguration.path.source.asset.base" because we
244
301
  already have resolved all module ids.
245
302
  */
@@ -263,7 +320,7 @@ environment = eval('process.env')) => {
263
320
  }
264
321
  resolvedConfiguration.module.aliases.webOptimizerDefaultTemplateFilePath = resolvedConfiguration.files.defaultHTML.template.filePath;
265
322
  // endregion
266
- // region apply html webpack plugin workarounds
323
+ // region apply HTML webpack plugin workarounds
267
324
  /*
268
325
  NOTE: Provides a workaround to handle a bug with chained loader
269
326
  configurations.
@@ -284,9 +341,8 @@ environment = eval('process.env')) => {
284
341
  * Get cached or determined configuration object.
285
342
  * @returns Nothing.
286
343
  */
287
- export const get = () => {
288
- if (loadedConfiguration) return loadedConfiguration;
289
- loadedConfiguration = load();
344
+ export const get = async () => {
345
+ if (!loadedConfiguration) loadedConfiguration = await load();
290
346
  return loadedConfiguration;
291
347
  };
292
348
  export default get;
package/ejsLoader.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- import { Encoding, Logger, Mapping } from 'clientnode';
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
+ import { Logger } from 'clientnode';
5
6
  export type TemplateFunction = EJSTemplateFunction;
6
7
  export type CompilerOptions = Options & {
7
8
  encoding: Encoding;
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 imports
19
- import { FileResult, transformSync as babelTransformSync } from '@babel/core';
18
+ // region
19
+ import { transformSync as babelTransformSync } from '@babel/core';
20
20
  import babelMinifyPreset from 'babel-preset-minify';
21
- import { convertSubstringInPlainObject, copy, currentRequire, evaluate, EvaluationResult, Encoding, extend, Logger, Mapping, RecursivePartial, UTILITY_SCOPE } from 'clientnode';
22
- import ejs, { Options, TemplateFunction as EJSTemplateFunction } from '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 { LoaderContext } from 'webpack';
27
26
  import getConfiguration from "./configurator.js";
28
27
  import { determineModuleFilePath } from "./helper.js";
29
- import { Extensions, Replacements, ResolvedConfiguration } from "./type.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,8 +1,8 @@
1
1
  import type { Encoding, Mapping } from 'clientnode';
2
2
  import type { BuildConfiguration, Extensions, GivenInjection, GivenInjectionConfiguration, NormalizedGivenInjection, PathConfiguration, PackageDescriptor, Replacements, ResolvedBuildConfiguration, SpecificExtensions } from './type';
3
- import clientnode from 'clientnode';
3
+ import { Logger } from 'clientnode';
4
4
  export declare const KNOWN_FILE_EXTENSIONS: Array<string>;
5
- export declare const log: clientnode.Logger;
5
+ export declare const log: Logger;
6
6
  /**
7
7
  * Determines whether given file path is within given list of file locations.
8
8
  * @param filePath - Path to file to check.
package/helper.js CHANGED
@@ -27,20 +27,7 @@ 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 clientnode from 'clientnode';
31
- const {
32
- copy,
33
- currentRequire,
34
- escapeRegularExpressions,
35
- extend,
36
- isAnyMatching,
37
- isDirectorySync,
38
- isFileSync,
39
- isPlainObject,
40
- Logger,
41
- represent,
42
- walkDirectoryRecursivelySync
43
- } = clientnode;
30
+ import { copy, currentRequire, escapeRegularExpressions, extend, isAnyMatching, isDirectorySync, isFileSync, isPlainObject, Logger, represent, walkDirectoryRecursivelySync } from 'clientnode';
44
31
  import { existsSync, readFileSync } from 'fs';
45
32
  import { basename, dirname, extname, join, normalize, resolve, sep, relative } from 'path';
46
33
  // endregion
package/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env babel-node
2
- import clientnode from 'clientnode';
3
- export declare const log: clientnode.Logger;
2
+ import { Logger } from 'clientnode';
3
+ export declare const log: Logger;
4
4
  /**
5
5
  * Main entry point.
6
6
  * @param context - Location from where to build current application.
package/index.js CHANGED
@@ -24,28 +24,10 @@ 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
26
  import { exec as execChildProcess, spawn as spawnChildProcess } from 'child_process';
27
- import clientnode from 'clientnode';
28
- const {
29
- CLOSE_EVENT_NAMES,
30
- copyDirectoryRecursiveSync,
31
- copyFileSync,
32
- evaluate,
33
- getProcessCloseHandler,
34
- handleChildProcess,
35
- isDirectory,
36
- isDirectorySync,
37
- isFile,
38
- isFileSync,
39
- isPlainObject,
40
- Logger,
41
- MAXIMAL_NUMBER_OF_ITERATIONS,
42
- NOOP,
43
- parseEncodedObject,
44
- walkDirectoryRecursively
45
- } = clientnode;
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';
46
28
  import { chmodSync, unlinkSync } from 'fs';
47
29
  import { writeFile, unlink } from 'fs/promises';
48
- import globAll from 'glob-all';
30
+ import { sync as globAllSync } from 'glob-all';
49
31
  import path, { join, resolve } from 'path';
50
32
  import { rimraf as removeDirectoryRecursively, sync as removeDirectoryRecursivelySync } from 'rimraf';
51
33
  import { load as loadConfiguration } from "./configurator.js";
@@ -59,6 +41,10 @@ Logger.configureAllInstances({
59
41
  });
60
42
  // NOTE: Environment variables can only be strings.
61
43
  process.env.UV_THREADPOOL_SIZE = '128';
44
+
45
+ // Wait until optional filesystem modules have been loaded.
46
+ await importsPromise;
47
+
62
48
  /**
63
49
  * Main entry point.
64
50
  * @param context - Location from where to build current application.
@@ -69,14 +55,14 @@ process.env.UV_THREADPOOL_SIZE = '128';
69
55
  * @param environment - Environment variables to take into account.
70
56
  * @returns Nothing.
71
57
  */
72
- const main = async (context, currentWorkingDirectory = process.cwd(), commandLineArguments = process.argv, webOptimizerPath = __dirname,
58
+ const main = async (context, currentWorkingDirectory = process.cwd(), commandLineArguments = process.argv, webOptimizerPath = import.meta.dirname,
73
59
  /*
74
60
  NOTE: We have to avoid that some pre-processor removes this
75
61
  assignment.
76
62
  */
77
63
  environment = eval('process.env')) => {
78
64
  if (environment.PATH && !environment.PATH.includes(':node_modules/.bin')) environment.PATH += ':node_modules/.bin';else environment.PATH = 'node_modules/.bin';
79
- const configuration = loadConfiguration(context, currentWorkingDirectory, commandLineArguments, webOptimizerPath, environment);
65
+ const configuration = await loadConfiguration(context, currentWorkingDirectory, commandLineArguments, webOptimizerPath, environment);
80
66
  let clear = NOOP();
81
67
  try {
82
68
  // region controller
@@ -119,7 +105,7 @@ environment = eval('process.env')) => {
119
105
  // endregion
120
106
  // region handle clear
121
107
  /*
122
- NOTE: Some tasks could depend on previously created artefacts
108
+ NOTE: Some tasks could depend on previously created artifacts
123
109
  packages so a preceding clear should not be performed in that
124
110
  cases.
125
111
  NOTE: If we have a dependency cycle we need to preserve files
@@ -127,7 +113,7 @@ environment = eval('process.env')) => {
127
113
  */
128
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]) ||
129
115
  /*
130
- NOTE: If target artefacts are located next to their
116
+ NOTE: If target artifacts are located next to their
131
117
  source files, we need to clear them first when running
132
118
  dev mode (watching source files and reloading build
133
119
  automatically).
@@ -152,7 +138,7 @@ environment = eval('process.env')) => {
152
138
  for (const filePath of configuration.path.tidyUpOnClear) if (filePath) if (isFileSync(filePath))
153
139
  // NOTE: Close handler have to be synchronous.
154
140
  unlinkSync(filePath);else if (isDirectorySync(filePath)) removeDirectoryRecursivelySync(filePath);
155
- removeDirectoryRecursivelySync(globAll.sync(configuration.path.tidyUpOnClearGlobs));
141
+ removeDirectoryRecursivelySync(globAllSync(configuration.path.tidyUpOnClearGlobs));
156
142
  }
157
143
  // endregion
158
144
  // region handle build
@@ -186,7 +172,7 @@ environment = eval('process.env')) => {
186
172
  for (const filePath of configuration.path.tidyUp) if (filePath) if (isFileSync(filePath))
187
173
  // NOTE: Close handler have to be synchronous.
188
174
  unlinkSync(filePath);else if (isDirectorySync(filePath)) removeDirectoryRecursivelySync(filePath);
189
- removeDirectoryRecursivelySync(globAll.sync(configuration.path.tidyUpGlobs));
175
+ removeDirectoryRecursivelySync(globAllSync(configuration.path.tidyUpGlobs));
190
176
  };
191
177
  closeEventHandlers.push(tidyUp);
192
178
 
@@ -293,7 +279,7 @@ environment = eval('process.env')) => {
293
279
  finished = true;
294
280
  };
295
281
  for (const closeEventName of CLOSE_EVENT_NAMES) process.on(closeEventName, closeHandler);
296
- if (require.main === module && (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');
282
+ 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');
297
283
  // endregion
298
284
  // region forward nested return codes
299
285
  try {
@@ -308,5 +294,5 @@ environment = eval('process.env')) => {
308
294
  }
309
295
  return clear;
310
296
  };
311
- if (require.main === module) void main();
297
+ if (import.meta.main) void main();
312
298
  export default main;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "weboptimizer",
3
- "version": "4.0.3",
3
+ "version": "4.0.5",
4
4
  "description": "A generic web optimizer, (module) bundler and development environment.",
5
5
  "keywords": [
6
6
  "webpack",
@@ -95,7 +95,7 @@
95
95
  "babel-plugin-polyfill-corejs3": "^1.0.0",
96
96
  "babel-plugin-transform-rewrite-imports": "^1.5.4",
97
97
  "babel-preset-minify": "^0.5.2",
98
- "clientnode": "4.0.1428",
98
+ "clientnode": "4.0.1432",
99
99
  "core-js": "^3.49.0",
100
100
  "ejs": "^6.0.1",
101
101
  "exports-loader": "^5.0.0",
@@ -109,7 +109,7 @@
109
109
  "rimraf": "^6.1.3",
110
110
  "script-loader": "^0.7.2",
111
111
  "typescript": "^6.0.3",
112
- "webpack": "^5.108.1",
112
+ "webpack": "^5.108.3",
113
113
  "webpack-cli": "^7.1.0",
114
114
  "webpack-sources": "^3.5.0"
115
115
  },
@@ -123,17 +123,17 @@
123
123
  "@types/html-minifier": "^4.0.6",
124
124
  "@types/html-minifier-terser": "^7.0.2",
125
125
  "@types/imagemin": "^9.0.1",
126
- "@types/node": "^26.0.1",
126
+ "@types/node": "^26.1.0",
127
127
  "@types/postcss-import": "^14.0.3",
128
128
  "@types/postcss-url": "^10.0.4",
129
129
  "@types/webpack-env": "^1.18.8",
130
130
  "@types/webpack-sources": "^3.2.3",
131
- "@typescript-eslint/parser": "^8.62.0",
131
+ "@typescript-eslint/parser": "^8.62.1",
132
132
  "css-loader": "^7.1.4",
133
133
  "cssnano": "^8.0.2",
134
- "eslint": "^10.5.0",
134
+ "eslint": "^10.6.0",
135
135
  "eslint-config-google": "^0.14.0",
136
- "eslint-plugin-jsdoc": "^63.0.9",
136
+ "eslint-plugin-jsdoc": "^63.0.10",
137
137
  "favicons": "^7.3.0",
138
138
  "favicons-webpack-plugin": "^6.0.1",
139
139
  "globals": "^17.7.0",
@@ -143,11 +143,11 @@
143
143
  "mini-css-extract-plugin": "^2.10.2",
144
144
  "mkdirp": "^3.0.1",
145
145
  "node-fetch": "^3.3.2",
146
- "postcss": "^8.5.15",
146
+ "postcss": "^8.5.16",
147
147
  "postcss-fontpath": "^1.0.0",
148
148
  "postcss-import": "^16.1.1",
149
149
  "postcss-loader": "^8.2.1",
150
- "postcss-preset-env": "^11.3.1",
150
+ "postcss-preset-env": "^11.3.2",
151
151
  "postcss-sprites": "^4.2.1",
152
152
  "postcss-url": "^10.1.4",
153
153
  "shx": "^0.4.0",
@@ -156,7 +156,7 @@
156
156
  "stylelint-config-standard": "^40.0.0",
157
157
  "stylelint-config-standard-scss": "^17.0.0",
158
158
  "terser-webpack-plugin": "^5.6.1",
159
- "typescript-eslint": "^8.62.0",
159
+ "typescript-eslint": "^8.62.1",
160
160
  "typescript-plugin-css-modules": "^5.2.0",
161
161
  "web-documentation": "^1.0.42",
162
162
  "workbox-webpack-plugin": "^7.4.1"
@@ -1190,24 +1190,11 @@
1190
1190
  }
1191
1191
  ],
1192
1192
  [
1193
- "@babel/plugin-transform-private-methods",
1193
+ "babel-plugin-polyfill-corejs3",
1194
1194
  {
1195
- "loose": true
1195
+ "method": "usage-global"
1196
1196
  }
1197
- ],
1198
- [
1199
- "@babel/plugin-transform-class-properties"
1200
- ],
1201
- [
1202
- "transform-modern-regexp",
1203
- {
1204
- "features": [
1205
- "dotAll",
1206
- "namedCapturingGroups"
1207
- ]
1208
- }
1209
- ],
1210
- "babel-plugin-polyfill-corejs3"
1197
+ ]
1211
1198
  ],
1212
1199
  "presets": {
1213
1200
  "#": "NOTE: We have to disable module export/import transformation to allow tree shaking by the final (minimizer).",
@@ -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, Mapping } from 'clientnode';
23
+ import { copy, extend } from 'clientnode';
24
24
  import HtmlWebpackPlugin from 'html-webpack-plugin';
25
25
  import { JSDOM as DOM } from 'jsdom';
26
- import { Compilation, Compiler, LoaderContext } from 'webpack';
27
- import ejsLoader, { LoaderConfiguration as EJSLoaderConfiguration } from "../ejsLoader.js";
28
- import { HTMLTransformationOptions, HTMLWebpackPluginBeforeEmitData, WebpackLoader } from "../type.js";
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.js";
29
27
  // endregion
30
28
 
31
29
  export class InPlaceAssetsIntoHTML {
@@ -19,6 +19,6 @@
19
19
  import getConfiguration from "./configurator.js";
20
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;
@@ -1,6 +1,5 @@
1
+ import type { WebpackConfiguration } from './type';
1
2
  import { Logger } from 'clientnode';
2
- import { WebpackConfiguration } from './type';
3
3
  export declare const log: Logger;
4
- export declare const optionalRequire: <T = unknown>(id: string) => null | T;
5
4
  export declare let webpackConfiguration: WebpackConfiguration;
6
5
  export default webpackConfiguration;
@@ -78,49 +78,45 @@ import "core-js/modules/es.iterator.constructor.js";
78
78
  import "core-js/modules/es.iterator.filter.js";
79
79
  import "core-js/modules/es.iterator.map.js";
80
80
  import "core-js/modules/es.iterator.some.js";
81
- import { convertToValidVariableName, evaluate, EvaluationResult, escapeRegularExpressions, extend, isFileSync, isObject, isPlainObject, Logger, Mapping, mask, PlainObject, PositiveEvaluationResult, RecursivePartial, represent, Unpacked } from 'clientnode';
82
- import { PluginOptions as ImageMinimizerOptions } from 'image-minimizer-webpack-plugin';
81
+ import { convertToValidVariableName, evaluate, escapeRegularExpressions, extend, importsPromise, isFileSync, isObject, isPlainObject, Logger, mask, optionalImport, represent } from 'clientnode';
83
82
  import { extname, join, relative, resolve } from 'path';
84
- import { Transformer as PostcssTransformer } from 'postcss';
85
- import PostcssNode from 'postcss/lib/node';
86
83
  import util from 'util';
87
- import { Chunk, Compiler, Compilation, ContextReplacementPlugin, DefinePlugin, HotModuleReplacementPlugin, IgnorePlugin, NormalModuleReplacementPlugin, ProvidePlugin, RuleSetRule } from 'webpack';
88
- import { RawSource as WebpackRawSource } from 'webpack-sources';
89
- import { InjectManifestOptions as WorkboxInjectManifestOptions } from 'workbox-build';
90
- import getConfiguration from "./configurator.js";
91
- import { LoaderConfiguration as EJSLoaderConfiguration } from "./ejsLoader.js";
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";
92
99
  import { determineAssetType, determineExternalRequest, determineModuleFilePath, getClosestPackageDescriptor, isFilePathInLocation, normalizePaths, stripLoader } from "./helper.js";
93
100
  import InPlaceAssetsIntoHTML from "./plugins/InPlaceAssetsIntoHTML.js";
94
101
  import HTMLTransformation from "./plugins/HTMLTransformation.js";
95
- import { AdditionalLoaderConfiguration, AssetPathConfiguration, EvaluationScope, GenericLoader, HTMLConfiguration, IgnorePattern, InPlaceConfiguration, Loader, PackageDescriptor, RedundantRequest, ResolvedConfiguration, RuleSet, WebpackConfiguration, WebpackExtendedResolveData, WebpackLoader, WebpackLoaderConfiguration, WebpackLoaderIndicator, WebpackPlugin, WebpackPlugins, WebpackResolveData } from "./type.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
96
114
  export const log = new Logger({
97
115
  name: 'weboptimizer.webpack-configurator'
98
116
  });
99
117
  Logger.configureAllInstances({
100
118
  level: ['debug', 'development'].includes(process.env.NODE_ENV ?? '') ? 'debug' : 'warn'
101
119
  });
102
- /// region optional imports
103
- // NOTE: Has to be defined here to ensure to resolve from here.
104
- const currentRequire =
105
- /*
106
- typeof __non_webpack_require__ === 'function' ?
107
- __non_webpack_require__ :
108
- */
109
- eval(`typeof require === 'undefined' ? null : require`);
110
- export const optionalRequire = id => {
111
- try {
112
- return currentRequire ? currentRequire(id) : null;
113
- } catch {
114
- return null;
115
- }
116
- };
117
- const postcssCSSnano = optionalRequire('cssnano');
118
- const postcssFontpath = optionalRequire('postcss-fontpath');
119
- const postcssImport = optionalRequire('postcss-import');
120
- const postcssSprites = optionalRequire('postcss-sprites');
121
- const updateRule = optionalRequire('postcss-sprites/lib/core')?.updateRule;
122
- const postcssURL = optionalRequire('postcss-url');
123
- /// endregion
124
120
  const pluginNameResourceMapping = {
125
121
  Favicon: 'favicons-webpack-plugin',
126
122
  ImageMinimizer: 'image-minimizer-webpack-plugin',
@@ -131,11 +127,13 @@ const pluginNameResourceMapping = {
131
127
  };
132
128
  const plugins = {};
133
129
  for (const [name, alias] of Object.entries(pluginNameResourceMapping)) {
134
- const plugin = optionalRequire(alias);
135
- if (plugin) plugins[name] = plugin;else log.debug(`Optional webpack plugin "${name}" not available.`);
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.`);
136
134
  }
137
135
  // endregion
138
- const configuration = getConfiguration();
136
+ const configuration = await getConfiguration();
139
137
  Logger.configureAllInstances({
140
138
  level: configuration.debug ? 'debug' : 'warn'
141
139
  });
@@ -226,14 +224,14 @@ pluginInstances.push({
226
224
  }
227
225
  });
228
226
  ///// endregion
229
- ///// region in-place configured assets in the main html file
227
+ ///// region in-place configured assets in the main HTML file
230
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({
231
229
  cascadingStyleSheet: configuration.inPlace.cascadingStyleSheet,
232
230
  javaScript: configuration.inPlace.javaScript,
233
231
  htmlPlugin: plugins.HTML
234
232
  }));
235
233
  ///// endregion
236
- ///// region mark empty javaScript modules as dummy
234
+ ///// region mark empty JavaScript modules as dummy
237
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');
238
236
  ///// endregion
239
237
  ///// region extract cascading style sheets
@@ -248,7 +246,7 @@ if (configuration.injection.external.modules === '__implicit__')
248
246
  We only want to process modules from local context in library mode,
249
247
  since a concrete project using this library should combine all assets
250
248
  (and de-duplicate them) for optimal bundling results.
251
- NOTE: Only native javascript and json modules will be marked as
249
+ NOTE: Only native JavaScript and json modules will be marked as
252
250
  external dependency.
253
251
  */
254
252
  configuration.injection.external.modules = ({
@@ -314,7 +312,7 @@ if (configuration.injection.external.modules === '__implicit__')
314
312
  };
315
313
  ///// endregion
316
314
  //// endregion
317
- //// region apply final html modifications/fixes
315
+ //// region apply final HTML modifications/fixes
318
316
  if (htmlAvailable && plugins.HTML) pluginInstances.push(new HTMLTransformation({
319
317
  hashAlgorithm: configuration.hashAlgorithm,
320
318
  htmlPlugin: plugins.HTML,
@@ -325,8 +323,7 @@ if (htmlAvailable && plugins.HTML) pluginInstances.push(new HTMLTransformation({
325
323
  for (const contextReplacement of module.replacements.context) pluginInstances.push(new ContextReplacementPlugin(...contextReplacement.map(value => {
326
324
  const evaluated = evaluate(value, {
327
325
  configuration,
328
- __dirname,
329
- __filename
326
+ metaImport: import.meta
330
327
  });
331
328
  if (evaluated.error) throw new Error('Error occurred during processing given context ' + `replacement: ${evaluated.error}`);
332
329
  return evaluated.result;
@@ -336,7 +333,7 @@ for (const contextReplacement of module.replacements.context) pluginInstances.pu
336
333
  /*
337
334
  NOTE: Redundancies usually occur when symlinks aren't converted to their
338
335
  real paths since real paths can be de-duplicated by webpack but if two
339
- linked modules share the same transitive dependency webpack wont recognize
336
+ linked modules share the same transitive dependency webpack won't recognize
340
337
  them as same dependency.
341
338
  */
342
339
  if (module.enforceDeduplication) {
@@ -501,7 +498,7 @@ const scope = {
501
498
  configuration,
502
499
  isFilePathInDependencies,
503
500
  loader,
504
- require: currentRequire ?? require
501
+ require
505
502
  };
506
503
  const evaluateAnThrow = (object, givenOptions = {}) => {
507
504
  const options = {
@@ -543,7 +540,7 @@ const cssUse = module.preprocessor.cascadingStyleSheet.additional.pre.map(create
543
540
  options: module.cascadingStyleSheet.options || {}
544
541
  }, module.preprocessor.cascadingStyleSheet.loader ? {
545
542
  loader: module.preprocessor.cascadingStyleSheet.loader,
546
- options: extend(true, optionalRequire('postcss') ? {
543
+ options: extend(true, (await optionalImport('postcss')) ? {
547
544
  postcssOptions: {
548
545
  /*
549
546
  NOTE: Some plugins like "postcss-import" are
@@ -640,7 +637,7 @@ const genericLoader = {
640
637
  }, module.preprocessor.javaScript.additional.post.map(createEvaluateMapper('script')))
641
638
  },
642
639
  // endregion
643
- // region html template
640
+ // region HTML template
644
641
  html: {
645
642
  // NOTE: This is only for the main entry template.
646
643
  main: {
@@ -835,7 +832,7 @@ const genericLoader = {
835
832
  extend(loader, genericLoader);
836
833
  if (configuration.files.compose.cascadingStyleSheet && plugins.MiniCSSExtract) {
837
834
  /*
838
- NOTE: We have to remove the client side javascript hmr style loader
835
+ NOTE: We have to remove the client side JavaScript hmr style loader
839
836
  first.
840
837
  */
841
838
  loader.style.use.shift();
@@ -862,7 +859,7 @@ if (htmlAvailable && configuration.debug && configuration.development.server.liv
862
859
  // endregion
863
860
  // region plugins
864
861
  for (const pluginConfiguration of configuration.plugins) {
865
- const plugin = optionalRequire(pluginConfiguration.name.module);
862
+ const plugin = await optionalImport(pluginConfiguration.name.module);
866
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.');
867
864
  }
868
865
  // endregion
@@ -887,7 +884,7 @@ let customConfiguration = {};
887
884
  if (configuration.path.configuration.json) try {
888
885
  require.resolve(_rewrite(configuration.path.configuration.json, _rewrite_options));
889
886
  try {
890
- customConfiguration = currentRequire(configuration.path.configuration.json);
887
+ customConfiguration = require(_rewrite(configuration.path.configuration.json, _rewrite_options));
891
888
  } catch (error) {
892
889
  log.debug('Importing provided json webpack configuration file path', `under "${configuration.path.configuration.json}" failed:`, represent(error));
893
890
  }
@@ -999,7 +996,7 @@ if (!Array.isArray(module.skipParseRegularExpressions) || module.skipParseRegula
999
996
  };
1000
997
  if (configuration.path.configuration.javaScript) try {
1001
998
  require.resolve(_rewrite(configuration.path.configuration.javaScript, _rewrite_options));
1002
- const result = optionalRequire(configuration.path.configuration.javaScript);
999
+ const result = await optionalImport(configuration.path.configuration.javaScript);
1003
1000
  if (isPlainObject(result)) {
1004
1001
  if (Object.prototype.hasOwnProperty.call(result, 'replaceWebOptimizer')) webpackConfiguration = result.replaceWebOptimizer;else extend(true, webpackConfiguration, result);
1005
1002
  } else log.debug('Failed to load given JavaScript configuration file path', `"${configuration.path.configuration.javaScript}".`);