weboptimizer 4.0.7 → 4.0.9

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,4 +1,4 @@
1
- import { Browser, InitializedBrowser } from './type';
1
+ import type { Browser, InitializedBrowser } from './type';
2
2
  export declare const browser: Browser;
3
3
  export declare const log: any;
4
4
  /**
package/browser.js CHANGED
@@ -17,11 +17,7 @@
17
17
  */
18
18
  // region imports
19
19
  import "core-js/modules/es.array.push.js";
20
- import { Browser, InitializedBrowser } from "./type.js";
21
20
  import { CONSOLE_METHODS, Logger, timeout } from 'clientnode';
22
- import { DOMWindow, VirtualConsole } from 'jsdom';
23
- import { LoaderContext } from 'webpack';
24
- import { LoaderConfiguration } from "./ejsLoader.js";
25
21
  // endregion
26
22
  // region declaration
27
23
 
@@ -107,9 +103,14 @@ if (typeof TARGET_TECHNOLOGY === 'undefined' || TARGET_TECHNOLOGY === 'node')
107
103
  const content = await (await import('fs')).promises.readFile(filePath, {
108
104
  encoding: 'utf-8'
109
105
  });
110
- render(ejsLoader.bind({
111
- resourcePath: filePath
112
- })(content));
106
+ let evaluatedContent = '';
107
+ await ejsLoader.bind({
108
+ resourcePath: filePath,
109
+ async: (error, result) => {
110
+ if (error) throw error;else evaluatedContent = result;
111
+ }
112
+ })(content);
113
+ render(evaluatedContent);
113
114
  } else render(await import('webOptimizerDefaultTemplateFilePath'));
114
115
  // endregion
