weboptimizer 4.0.20 → 4.0.22

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.js CHANGED
@@ -17,7 +17,6 @@
17
17
  */
18
18
  // region imports
19
19
  import { CONSOLE_METHODS, Logger, timeout } from 'clientnode';
20
- import webOptimizerDefaultTemplate from 'webOptimizerDefaultTemplateFilePath';
21
20
  // endregion
22
21
  // region declaration
23
22
 
@@ -100,17 +99,17 @@ if (typeof TARGET_TECHNOLOGY === 'undefined' || TARGET_TECHNOLOGY === 'node')
100
99
  NOTE: We load dependencies now to avoid having file imports
101
100
  after test runner has finished to isolate the environment.
102
101
  */
103
- const ejsLoader = (await import('./ejsLoader')).default;
102
+ const ejsLoader = (await import('./ejsLoader.js')).default;
104
103
  const content = await (await import('fs')).promises.readFile(filePath, {
105
104
  encoding: 'utf-8'
106
105
  });
107
106
  await ejsLoader.bind({
108
107
  resourcePath: filePath,
109
- async: (error, result) => {
108
+ async: () => (error, result) => {
110
109
  if (error) throw error;else evaluatedContent = result;
111
110
  }
112
111
  })(content);
113
- } else evaluatedContent = webOptimizerDefaultTemplate;
112
+ } else evaluatedContent = (await import('webOptimizerDefaultTemplateFilePath')).default;
114
113
  render(evaluatedContent);
115
114
  // endregion
116
115
  })().catch(error => {
package/configurator.d.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  import type { ResolvedConfiguration } from './type';
2
2
  import { Logger } from 'clientnode';
3
- export declare const require: NodeJS.Require;
4
- export declare const optionalRequire: <T = unknown>(id: string) => null | T;
5
3
  export declare let loadedConfiguration: null | ResolvedConfiguration;
6
4
  export declare const log: Logger;
7
5
  /**
package/configurator.js CHANGED
@@ -16,79 +16,13 @@
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
- };
76
19
  import { convertCircularObjectToJSON, copy, evaluateAsyncDynamicData, evaluateDynamicData, extend, getUTCTimestamp, importsPromise, isFileSync, isObject, isPlainObject, Logger, MAXIMAL_NUMBER_OF_ITERATIONS, modifyObject, optionalImport, parseEncodedObject, removeKeyPrefixes, UTILITY_SCOPE } from 'clientnode';
77
20
  import fileSystem, { lstatSync, readFileSync, unlinkSync } from 'fs';
78
- import { createRequire } from 'node:module';
79
21
  import path, { basename, dirname, join, resolve } from 'path';
80
22
  import { determineAssetType, determineModuleFilePath, determineModuleLocations, resolveAutoInjection, resolveBuildConfigurationFilePaths, resolveModulesInFolders, normalizeGivenInjection, normalizePaths } from "./helper.js";
81
23
  import packageConfiguration from './package.json' with { type: 'json' };
82
24
  import { SubConfigurationTypes } from "./type.js";
83
25
  // endregion
84
- export const require = createRequire(import.meta.url);
85
- export const optionalRequire = id => {
86
- try {
87
- return require(_rewrite(id, _rewrite_options));
88
- } catch {
89
- return null;
90
- }
91
- };
92
26
  const {
93
27
  configuration: metaConfiguration
94
28
  } = packageConfiguration;
@@ -184,7 +118,16 @@ environment = eval('process.env')) => {
184
118
  if (debug) configuration = extend(true, modifyObject(metaConfiguration.default, metaConfiguration.debug), metaConfiguration.debug);else configuration = metaConfiguration.default;
185
119
  configuration.debug = debug;
186
120
  if (typeof configuration.library === 'object') extend(true, modifyObject(libraryConfiguration, configuration.library), configuration.library);
187
- if (configuration.library && specificConfiguration.library !== false) configuration = extend(true, modifyObject(configuration, libraryConfiguration), libraryConfiguration);
121
+ if (configuration.library && specificConfiguration.library !== false) {
122
+ const modifiedConfiguration = modifyObject(configuration, libraryConfiguration);
123
+ configuration = extend(true,
124
+ /*
125
+ NOTE: We have to copy both objects otherwise the
126
+ substucture under "path" is not extended as expected.
127
+ */
128
+ copy(modifiedConfiguration), copy(libraryConfiguration));
129
+ }
130
+
188
131
  // endregion
189
132
  // region merging and evaluating task specific and dynamic configurations
190
133
  /// region load additional dynamically given configuration
package/ejsLoader.d.ts CHANGED
@@ -14,7 +14,7 @@ export type LoaderConfiguration = Mapping<unknown> & {
14
14
  compileSteps: number;
15
15
  compress: {
16
16
  html: Mapping<unknown>;
17
- javaScript: Mapping<unknown>;
17
+ javaScript: boolean;
18
18
  };
19
19
  context: string;
20
20
  debug: boolean;
package/ejsLoader.js CHANGED
@@ -17,7 +17,6 @@
17
17
  */
18
18
  // region
19
19
  import { transform as babelTransform } from '@babel/core';
20
- import babelMinifyPreset from 'babel-preset-minify';
21
20
  import { convertSubstringInPlainObject, copy, evaluate, extend, Logger, UTILITY_SCOPE } from 'clientnode';
22
21
  import ejs from 'ejs';
23
22
  import { readFile } from 'fs/promises';
@@ -29,7 +28,6 @@ import { determineModuleFilePath } from "./helper.js";
29
28
  // region types
30
29
 
31
30
  // endregion
32
- const configuration = await getConfiguration();
33
31
  export const log = new Logger({
34
32
  name: 'weboptimizer.ejs-loader'
35
33
  });
@@ -40,6 +38,7 @@ export const log = new Logger({
40
38
  */
41
39
  export const loader = async function (source) {
42
40
  const callback = this.async();
41
+ const configuration = await getConfiguration();
43
42
  const givenOptions = convertSubstringInPlainObject(extend(true, {
44
43
  compiler: {
45
44
  async: true,
@@ -48,12 +47,15 @@ export const loader = async function (source) {
48
47
  compileSteps: 2,
49
48
  compress: {
50
49
  html: {},
51
- javaScript: {}
50
+ javaScript: true
52
51
  },
53
52
  context: './',
54
53
  debug: false,
55
54
  extensions: {
56
55
  file: {
56
+ alias: {
57
+ '.js': ['.js', '.ts', '.tsx', '.jsx']
58
+ },
57
59
  external: [],
58
60
  internal: ['.js', '.json', '.css', '.svg', '.png', '.jpg', '.gif', '.ico', '.html', '.eot', '.ttf', '.woff', '.woff2']
59
61
  }
@@ -243,10 +245,9 @@ export const loader = async function (source) {
243
245
  ast: false,
244
246
  babelrc: false,
245
247
  comments: !givenOptions.compress?.javaScript,
246
- compact: Boolean(givenOptions.compress?.javaScript),
247
248
  filename: options.filename || 'unknown',
248
- minified: Boolean(givenOptions.compress?.javaScript),
249
- presets: givenOptions.compress?.javaScript ? [[babelMinifyPreset, givenOptions.compress.javaScript]] : [],
249
+ minified: givenOptions.compress?.javaScript,
250
+ presets: [],
250
251
  sourceMaps: false,
251
252
  sourceType: 'script'
252
253
  }, (error, file) => {
package/helper.js CHANGED
@@ -154,6 +154,9 @@ export const applyContext = (request, context = './', referencePath = './', alia
154
154
  */
155
155
  export const determineExternalRequest = (request, context = './', requestContext = './', normalizedGivenInjection = {}, relativeExternalModuleLocations = ['node_modules'], aliases = {}, moduleReplacements = {}, extensions = {
156
156
  file: {
157
+ alias: {
158
+ '.js': ['.js', '.ts', '.tsx', '.jsx']
159
+ },
157
160
  external: ['.compiled.js', '.js', '.json'],
158
161
  internal: KNOWN_FILE_EXTENSIONS.map(suffix => `.${suffix}`)
159
162
  }
@@ -374,6 +377,9 @@ export const normalizeGivenInjection = givenInjection => {
374
377
  */
375
378
  export const resolveAutoInjection = (givenInjection, buildConfigurations, aliases = {}, moduleReplacements = {}, extensions = {
376
379
  file: {
380
+ alias: {
381
+ '.js': ['.js', '.ts', '.tsx', '.jsx']
382
+ },
377
383
  external: ['compiled.js', '.js', '.json'],
378
384
  internal: KNOWN_FILE_EXTENSIONS.map(suffix => `.${suffix}`)
379
385
  }
@@ -591,7 +597,14 @@ export const findPackageDescriptorFilePath = (start, fileName = 'package.json')
591
597
  export const getClosestPackageDescriptor = async (modulePath, fileName = 'package.json') => {
592
598
  const filePath = findPackageDescriptorFilePath(modulePath, fileName);
593
599
  if (!filePath) return null;
594
- const configuration = await import(filePath);
600
+
601
+ /*
602
+ NOTE: In native ecmascript module contexts json imports are wrapped
603
+ into a module namespace object providing its content as "default"
604
+ export whereas commonjs interoperability provides it directly.
605
+ */
606
+ const importedModule = await import(filePath);
607
+ const configuration = importedModule.default ?? importedModule;
595
608
  /*
596
609
  If the package.json does not have a name property, try again from
597
610
  one level higher.
package/index.js CHANGED
@@ -288,7 +288,12 @@ environment = eval('process.env')) => {
288
288
  }
289
289
  // endregion
290
290
  } catch (error) {
291
- if (configuration.debug) throw error;else log.error(error);
291
+ if (configuration.debug) throw error;else {
292
+ log.error(error);
293
+
294
+ // NOTE: Forward nested return codes.
295
+ process.exitCode = error.returnCode ?? 1;
296
+ }
292
297
  }
293
298
  return clear;
294
299
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "weboptimizer",
3
- "version": "4.0.20",
3
+ "version": "4.0.22",
4
4
  "description": "A generic web optimizer, (module) bundler and development environment.",
5
5
  "keywords": [
6
6
  "webpack",
@@ -77,7 +77,7 @@
77
77
  "lint:base": "eslint --no-warn-ignored *.ts */*.ts test/*/*.ts",
78
78
  "prepare": "yarn build",
79
79
  "prettify": "yarn lint:base --fix || true",
80
- "test": "yarn build:test && jest --config ./weboptimizerJest.json --noStackTrace --root-dir './' --test-regex '/test/.+\\\\.js$' test/browser.js test/configurator.js test/helper.js test/ejsLoader.js test/stylelintConfigurator.js test/index.js test/webpackConfigurator.js",
80
+ "test": "yarn build:test && node --experimental-vm-modules node_modules/.bin/jest --config ./weboptimizerJest.json --noStackTrace --root-dir './' --test-regex '/test/.+\\\\.js$' test/browser.js test/configurator.js test/helper.js test/ejsLoader.js test/stylelintConfigurator.js test/index.js test/webpackConfigurator.js",
81
81
  "test:coverage": "yarn test --ci --coverage --coverageReporters=text --coverageReporters=text-summary --silent --testLocationInResults",
82
82
  "test:coverage:report": "yarn test:coverage --coverageDirectory=.coverage --coverageReporters=lcov --outputFile=lcov.info",
83
83
  "test:watch": "yarn test --watch",
@@ -94,8 +94,7 @@
94
94
  "babel-loader": "^10.1.1",
95
95
  "babel-plugin-polyfill-corejs3": "^1.0.0",
96
96
  "babel-plugin-transform-rewrite-imports": "^1.5.4",
97
- "babel-preset-minify": "^0.5.2",
98
- "clientnode": "4.0.1444",
97
+ "clientnode": "4.0.1451",
99
98
  "core-js": "^3.49.0",
100
99
  "ejs": "^6.0.1",
101
100
  "exports-loader": "^5.0.0",
@@ -128,12 +127,12 @@
128
127
  "@types/postcss-url": "^10.0.4",
129
128
  "@types/webpack-env": "^1.18.8",
130
129
  "@types/webpack-sources": "^3.2.3",
131
- "@typescript-eslint/parser": "^8.63.0",
130
+ "@typescript-eslint/parser": "^8.64.0",
132
131
  "css-loader": "^7.1.4",
133
132
  "cssnano": "^8.0.2",
134
- "eslint": "^10.6.0",
133
+ "eslint": "^10.7.0",
135
134
  "eslint-config-google": "^0.14.0",
136
- "eslint-plugin-jsdoc": "^63.0.12",
135
+ "eslint-plugin-jsdoc": "^63.0.13",
137
136
  "favicons": "^7.3.0",
138
137
  "favicons-webpack-plugin": "^6.0.1",
139
138
  "globals": "^17.7.0",
@@ -143,7 +142,7 @@
143
142
  "mini-css-extract-plugin": "^2.10.2",
144
143
  "mkdirp": "^3.0.1",
145
144
  "node-fetch": "^3.3.2",
146
- "postcss": "^8.5.16",
145
+ "postcss": "^8.5.19",
147
146
  "postcss-fontpath": "^1.0.0",
148
147
  "postcss-import": "^16.1.1",
149
148
  "postcss-loader": "^8.2.1",
@@ -156,7 +155,7 @@
156
155
  "stylelint-config-standard": "^40.0.0",
157
156
  "stylelint-config-standard-scss": "^17.0.0",
158
157
  "terser-webpack-plugin": "^5.6.1",
159
- "typescript-eslint": "^8.63.0",
158
+ "typescript-eslint": "^8.64.0",
160
159
  "typescript-plugin-css-modules": "^5.2.0",
161
160
  "web-documentation": "^1.0.42",
162
161
  "workbox-webpack-plugin": "^7.4.1"
@@ -583,7 +582,19 @@
583
582
  },
584
583
  "module": {
585
584
  "optimizer": {
586
- "cssnano": null
585
+ "cssnano": null,
586
+ "terser": {
587
+ "terserOptions": {
588
+ "compress": {
589
+ "drop_console": {
590
+ "__evaluate__": "!self.debug"
591
+ },
592
+ "drop_debugger": {
593
+ "__evaluate__": "!self.debug"
594
+ }
595
+ }
596
+ }
597
+ }
587
598
  }
588
599
  }
589
600
  },
@@ -601,6 +612,15 @@
601
612
  },
602
613
  "extensions": {
603
614
  "file": {
615
+ "#": "NOTE: Maps import specifier extensions to resolvable source extensions (webpack's \"resolve.extensionAlias\") since imports rewritten to \".js\" have to be resolved back to their typescript sources.",
616
+ "alias": {
617
+ ".js": [
618
+ ".js",
619
+ ".ts",
620
+ ".tsx",
621
+ ".jsx"
622
+ ]
623
+ },
604
624
  "external": {
605
625
  "__evaluate__": "self.generic.isWeb ? self.extensions.file.internal : ['.compiled.js', '.js', '.json', '.mjs']"
606
626
  },
@@ -928,29 +948,11 @@
928
948
  }
929
949
  },
930
950
  "optimizer": {
931
- "babelMinify": {
932
- "bundle": {
933
- "transform": {
934
- "removeConsole": true,
935
- "removeDebugger": true,
936
- "mangle": {
937
- "topLevel": {
938
- "#": "Indicates to not mangle scope names from the entry (main) scope in libraries.",
939
- "__evaluate__": "!self.library"
940
- }
941
- }
942
- }
943
- },
944
- "module": {
945
- "removeConsole": true,
946
- "removeDebugger": true
947
- }
948
- },
949
951
  "cssnano": {
950
952
  "#": "The autoprefixer has to be disabled in this context since it would remove all needed vendor prefixes from the preceding processing (every prefix should be needed here).",
951
953
  "preset": [
952
954
  {
953
- "__await_evaluate__": "module.optionalImport('cssnano-preset-default')"
955
+ "__await_evaluate__": "module.optionalImport('cssnano-preset-default').then((module) => module?.default)"
954
956
  },
955
957
  {
956
958
  "autoprefixer": false,
@@ -1065,7 +1067,19 @@
1065
1067
  },
1066
1068
  "loader": []
1067
1069
  },
1068
- "minimize": true
1070
+ "terser": {
1071
+ "terserOptions": {
1072
+ "compress": {
1073
+ "#": "To provide a logging output we need to exclude this feature.",
1074
+ "drop_console": {
1075
+ "__evaluate__": "!self.debug"
1076
+ },
1077
+ "drop_debugger": {
1078
+ "__evaluate__": "!self.debug"
1079
+ }
1080
+ }
1081
+ }
1082
+ }
1069
1083
  },
1070
1084
  "preprocessor": {
1071
1085
  "cascadingStyleSheet": {
@@ -1113,7 +1127,7 @@
1113
1127
  "__evaluate__": "self.module.optimizer.htmlMinifier"
1114
1128
  },
1115
1129
  "javaScript": {
1116
- "__evaluate__": "self.module.optimizer.babelMinify.module"
1130
+ "__evaluate__": "!self.debug"
1117
1131
  }
1118
1132
  },
1119
1133
  "context": {
@@ -1218,8 +1232,8 @@
1218
1232
  ]
1219
1233
  ],
1220
1234
  "presets": {
1221
- "#": "NOTE: We have to disable module export/import transformation to allow tree shaking by the final (minimizer).",
1222
- "__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]])"
1235
+ "#": "NOTE: We disable module export/import transformation to allow tree shaking by the final (minimizer).",
1236
+ "__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']"
1223
1237
  }
1224
1238
  },
1225
1239
  "regularExpression": "\\.[jt]sx?(?:\\?.*)?$"
@@ -1492,14 +1506,16 @@
1492
1506
  },
1493
1507
  "module": {
1494
1508
  "optimizer": {
1495
- "babelMinify": {
1496
- "bundle": {
1497
- "transform": {
1498
- "removeConsole": false
1509
+ "terser": {
1510
+ "terserOptions": {
1511
+ "compress": {
1512
+ "drop_console": {
1513
+ "__evaluate__": "false"
1514
+ },
1515
+ "drop_debugger": {
1516
+ "__evaluate__": "false"
1517
+ }
1499
1518
  }
1500
- },
1501
- "module": {
1502
- "removeConsole": false
1503
1519
  }
1504
1520
  }
1505
1521
  }
@@ -1,2 +1,2 @@
1
- declare const _default: any;
1
+ declare const _default: import("clientnode").PlainObject;
2
2
  export default _default;
@@ -15,10 +15,6 @@
15
15
  See https://creativecommons.org/licenses/by/3.0/deed.de
16
16
  endregion
17
17
  */
18
- // region imports
19
18
  import getConfiguration from "./configurator.js";
20
- import { ResolvedConfiguration } from "./type.js";
21
- // endregion
22
19
  const configuration = await getConfiguration();
23
- module.exports = configuration.stylelint;
24
- export default module.exports;
20
+ export default configuration.stylelint;
package/type.d.ts CHANGED
@@ -231,6 +231,7 @@ export interface ResolvedBuildConfigurationItem extends BuildConfigurationItem {
231
231
  }
232
232
  export interface Extensions {
233
233
  file: {
234
+ alias: Mapping<Array<string>>;
234
235
  external: Array<string>;
235
236
  internal: Array<string>;
236
237
  };
@@ -325,13 +326,6 @@ export interface ResolvedConfiguration {
325
326
  filePaths: Array<string>;
326
327
  };
327
328
  optimizer: BaseWebpackConfiguration['optimization'] & {
328
- babelMinify?: {
329
- bundle?: {
330
- plugin?: PlainObject;
331
- transform?: PlainObject;
332
- };
333
- module?: PlainObject;
334
- };
335
329
  cssnano?: PlainObject;
336
330
  data: ResourceLoaderConfiguration;
337
331
  font: {
@@ -346,6 +340,7 @@ export interface ResolvedConfiguration {
346
340
  exclude: null | string;
347
341
  loader: Array<string>;
348
342
  };
343
+ terser: Mapping<unknown>;
349
344
  };
350
345
  preprocessor: {
351
346
  cascadingStyleSheet: WebpackLoader & {
@@ -42,12 +42,12 @@ import HTMLTransformation from "./plugins/HTMLTransformation.js";
42
42
  await importsPromise;
43
43
 
44
44
  /// region optional imports
45
- const postcssCSSnano = await optionalImport('cssnano');
46
- const postcssFontpath = await optionalImport('postcss-fontpath');
47
- const postcssImport = await optionalImport('postcss-import');
48
- const postcssSprites = await optionalImport('postcss-sprites');
49
- const updateRule = (await optionalImport('postcss-sprites/lib/core'))?.updateRule;
50
- const postcssURL = await optionalImport('postcss-url');
45
+ const postcssCSSnano = (await optionalImport('cssnano'))?.default;
46
+ const postcssFontpath = (await optionalImport('postcss-fontpath'))?.default;
47
+ const postcssImport = (await optionalImport('postcss-import'))?.default;
48
+ const postcssSprites = (await optionalImport('postcss-sprites'))?.default;
49
+ const updateRule = (await optionalImport('postcss-sprites/lib/core'))?.default.updateRule;
50
+ const postcssURL = (await optionalImport('postcss-url'))?.default;
51
51
  /// endregion
52
52
  export const log = new Logger({
53
53
  name: 'weboptimizer.webpack-configurator'
@@ -70,12 +70,15 @@ for (const [name, alias] of Object.entries(pluginNameResourceMapping)) {
70
70
  if ('default' in plugin) plugins[name] = plugin.default;else plugins[name] = plugin;
71
71
  } else log.debug(`Optional webpack plugin "${name}" not available.`);
72
72
  }
73
+
73
74
  // endregion
74
75
  const configuration = await getConfiguration();
75
76
  Logger.configureAllInstances({
76
77
  level: configuration.debug ? 'debug' : 'warn'
77
78
  });
78
- const module = configuration.module;
79
+ const {
80
+ module
81
+ } = configuration;
79
82
  // region initialization
80
83
  /// region determine library name
81
84
  const exportFormatsNeedingAValidVariableName = ['assign', 'global', 'this', 'var', 'window'];
@@ -720,8 +723,11 @@ if (htmlAvailable && configuration.debug && configuration.development.server.liv
720
723
  // endregion
721
724
  // region plugins
722
725
  for (const pluginConfiguration of configuration.plugins) {
723
- const plugin = await optionalImport(pluginConfiguration.name.module);
724
- if (plugin) pluginInstances.push(new plugin[pluginConfiguration.name.initializer](...pluginConfiguration.parameters));else log.warn(`Configured plugin module "${pluginConfiguration.name.module}"`, 'could not be loaded.');
726
+ let plugin = await optionalImport(pluginConfiguration.name.module);
727
+ if (plugin) {
728
+ if ('default' in plugin) plugin = plugin.default;
729
+ pluginInstances.push(new plugin[pluginConfiguration.name.initializer](...pluginConfiguration.parameters));
730
+ } else log.warn(`Configured plugin module "${pluginConfiguration.name.module}"`, 'could not be loaded.');
725
731
  }
726
732
  // endregion
727
733
  // region minimizer and image compression
@@ -731,7 +737,8 @@ if (!module.optimizer.minimizer) {
731
737
  module.optimizer.minimizer = [];
732
738
  if (plugins.Terser) module.optimizer.minimizer.push(new plugins.Terser({
733
739
  extractComments: false,
734
- parallel: true
740
+ parallel: true,
741
+ ...module.optimizer.terser
735
742
  }));
736
743
  if (plugins.ImageMinimizer) module.optimizer.minimizer.push(new plugins.ImageMinimizer(extend(true, {
737
744
  minimizer: {
@@ -759,7 +766,26 @@ export let webpackConfiguration = extend(true, {
759
766
  devServer: configuration.development.server,
760
767
  experiments: {
761
768
  futureDefaults: true,
762
- outputModule: true
769
+ outputModule: true,
770
+ /*
771
+ "futureDefaults" would enable webpack's native css support
772
+ which disables the configured "mini-css-extract-plugin"
773
+ pipeline (naming outputs "<name>.css.css" instead of
774
+ "<name>.compiled.css").
775
+ */
776
+ css: false,
777
+ /*
778
+ "futureDefaults" would enable webpack's native html support
779
+ which conflicts with the configured ejs / html plugin
780
+ pipeline.
781
+ */
782
+ html: false,
783
+ /*
784
+ "futureDefaults" would enable webpack's native type stripping
785
+ which cannot handle ".tsx" files; typescript sources are
786
+ transpiled via babel instead.
787
+ */
788
+ typescript: false
763
789
  },
764
790
  // region input
765
791
  entry: configuration.injection.entry.normalized,
@@ -767,6 +793,12 @@ export let webpackConfiguration = extend(true, {
767
793
  resolve: {
768
794
  alias: module.aliases,
769
795
  aliasFields: configuration.package.aliasPropertyNames,
796
+ /*
797
+ Resolves imports which were rewritten to ".js" (e.g. via
798
+ "babel-plugin-transform-rewrite-imports") back to their
799
+ (typescript) sources.
800
+ */
801
+ extensionAlias: configuration.extensions.file.alias,
770
802
  extensions: configuration.extensions.file.internal,
771
803
  mainFields: configuration.package.main.propertyNames,
772
804
  mainFiles: configuration.package.main.fileNames,
@@ -837,7 +869,6 @@ export let webpackConfiguration = extend(true, {
837
869
  // endregion
838
870
  ...mask(module.optimizer, {
839
871
  exclude: {
840
- babelMinify: true,
841
872
  cssnano: true,
842
873
  data: true,
843
874
  font: true,
@@ -858,9 +889,10 @@ if (Array.isArray(module.skipParseRegularExpressions) ? module.skipParseRegularE
858
889
  };
859
890
  if (configuration.path.configuration.javaScript) try {
860
891
  import.meta.resolve(configuration.path.configuration.javaScript);
861
- const result = await optionalImport(configuration.path.configuration.javaScript);
892
+ let result = await optionalImport(configuration.path.configuration.javaScript);
862
893
  if (isPlainObject(result)) {
863
- if (Object.prototype.hasOwnProperty.call(result, 'replaceWebOptimizer')) webpackConfiguration = result.replaceWebOptimizer;else extend(true, webpackConfiguration, result);
894
+ if ('default' in result) result = result.default;
895
+ if ('replaceWebOptimizer' in result) webpackConfiguration = result.replaceWebOptimizer;else extend(true, webpackConfiguration, result);
864
896
  } else log.debug('Failed to load given JavaScript configuration file path', `"${configuration.path.configuration.javaScript}".`);
865
897
  } catch {
866
898
  log.debug('Optional configuration file script', `"${configuration.path.configuration.javaScript}" not available.`);