115
116
  })().catch(error => {
package/configurator.js CHANGED
@@ -255,7 +255,6 @@ environment = eval('process.env')) => {
255
255
  ...UTILITY_SCOPE,
256
256
  currentPath: currentWorkingDirectory,
257
257
  fs: fileSystem,
258
- optionalRequire,
259
258
  packageConfiguration,
260
259
  path,
261
260
  webOptimizerPath,
package/ejsLoader.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import type { Encoding, Mapping } from 'clientnode';
2
- import type { Options, TemplateFunction as EJSTemplateFunction } from 'ejs';
2
+ import type { Options, AsyncTemplateFunction as EJSAsyncTemplateFunction } from 'ejs';
3
3
  import type { LoaderContext } from 'webpack';
4
4
  import type { Extensions, Replacements } from './type';
5
- export type TemplateFunction = EJSTemplateFunction;
5
+ export type TemplateFunction = EJSAsyncTemplateFunction;
6
6
  export type CompilerOptions = Options & {
7
7
  encoding: Encoding;
8
8
  isString?: boolean;
@@ -30,5 +30,7 @@ export declare const log: any;
30
30
  * @param source - Input string to transform.
31
31
  * @returns Transformed string.
32
32
  */
33
- export declare const loader: (this: Partial<LoaderContext<LoaderConfiguration>>, source: string) => string;
33
+ export declare const loader: (this: (Partial<LoaderContext<LoaderConfiguration>> & {
34
+ async: (result: unknown) => void;
35
+ }), source: string) => Promise<void>;
34
36
  export default loader;
package/ejsLoader.js CHANGED
@@ -16,11 +16,11 @@
16
16
  endregion
17
17
  */
18
18
  // region
19
- import { transformSync as babelTransformSync } from '@babel/core';
19
+ import { transform as babelTransform } from '@babel/core';
20
20
  import babelMinifyPreset from 'babel-preset-minify';
21
- import { convertSubstringInPlainObject, copy, currentRequire, evaluate, extend, Logger, UTILITY_SCOPE } from 'clientnode';
21
+ import { convertSubstringInPlainObject, copy, evaluate, extend, Logger, UTILITY_SCOPE } from 'clientnode';
22
22
  import ejs from 'ejs';
23
- import { readFileSync } from 'fs';
23
+ import { readFile } from 'fs/promises';
24
24
  import { minify as minifyHTML } from 'html-minifier';
25
25
  import { extname } from 'path';
26
26
  import getConfiguration from "./configurator.js";
@@ -38,9 +38,11 @@ export const log = new Logger({
38
38
  * @param source - Input string to transform.
39
39
  * @returns Transformed string.
40
40
  */
41
- export const loader = function (source) {
41
+ export const loader = async function (source) {
42
+ const callback = this.async();
42
43
  const givenOptions = convertSubstringInPlainObject(extend(true, {
43
44
  compiler: {
45
+ async: true,
44
46
  localsName: '_'
45
47
  },
46
48
  compileSteps: 2,
@@ -61,13 +63,13 @@ export const loader = function (source) {
61
63
  replacements: {}
62
64
  }
63
65
  }, this.getOptions ? this.getOptions() : this.query ?? {}), /#%%%#/g, '!');
64
- const compile = (template, options = givenOptions.compiler, compileSteps = 2) => (locals = {}) => {
65
- options = {
66
+ const compile = (template, nestedGivenOptions = givenOptions.compiler, compileSteps = 2) => async (locals = {}) => {
67
+ const options = {
66
68
  filename: template,
67
- ...options
69
+ ...(nestedGivenOptions || {})
68
70
  };
69
71
  const givenLocals = [].concat(locals);
70
- const require = (request, nestedLocals = {}) => {
72
+ const importFile = async (request, nestedLocals = {}) => {
71
73
  const template = request.replace(/^(.+)\?[^?]+$/, '$1');
72
74
  const queryMatch = /^[^?]+\?(.+)$/.exec(request);
73
75
  if (queryMatch) {
@@ -84,8 +86,8 @@ export const loader = function (source) {
84
86
  delete nestedOptions.client;
85
87
  nestedOptions = extend(true, {
86
88
  encoding: configuration.encoding
87
- }, nestedOptions, nestedLocals.options || {}, options ?? {});
88
- if (nestedOptions.isString) return compile(template, nestedOptions)(nestedLocals);
89
+ }, nestedOptions, nestedLocals.options || {}, options);
90
+ if (nestedOptions.isString) return await compile(template, nestedOptions)(nestedLocals);
89
91
  const templateFilePath = determineModuleFilePath(template, givenOptions.module?.aliases, givenOptions.module?.replacements, {
90
92
  file: givenOptions.extensions?.file.internal || []
91
93
  }, givenOptions.context, configuration.path.source.asset.base, configuration.path.ignore, configuration.module.directoryNames, configuration.package.main.fileNames, configuration.package.main.propertyNames, configuration.package.aliasPropertyNames, configuration.encoding);
@@ -96,8 +98,8 @@ export const loader = function (source) {
96
98
  file doesn't seem to be an ejs template we simply load
97
99
  included file content.
98
100
  */
99
- if (queryMatch || templateFilePath.endsWith('.ejs')) return compile(templateFilePath, nestedOptions)(nestedLocals);
100
- return readFileSync(templateFilePath, {
101
+ if (queryMatch || templateFilePath.endsWith('.ejs')) return await compile(templateFilePath, nestedOptions)(nestedLocals);
102
+ return await readFile(templateFilePath, {
101
103
  encoding: nestedOptions.encoding
102
104
  });
103
105
  }
@@ -143,19 +145,18 @@ export const loader = function (source) {
143
145
  if (step < 3 && 1 < compileSteps) scope = {
144
146
  ...UTILITY_SCOPE,
145
147
  configuration,
146
- include: require,
147
- require,
148
+ include: importFile,
148
149
  ...(Array.isArray(stepLocals) ? {} : stepLocals)
149
150
  };else if (!Array.isArray(stepLocals)) scope = stepLocals;
150
151
  // endregion
151
152
  }
152
153
  if (typeof result === 'string') {
153
154
  const filePath = isString ? options.filename : result;
154
- if (filePath && extname(filePath) === '.js' && currentRequire) result = currentRequire(filePath);else {
155
+ if (filePath && extname(filePath) === '.js') result = await import(filePath);else {
155
156
  if (!isString) {
156
157
  let encoding = configuration.encoding;
157
158
  if (typeof options.encoding === 'string') encoding = options.encoding;
158
- result = readFileSync(result, {
159
+ result = await readFile(result, {
159
160
  encoding
160
161
  });
161
162
  }
@@ -232,21 +233,25 @@ export const loader = function (source) {
232
233
  } else result = ejs.compile(result, options);
233
234
  }
234
235
  } else {
235
- result = result(scope);
236
+ result = await result(scope);
236
237
  if (givenOptions.compress?.html) result = compressHTML(result);
237
238
  }
238
239
  }
239
240
  if (compileSteps % 2) {
240
- const processed = babelTransformSync(result, {
241
- ast: false,
242
- babelrc: false,
243
- comments: !givenOptions.compress?.javaScript,
244
- compact: Boolean(givenOptions.compress?.javaScript),
245
- filename: options.filename || 'unknown',
246
- minified: Boolean(givenOptions.compress?.javaScript),
247
- presets: givenOptions.compress?.javaScript ? [[babelMinifyPreset, givenOptions.compress.javaScript]] : [],
248
- sourceMaps: false,
249
- sourceType: 'script'
241
+ const processed = await new Promise((resolve, reject) => {
242
+ babelTransform(result, {
243
+ ast: false,
244
+ babelrc: false,
245
+ comments: !givenOptions.compress?.javaScript,
246
+ compact: Boolean(givenOptions.compress?.javaScript),
247
+ filename: options.filename || 'unknown',
248
+ minified: Boolean(givenOptions.compress?.javaScript),
249
+ presets: givenOptions.compress?.javaScript ? [[babelMinifyPreset, givenOptions.compress.javaScript]] : [],
250
+ sourceMaps: false,
251
+ sourceType: 'script'
252
+ }, (error, file) => {
253
+ if (error) reject(error);else resolve(file);
254
+ });
250
255
  });
251
256
  if (typeof processed?.code === 'string') result = processed.code;
252
257
  return `${options.strict ? `'use strict';\n` : ''}${result}`;
@@ -257,13 +262,17 @@ export const loader = function (source) {
257
262
  }
258
263
  return '';
259
264
  };
260
- return compile(source, {
261
- ...givenOptions.compiler,
262
- client: Boolean((givenOptions.compileSteps ?? 2) % 2),
263
- compileDebug: givenOptions.debug,
264
- debug: givenOptions.debug,
265
- filename: this.resourcePath || 'unknown',
266
- isString: true
267
- }, givenOptions.compileSteps)(givenOptions.locals || {});
265
+ try {
266
+ callback(null, await compile(source, {
267
+ ...givenOptions.compiler,
268
+ client: Boolean((givenOptions.compileSteps ?? 2) % 2),
269
+ compileDebug: givenOptions.debug,
270
+ debug: givenOptions.debug,
271
+ filename: this.resourcePath || 'unknown',
272
+ isString: true
273
+ }, givenOptions.compileSteps)(givenOptions.locals || {}));
274
+ } catch (error) {
275
+ callback(error);
276
+ }
268
277
  };
269
278
  export default loader;
package/helper.d.ts CHANGED
@@ -245,4 +245,4 @@ export declare const findPackageDescriptorFilePath: (start: Array<string> | stri
245
245
  * @returns A object containing found parsed configuration an their
246
246
  * corresponding file path.
247
247
  */
248
- export declare const getClosestPackageDescriptor: (modulePath: string, fileName?: string) => null | PackageDescriptor;
248
+ export declare const getClosestPackageDescriptor: (modulePath: string, fileName?: string) => Promise<null | PackageDescriptor>;
package/helper.js CHANGED
@@ -27,7 +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 { copy, currentRequire, escapeRegularExpressions, extend, isAnyMatching, isDirectorySync, isFileSync, isPlainObject, Logger, represent, walkDirectoryRecursivelySync } from 'clientnode';
30
+ import { copy, 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
33
  // endregion
@@ -599,15 +599,15 @@ export const findPackageDescriptorFilePath = (start, fileName = 'package.json')
599
599
  * @returns A object containing found parsed configuration an their
600
600
  * corresponding file path.
601
601
  */
602
- export const getClosestPackageDescriptor = (modulePath, fileName = 'package.json') => {
602
+ export const getClosestPackageDescriptor = async (modulePath, fileName = 'package.json') => {
603
603
  const filePath = findPackageDescriptorFilePath(modulePath, fileName);
604
- if (!(filePath && currentRequire)) return null;
605
- const configuration = currentRequire(filePath);
604
+ if (!filePath) return null;
605
+ const configuration = await import(filePath);
606
606
  /*
607
607
  If the package.json does not have a name property, try again from
608
608
  one level higher.
609
609
  */
610
- if (!configuration.name) return getClosestPackageDescriptor(resolve(dirname(filePath), '..'), fileName);
610
+ if (!configuration.name) return await getClosestPackageDescriptor(resolve(dirname(filePath), '..'), fileName);
611
611
  if (!configuration.version) configuration.version = 'not set';
612
612
  return {
613
613
  configuration,
package/jestSetup.js CHANGED
@@ -15,15 +15,8 @@
15
15
  See https://creativecommons.org/licenses/by/3.0/deed.de
16
16
  endregion
17
17
  */
18
- // region imports
19
- import { globalContext } from 'clientnode';
20
- import { TextEncoder, TextDecoder } from 'util'
21
- // endregion
22
- ;
18
+ import { globalContext, optionalImport } from 'clientnode';
19
+ import { TextEncoder, TextDecoder } from 'util';
23
20
  globalContext.TextEncoder = TextEncoder;
24
21
  globalContext.TextDecoder = TextDecoder;
25
- try {
26
- if (eval('require')('jest-canvas-mock')) console.info('Canvas mocking module loaded.');
27
- } catch {
28
- // Do nothing.
29
- }
22
+ if (await optionalImport('jest-canvas-mock')) console.info('Canvas mocking module loaded.');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "weboptimizer",
3
- "version": "4.0.7",
3
+ "version": "4.0.9",
4
4
  "description": "A generic web optimizer, (module) bundler and development environment.",
5
5
  "keywords": [
6
6
  "webpack",
@@ -109,9 +109,9 @@
109
109
  "rimraf": "^6.1.3",
110
110
  "script-loader": "^0.7.2",
111
111
  "typescript": "^6.0.3",
112
- "webpack": "^5.108.3",
113
- "webpack-cli": "^7.1.0",
114
- "webpack-sources": "^3.5.0"
112
+ "webpack": "^5.108.4",
113
+ "webpack-cli": "^7.2.1",
114
+ "webpack-sources": "^3.5.1"
115
115
  },
116
116
  "devDependencies": {
117
117
  "@babel/cli": "^8.0.1",
@@ -128,12 +128,12 @@
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.1",
131
+ "@typescript-eslint/parser": "^8.63.0",
132
132
  "css-loader": "^7.1.4",
133
133
  "cssnano": "^8.0.2",
134
134
  "eslint": "^10.6.0",
135
135
  "eslint-config-google": "^0.14.0",
136
- "eslint-plugin-jsdoc": "^63.0.10",
136
+ "eslint-plugin-jsdoc": "^63.0.12",
137
137
  "favicons": "^7.3.0",
138
138
  "favicons-webpack-plugin": "^6.0.1",
139
139
  "globals": "^17.7.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.1",
159
+ "typescript-eslint": "^8.63.0",
160
160
  "typescript-plugin-css-modules": "^5.2.0",
161
161
  "web-documentation": "^1.0.42",
162
162
  "workbox-webpack-plugin": "^7.4.1"
@@ -329,6 +329,7 @@
329
329
  "colors": "1.4.0"
330
330
  },
331
331
  "sideEffects": true,
332
+ "type": "module",
332
333
  "webDocumentation": {
333
334
  "trackingCode": "UA-40192634-11"
334
335
  },
@@ -342,7 +343,7 @@
342
343
  },
343
344
  "includeFilePathRegularExpression": "^.*$",
344
345
  "pattern": {
345
- "__evaluate__": "`${self.generic.assetPattern.javaScript.pattern}if(typeof window==='undefined'||window===null)var window=(typeof global==='undefined'||global===null)?{}:global;{1}`"
346
+ "__evaluate__": "`if(typeof window==='undefined'||window===null)var window=(typeof global==='undefined'||global===null)?{}:global;{1}`"
346
347
  }
347
348
  }
348
349
  },
@@ -582,11 +583,10 @@
582
583
  },
583
584
  "encoding": "utf-8",
584
585
  "exportFormat": {
585
- "external": "umd",
586
586
  "globalObject": {
587
587
  "__evaluate__": "2 < self.givenCommandLineArguments.length && self.givenCommandLineArguments[2] === 'serve' ? 'window' : 'this'"
588
588
  },
589
- "self": "umd"
589
+ "self": "modern-module"
590
590
  },
591
591
  "extensions": {
592
592
  "file": {
@@ -728,12 +728,6 @@
728
728
  ]
729
729
  },
730
730
  "generic": {
731
- "assetPattern": {
732
- "javaScript": {
733
- "#": "We have to ensure, that the highest resolvable dependency inside this project will be used in node environments to ensure one instance of each dependent artefact for linked projects. We have to wrap \"require\" into an eval call to avoid other pre-processing scripts to replace this statement here.",
734
- "pattern": "'use strict';if(typeof module!=='undefined'&&module!==null&&eval('typeof require')!=='undefined'&&eval('require')!==null&&'main'in eval('require')&&eval('typeof require.main')!=='undefined'&&eval('require.main')!==null){var ORIGINAL_MAIN_MODULE=module;if(module!==eval('require.main')&&'paths'in module&&'paths'in eval('require.main')&&typeof __dirname!=='undefined'&&__dirname!==null)module.paths=eval('require.main.paths').concat(module.paths.filter(function(path){return eval('require.main.paths').includes(path)}))};"
735
- }
736
- },
737
731
  "cascadingStyleSheetFileExtension": "css",
738
732
  "isWeb": true,
739
733
  "supportedBrowsers": [
@@ -1457,14 +1451,10 @@
1457
1451
  "javaScript": {
1458
1452
  "pattern": {
1459
1453
  "#": "This is how we can make our test artefact executable.",
1460
- "__evaluate__": "`#!/usr/bin/env node\n// -*- coding: utf-8 -*-\n${self.generic.assetPattern.javaScript.pattern}{1}`"
1454
+ "__evaluate__": "`#!/usr/bin/env node\n// -*- coding: utf-8 -*-\n{1}`"
1461
1455
  }
1462
1456
  }
1463
1457
  },
1464
- "exportFormat": {
1465
- "external": "commonjs2",
1466
- "self": "commonjs2"
1467
- },
1468
1458
  "files": {
1469
1459
  "defaultHTML": {
1470
1460
  "filename": "test.html",
@@ -35,7 +35,7 @@ export class HTMLTransformation {
35
35
  ...options
36
36
  };
37
37
  }
38
- process(data) {
38
+ async process(data) {
39
39
  /*
40
40
  NOTE: We have to prevent creating native "style" dom nodes to
41
41
  prevent jsdom from parsing the entire cascading style sheet. Which
@@ -74,9 +74,14 @@ export class HTMLTransformation {
74
74
  data.html = dom.serialize().replace(/##\+#\+#\+##/g, '<%').replace(/##-#-#-##/g, '%>').replace(/(<style[^>]*>)[\s\S]*?(<\/style[^>]*>)/gi, (match, startTag, endTag) => `${startTag}${styleContents.shift()}${endTag}`);
75
75
  // region post compilation
76
76
  for (const htmlFileSpecification of this.options.files) if (htmlFileSpecification.filename === data.plugin.options.filename) {
77
- for (const loaderConfiguration of [].concat(htmlFileSpecification.template.use)) if (loaderConfiguration.options?.compileSteps && typeof loaderConfiguration.options.compileSteps === 'number') data.html = ejsLoader.bind({
78
- query: extend(true, Object.prototype.hasOwnProperty.call(loaderConfiguration, 'options') ? copy(loaderConfiguration.options) : {}, htmlFileSpecification.template.postCompileOptions)
79
- })(data.html);
77
+ for (const loaderConfiguration of [].concat(htmlFileSpecification.template.use)) if (loaderConfiguration.options?.compileSteps && typeof loaderConfiguration.options.compileSteps === 'number') data.html = await new Promise((resolve, reject) => {
78
+ void ejsLoader.bind({
79
+ query: extend(true, Object.prototype.hasOwnProperty.call(loaderConfiguration, 'options') ? copy(loaderConfiguration.options) : {}, htmlFileSpecification.template.postCompileOptions),
80
+ async: (error, result) => {
81
+ if (error) reject(error);else resolve(result);
82
+ }
83
+ })(data.html);
84
+ });
80
85
  break;
81
86
  }
82
87
  // endregion
@@ -84,7 +89,7 @@ export class HTMLTransformation {
84
89
  }
85
90
  apply(compiler) {
86
91
  compiler.hooks.compilation.tap('WebOptimizer', compilation => {
87
- this.options.htmlPlugin.getHooks(compilation).beforeEmit.tap('WebOptimizerPostProcessHTML', this.process.bind(this));
92
+ this.options.htmlPlugin.getHooks(compilation).beforeEmit.tapPromise('WebOptimizerPostProcessHTML', this.process.bind(this));
88
93
  });
89
94
  }
90
95
  }
package/type.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { AnyFunction, Encoding, Mapping, PlainObject, SecondParameter } from 'clientnode';
1
+ import type { AnyFunction, Encoding, Mapping, PlainObject, SecondParameter, UTILITY_SCOPE } from 'clientnode';
2
2
  import type FaviconWebpackPlugin from 'favicons-webpack-plugin';
3
3
  import type { FaviconWebpackPlugionOptions as FaviconWebpackPluginOptions } from 'favicons-webpack-plugin/src/options';
4
4
  import type HtmlWebpackPlugin from 'html-webpack-plugin';
@@ -432,12 +432,12 @@ export interface GenericLoader {
432
432
  data: RuleSetRule;
433
433
  }
434
434
  export type Loader = GenericLoader & Mapping<WebpackRuleSetRule>;
435
- export interface EvaluationScope {
435
+ export type EvaluationScope = (typeof UTILITY_SCOPE) & {
436
436
  configuration: ResolvedConfiguration;
437
437
  isFilePathInDependencies: (filePath: string) => boolean;
438
438
  loader: Loader;
439
439
  require: typeof require;
440
- }
440
+ };
441
441
  export interface WebpackBaseAssets {
442
442
  outputName: string;
443
443
  plugin: HtmlWebpackPlugin;
@@ -16,69 +16,11 @@
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
- };
76
19
  import "core-js/modules/es.array.push.js";
77
20
  import "core-js/modules/es.iterator.constructor.js";
78
21
  import "core-js/modules/es.iterator.filter.js";
79
22
  import "core-js/modules/es.iterator.map.js";
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';
23
+ import { convertToValidVariableName, evaluate, escapeRegularExpressions, extend, importsPromise, isFileSync, isObject, isPlainObject, Logger, mask, optionalImport, represent, UTILITY_SCOPE } from 'clientnode';
82
24
  import { extname, join, relative, resolve } from 'path';
83
25
  import util from 'util';
84
26
  import webpack from 'webpack';
@@ -95,7 +37,7 @@ import webpackSources from 'webpack-sources';
95
37
  const {
96
38
  RawSource: WebpackRawSource
97
39
  } = webpackSources;
98
- import getConfiguration, { require } from "./configurator.js";
40
+ import getConfiguration from "./configurator.js";
99
41
  import { determineAssetType, determineExternalRequest, determineModuleFilePath, getClosestPackageDescriptor, isFilePathInLocation, normalizePaths, stripLoader } from "./helper.js";
100
42
  import InPlaceAssetsIntoHTML from "./plugins/InPlaceAssetsIntoHTML.js";
101
43
  import HTMLTransformation from "./plugins/HTMLTransformation.js";
@@ -338,10 +280,10 @@ for (const contextReplacement of module.replacements.context) pluginInstances.pu
338
280
  */
339
281
  if (module.enforceDeduplication) {
340
282
  const absoluteContextPath = resolve(configuration.path.context);
341
- const consolidator = result => {
283
+ const consolidator = async result => {
342
284
  const targetPath = result.createData.resource;
343
285
  if (targetPath && /((?: ^|\/)node_modules\/.+)/.test(targetPath) && (!targetPath.startsWith(absoluteContextPath) || /((?: ^|\/)node_modules\/.+){2}/.test(targetPath)) && isFileSync(targetPath)) {
344
- const packageDescriptor = getClosestPackageDescriptor(targetPath);
286
+ const packageDescriptor = await getClosestPackageDescriptor(targetPath);
345
287
  if (packageDescriptor) {
346
288
  let pathPrefixes;
347
289
  let pathSuffix;
@@ -371,7 +313,7 @@ if (module.enforceDeduplication) {
371
313
  for (const pathPrefix of pathPrefixes) {
372
314
  const alternateTargetPath = resolve(pathPrefix, pathSuffix);
373
315
  if (isFileSync(alternateTargetPath)) {
374
- const otherPackageDescriptor = getClosestPackageDescriptor(alternateTargetPath);
316
+ const otherPackageDescriptor = await getClosestPackageDescriptor(alternateTargetPath);
375
317
  if (otherPackageDescriptor) {
376
318
  if (packageDescriptor.configuration.version === otherPackageDescriptor.configuration.version) {
377
319
  log.info('\nConsolidate module request', `"${targetPath}" to`, `"${alternateTargetPath}".`);
@@ -399,93 +341,11 @@ if (module.enforceDeduplication) {
399
341
  pluginInstances.push({
400
342
  apply: compiler => {
401
343
  compiler.hooks.normalModuleFactory.tap('WebOptimizerModuleConsolidation', nmf => {
402
- nmf.hooks.afterResolve.tap('WebOptimizerModuleConsolidation', consolidator);
344
+ nmf.hooks.afterResolve.tapPromise('WebOptimizerModuleConsolidation', consolidator);
403
345
  });
404
346
  }
405
347
  });
406
348
  }
407
- /*
408
- new NormalModuleReplacementPlugin(
409
- /.+/,
410
- (result: {
411
- context: string
412
- createData: {resource: string}
413
- request: string
414
- }): void => {
415
- const isResource: boolean = Boolean(result.createData.resource)
416
- const targetPath: string = isResource ?
417
- result.createData.resource :
418
- resolve(result.context, result.request)
419
- if (
420
- targetPath &&
421
- /((?: ^|\/)node_modules\/.+){2}/.test(targetPath) &&
422
- isFileSync(targetPath)
423
- ) {
424
- const packageDescriptor: null | PackageDescriptor =
425
- Helper.getClosestPackageDescriptor(targetPath)
426
- if (packageDescriptor) {
427
- const pathPrefixes: null | RegExpMatchArray = targetPath.match(
428
- /((?: ^|.*?\/)node_modules\/)/g
429
- )
430
- if (pathPrefixes === null)
431
- return
432
- // Avoid finding the same artefact.
433
- pathPrefixes.pop()
434
- let index: number = 0
435
- for (const pathPrefix of pathPrefixes) {
436
- if (index > 0)
437
- pathPrefixes[index] =
438
- resolve(pathPrefixes[index - 1], pathPrefix)
439
- index += 1
440
- }
441
- const pathSuffix: string =
442
- targetPath.replace(/(?: ^|.*\/)node_modules\/(.+$)/, '$1')
443
- let redundantRequest: null | PlainObject = null
444
- for (const pathPrefix of pathPrefixes) {
445
- const alternateTargetPath: string =
446
- resolve(pathPrefix, pathSuffix)
447
- if (isFileSync(alternateTargetPath)) {
448
- const otherPackageDescriptor: null | PackageDescriptor =
449
- Helper.getClosestPackageDescriptor(
450
- alternateTargetPath
451
- )
452
- if (otherPackageDescriptor) {
453
- if (
454
- packageDescriptor.configuration.version ===
455
- otherPackageDescriptor.configuration.version
456
- ) {
457
- log.info(
458
- '\nConsolidate module request',
459
- `"${targetPath}" to`,
460
- `"${alternateTargetPath}".`
461
- )
462
- result.createData.resource =
463
- alternateTargetPath
464
- result.request = alternateTargetPath
465
- return
466
- }
467
- redundantRequest = {
468
- path: alternateTargetPath,
469
- version:
470
- otherPackageDescriptor.configuration
471
- .version
472
- }
473
- }
474
- }
475
- }
476
- if (redundantRequest)
477
- log.warn(
478
- '\nIncluding different versions of same package',
479
- `"${packageDescriptor.configuration.name}". Module`,
480
- `"${targetPath}" (version`,
481
- `${packageDescriptor.configuration.version}) has`,
482
- `redundancies with "${redundantRequest.path}"`,
483
- `(version ${redundantRequest.version}).`
484
- )
485
- }
486
- }
487
- }
488
- ))*/
489
349
  //// endregion
490
350
  /// endregion
491
351
  /// region loader helper
@@ -495,12 +355,13 @@ const isFilePathInDependencies = filePath => {
495
355
  };
496
356
  const loader = {};
497
357
  const scope = {
358
+ ...UTILITY_SCOPE,
498
359
  configuration,
499
360
  isFilePathInDependencies,
500
361
  loader,
501
362
  require
502
363
  };
503
- const evaluateAnThrow = (object, givenOptions = {}) => {
364
+ const evaluateAndThrow = (object, givenOptions = {}) => {
504
365
  const options = {
505
366
  filePath: configuration.path.context,
506
367
  ...givenOptions
@@ -516,16 +377,16 @@ const evaluateAnThrow = (object, givenOptions = {}) => {
516
377
  }
517
378
  return object;
518
379
  };
519
- const createEvaluateMapper = type => value => evaluateAnThrow(value, {
380
+ const createEvaluateMapper = type => value => evaluateAndThrow(value, {
520
381
  type
521
382
  });
522
383
  const evaluateAdditionalLoaderConfiguration = loaderConfiguration => ({
523
- exclude: filePath => evaluateAnThrow(loaderConfiguration.exclude, {
384
+ exclude: filePath => evaluateAndThrow(loaderConfiguration.exclude, {
524
385
  filePath
525
386
  }),
526
- include: loaderConfiguration.include && evaluateAnThrow(loaderConfiguration.include) || configuration.path.source.base,
527
- test: new RegExp(evaluateAnThrow(loaderConfiguration.test)),
528
- use: evaluateAnThrow(loaderConfiguration.use)
387
+ include: loaderConfiguration.include && evaluateAndThrow(loaderConfiguration.include) || configuration.path.source.base,
388
+ test: new RegExp(evaluateAndThrow(loaderConfiguration.test)),
389
+ use: evaluateAndThrow(loaderConfiguration.use)
529
390
  });
530
391
  const getIncludingPaths = path => normalizePaths([path].concat(module.locations.directoryPaths));
531
392
  const postCSSResolver = (name, _context) => {
@@ -598,7 +459,7 @@ const genericLoader = {
598
459
  // Convert to compatible native web types.
599
460
  // region generic template
600
461
  ejs: {
601
- exclude: filePath => normalizePaths(configuration.files.html.concat(configuration.files.defaultHTML).map(htmlConfiguration => htmlConfiguration.template.filePath)).includes(filePath) || module.preprocessor.ejs.exclude === null ? false : evaluateAnThrow(module.preprocessor.ejs.exclude, {
462
+ exclude: filePath => normalizePaths(configuration.files.html.concat(configuration.files.defaultHTML).map(htmlConfiguration => htmlConfiguration.template.filePath)).includes(filePath) || module.preprocessor.ejs.exclude === null ? false : evaluateAndThrow(module.preprocessor.ejs.exclude, {
602
463
  filePath
603
464
  }),
604
465
  include: getIncludingPaths(configuration.path.source.asset.template),
@@ -615,12 +476,12 @@ const genericLoader = {
615
476
  // endregion
616
477
  // region script
617
478
  script: {
618
- exclude: filePath => evaluateAnThrow(module.preprocessor.javaScript.exclude, {
479
+ exclude: filePath => evaluateAndThrow(module.preprocessor.javaScript.exclude, {
619
480
  filePath,
620
481
  type: 'script'
621
482
  }),
622
483
  include: filePath => {
623
- const result = evaluateAnThrow(module.preprocessor.javaScript.include, {
484
+ const result = evaluateAndThrow(module.preprocessor.javaScript.include, {
624
485
  filePath,
625
486
  type: 'script'
626
487
  });
@@ -645,7 +506,7 @@ const genericLoader = {
645
506
  use: configuration.files.defaultHTML.template.use
646
507
  },
647
508
  ejs: {
648
- exclude: filePath => normalizePaths(configuration.files.html.concat(configuration.files.defaultHTML).map(htmlConfiguration => htmlConfiguration.template.filePath)).includes(filePath) || (module.preprocessor.html.exclude === null ? false : evaluateAnThrow(module.preprocessor.html.exclude, {
509
+ exclude: filePath => normalizePaths(configuration.files.html.concat(configuration.files.defaultHTML).map(htmlConfiguration => htmlConfiguration.template.filePath)).includes(filePath) || (module.preprocessor.html.exclude === null ? false : evaluateAndThrow(module.preprocessor.html.exclude, {
649
510
  filePath,
650
511
  type: 'html.ejs'
651
512
  })),
@@ -671,7 +532,7 @@ const genericLoader = {
671
532
  }, module.preprocessor.html.additional.post.map(createEvaluateMapper('html.ejs')))
672
533
  },
673
534
  html: {
674
- exclude: filePath => normalizePaths(configuration.files.html.concat(configuration.files.defaultHTML).map(htmlConfiguration => htmlConfiguration.template.filePath)).includes(filePath) || (module.html.exclude === null ? true : evaluateAnThrow(module.html.exclude, {
535
+ exclude: filePath => normalizePaths(configuration.files.html.concat(configuration.files.defaultHTML).map(htmlConfiguration => htmlConfiguration.template.filePath)).includes(filePath) || (module.html.exclude === null ? true : evaluateAndThrow(module.html.exclude, {
675
536
  filePath,
676
537
  type: 'html'
677
538
  })),
@@ -691,12 +552,12 @@ const genericLoader = {
691
552
  // Load dependencies.
692
553
  // region style
693
554
  style: {
694
- exclude: filePath => module.cascadingStyleSheet.exclude === null ? isFilePathInDependencies(filePath) : evaluateAnThrow(module.cascadingStyleSheet.exclude, {
555
+ exclude: filePath => module.cascadingStyleSheet.exclude === null ? isFilePathInDependencies(filePath) : evaluateAndThrow(module.cascadingStyleSheet.exclude, {
695
556
  filePath,
696
557
  type: 'style'
697
558
  }),
698
559
  include: filePath => {
699
- const result = evaluateAnThrow(module.cascadingStyleSheet.include, {
560
+ const result = evaluateAndThrow(module.cascadingStyleSheet.include, {
700
561
  filePath,
701
562
  type: 'style'
702
563
  });
@@ -714,7 +575,7 @@ const genericLoader = {
714
575
  // region font
715
576
  font: {
716
577
  eot: {
717
- exclude: filePath => module.optimizer.font.eot.exclude === null ? false : evaluateAnThrow(module.optimizer.font.eot.exclude, {
578
+ exclude: filePath => module.optimizer.font.eot.exclude === null ? false : evaluateAndThrow(module.optimizer.font.eot.exclude, {
718
579
  filePath,
719
580
  type: 'font.eot'
720
581
  }),
@@ -731,7 +592,7 @@ const genericLoader = {
731
592
  use: module.optimizer.font.eot.loader.map(createEvaluateMapper('font.eot'))
732
593
  },
733
594
  svg: {
734
- exclude: filePath => module.optimizer.font.svg.exclude === null ? false : evaluateAnThrow(module.optimizer.font.svg.exclude, {
595
+ exclude: filePath => module.optimizer.font.svg.exclude === null ? false : evaluateAndThrow(module.optimizer.font.svg.exclude, {
735
596
  filePath,
736
597
  type: 'svg'
737
598
  }),
@@ -750,7 +611,7 @@ const genericLoader = {
750
611
  use: module.optimizer.font.svg.loader.map(createEvaluateMapper('font.svg'))
751
612
  },
752
613
  ttf: {
753
- exclude: filePath => module.optimizer.font.ttf.exclude === null ? false : evaluateAnThrow(module.optimizer.font.ttf.exclude, {
614
+ exclude: filePath => module.optimizer.font.ttf.exclude === null ? false : evaluateAndThrow(module.optimizer.font.ttf.exclude, {
754
615
  filePath,
755
616
  type: 'ttf'
756
617
  }),
@@ -768,7 +629,7 @@ const genericLoader = {
768
629
  use: module.optimizer.font.ttf.loader.map(createEvaluateMapper('font.ttf'))
769
630
  },
770
631
  woff: {
771
- exclude: filePath => module.optimizer.font.woff.exclude === null ? false : evaluateAnThrow(module.optimizer.font.woff.exclude, {
632
+ exclude: filePath => module.optimizer.font.woff.exclude === null ? false : evaluateAndThrow(module.optimizer.font.woff.exclude, {
772
633
  filePath,
773
634
  type: 'woff'
774
635
  }),
@@ -788,7 +649,7 @@ const genericLoader = {
788
649
  // endregion
789
650
  // region image
790
651
  image: {
791
- exclude: filePath => module.optimizer.image.exclude === null ? isFilePathInDependencies(filePath) : evaluateAnThrow(module.optimizer.image.exclude, {
652
+ exclude: filePath => module.optimizer.image.exclude === null ? isFilePathInDependencies(filePath) : evaluateAndThrow(module.optimizer.image.exclude, {
792
653
  filePath,
793
654
  type: 'image'
794
655
  }),
@@ -810,7 +671,7 @@ const genericLoader = {
810
671
  data: {
811
672
  exclude: filePath => {
812
673
  if (typeof filePath !== 'string') return false;
813
- return configuration.extensions.file.internal.includes(extname(stripLoader(filePath))) || (module.optimizer.data.exclude === null ? isFilePathInDependencies(filePath) : evaluateAnThrow(module.optimizer.data.exclude, {
674
+ return configuration.extensions.file.internal.includes(extname(stripLoader(filePath))) || (module.optimizer.data.exclude === null ? isFilePathInDependencies(filePath) : evaluateAndThrow(module.optimizer.data.exclude, {
814
675
  filePath,
815
676
  type: 'data'
816
677
  }));
@@ -882,9 +743,9 @@ if (!module.optimizer.minimizer) {
882
743
  // region configuration
883
744
  let customConfiguration = {};
884
745
  if (configuration.path.configuration.json) try {
885
- require.resolve(_rewrite(configuration.path.configuration.json, _rewrite_options));
746
+ import.meta.resolve(configuration.path.configuration.json);
886
747
  try {
887
- customConfiguration = require(_rewrite(configuration.path.configuration.json, _rewrite_options));
748
+ customConfiguration = await import(configuration.path.configuration.json);
888
749
  } catch (error) {
889
750
  log.debug('Importing provided json webpack configuration file path', `under "${configuration.path.configuration.json}" failed:`, represent(error));
890
751
  }
@@ -897,7 +758,8 @@ export let webpackConfiguration = extend(true, {
897
758
  devtool: configuration.development.tool,
898
759
  devServer: configuration.development.server,
899
760
  experiments: {
900
- topLevelAwait: true
761
+ futureDefaults: true,
762
+ outputModule: true
901
763
  },
902
764
  // region input
903
765
  entry: configuration.injection.entry.normalized,
@@ -995,7 +857,7 @@ if (!Array.isArray(module.skipParseRegularExpressions) || module.skipParseRegula
995
857
  noParse: module.skipParseRegularExpressions
996
858
  };
997
859
  if (configuration.path.configuration.javaScript) try {
998
- require.resolve(_rewrite(configuration.path.configuration.javaScript, _rewrite_options));
860
+ import.meta.resolve(configuration.path.configuration.javaScript);
999
861
  const result = await optionalImport(configuration.path.configuration.javaScript);
1000
862
  if (isPlainObject(result)) {
1001
863
  if (Object.prototype.hasOwnProperty.call(result, 'replaceWebOptimizer')) webpackConfiguration = result.replaceWebOptimizer;else extend(true, webpackConfiguration, result);