weboptimizer 4.0.103 → 4.0.105-1
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/dist/ejsLoader.js
CHANGED
|
@@ -110,28 +110,39 @@ export const loader = async function (source) {
|
|
|
110
110
|
}
|
|
111
111
|
throw new Error(`Given template file "${template}" couldn't be resolved.`);
|
|
112
112
|
};
|
|
113
|
-
const compressHTML = content =>
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
113
|
+
const compressHTML = content => {
|
|
114
|
+
const minifierOptions = extend(true, {
|
|
115
|
+
caseSensitive: true,
|
|
116
|
+
collapseInlineTagWhitespace: true,
|
|
117
|
+
collapseWhitespace: true,
|
|
118
|
+
conservativeCollapse: true,
|
|
119
|
+
minifyCSS: true,
|
|
120
|
+
minifyJS: true,
|
|
121
|
+
processScripts: ['text/ng-template', 'text/x-handlebars-template'],
|
|
122
|
+
removeAttributeQuotes: true,
|
|
123
|
+
removeComments: true,
|
|
124
|
+
removeDefaultTypeAttributes: true,
|
|
125
|
+
removeRedundantAttributes: true,
|
|
126
|
+
sortAttributes: true,
|
|
127
|
+
sortClassNames: true,
|
|
128
|
+
// NOTE: Avoids whitespace around placeholder in tags.
|
|
129
|
+
trimCustomFragments: true,
|
|
130
|
+
useShortDoctype: true
|
|
131
|
+
}, givenOptions.compress?.html || {});
|
|
128
132
|
/*
|
|
129
|
-
NOTE:
|
|
130
|
-
|
|
133
|
+
NOTE: Given options are shared with "html-webpack-plugin" and
|
|
134
|
+
"html-loader" which are based on "html-minifier-terser" so we
|
|
135
|
+
have to map its option names to "html-minifier".
|
|
131
136
|
*/
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
137
|
+
const renamedOptions = {};
|
|
138
|
+
for (const [oldName, newName] of [['removeScriptTypeAttributes', 'removeDefaultTypeAttributes'], ['removeStyleLinkTypeAttributes', 'removeDefaultTypeAttributes'], ['sortClassName', 'sortClassNames']]) if (Object.prototype.hasOwnProperty.call(minifierOptions, oldName)) {
|
|
139
|
+
renamedOptions[newName] = Boolean(renamedOptions[newName]) || Boolean(minifierOptions[oldName]);
|
|
140
|
+
delete minifierOptions[oldName];
|
|
141
|
+
}
|
|
142
|
+
Object.assign(minifierOptions, renamedOptions);
|
|
143
|
+
for (const name of ['html5', 'processConditionalComments', 'removeCDATASectionsFromCDATA', 'removeCommentsFromCDATA']) delete minifierOptions[name];
|
|
144
|
+
return minifyHTML(content, minifierOptions);
|
|
145
|
+
};
|
|
135
146
|
let result = template;
|
|
136
147
|
const isString = Boolean(options.isString);
|
|
137
148
|
delete options.isString;
|
|
@@ -165,7 +176,7 @@ export const loader = async function (source) {
|
|
|
165
176
|
encoding
|
|
166
177
|
});
|
|
167
178
|
}
|
|
168
|
-
if (step === compileSteps && givenOptions.compress?.html) result = compressHTML(result);
|
|
179
|
+
if (step === compileSteps && givenOptions.compress?.html) result = await compressHTML(result);
|
|
169
180
|
if (step === compileSteps && compileSteps % 2) {
|
|
170
181
|
/*
|
|
171
182
|
We have to use the templace class directly to get
|
|
@@ -235,7 +246,7 @@ export const loader = async function (source) {
|
|
|
235
246
|
}
|
|
236
247
|
} else {
|
|
237
248
|
result = await result(scope);
|
|
238
|
-
if (givenOptions.compress?.html) result = compressHTML(result);
|
|
249
|
+
if (givenOptions.compress?.html) result = await compressHTML(result);
|
|
239
250
|
}
|
|
240
251
|
}
|
|
241
252
|
if (compileSteps % 2) {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Chunk, Compilation, Compiler, Module } from 'webpack';
|
|
2
|
+
import type { RemoveStyleOnlyScriptsOptions } from '../type';
|
|
3
|
+
/**
|
|
4
|
+
* Module type of modules representing extracted style sheets.
|
|
5
|
+
*/
|
|
6
|
+
export declare const EXTRACTED_STYLE_MODULE_TYPE = "css/mini-extract";
|
|
7
|
+
/**
|
|
8
|
+
* Removes java script files of initial chunks which only consist of style
|
|
9
|
+
* sheets extracted into separate files like a dedicated "styles" entry. The
|
|
10
|
+
* remaining java script file would be (nearly) empty and useless.
|
|
11
|
+
*/
|
|
12
|
+
export declare class RemoveStyleOnlyScripts {
|
|
13
|
+
private defaultOptions;
|
|
14
|
+
private options;
|
|
15
|
+
constructor(options?: Partial<RemoveStyleOnlyScriptsOptions>);
|
|
16
|
+
/**
|
|
17
|
+
* Determines whether given module is an extracted style sheet or its
|
|
18
|
+
* empty java script counterpart created by the extraction loader.
|
|
19
|
+
* NOTE: Style sheet modules export their class name mapping which has to
|
|
20
|
+
* be kept.
|
|
21
|
+
* @param module - Module to check.
|
|
22
|
+
* @param compilation - Current compilation.
|
|
23
|
+
* @returns Indicator.
|
|
24
|
+
*/
|
|
25
|
+
isExtractedStyle(module: Module, compilation: Compilation): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Determines whether java script files of given chunk can be removed
|
|
28
|
+
* safely.
|
|
29
|
+
* NOTE: Asynchronous chunks are still needed to load their style sheets
|
|
30
|
+
* and chunks hosting a runtime for other chunks are needed as well. Hot
|
|
31
|
+
* module replacement adds client modules so affected chunks are kept.
|
|
32
|
+
* @param chunk - Chunk to check.
|
|
33
|
+
* @param compilation - Current compilation.
|
|
34
|
+
* @returns Indicator.
|
|
35
|
+
*/
|
|
36
|
+
isStyleOnly(chunk: Chunk, compilation: Compilation): boolean;
|
|
37
|
+
apply(compiler: Compiler): void;
|
|
38
|
+
}
|
|
39
|
+
export default RemoveStyleOnlyScripts;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// #!/usr/bin/env babel-node
|
|
2
|
+
// -*- coding: utf-8 -*-
|
|
3
|
+
/** @module RemoveStyleOnlyScripts */
|
|
4
|
+
'use strict';
|
|
5
|
+
|
|
6
|
+
/* !
|
|
7
|
+
region header
|
|
8
|
+
Copyright Torben Sickert (info["~at~"]tsickert.com) 16.12.2012
|
|
9
|
+
|
|
10
|
+
License
|
|
11
|
+
-------
|
|
12
|
+
|
|
13
|
+
This library written by Torben Sickert stands under a creative commons
|
|
14
|
+
naming 3.0 unported license.
|
|
15
|
+
See https://creativecommons.org/licenses/by/3.0/deed.de
|
|
16
|
+
endregion
|
|
17
|
+
*/
|
|
18
|
+
// region imports
|
|
19
|
+
function _defineProperty(r, t, o) { return (t = _toPropertyKey(t)) in r ? Object.defineProperty(r, t, { value: o, enumerable: !0, configurable: !0, writable: !0 }) : r[t] = o, r; }
|
|
20
|
+
function _toPropertyKey(r) { var o = _toPrimitive(r, "string"); return "symbol" == typeof o ? o : o + ""; }
|
|
21
|
+
function _toPrimitive(t, e) { if ("object" != typeof t || !t) return t; var r; if ("undefined" != typeof Symbol && void 0 !== (r = t[Symbol.toPrimitive])) { var i = r.call(t, e || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === e ? String : Number)(t); }
|
|
22
|
+
// endregion
|
|
23
|
+
/**
|
|
24
|
+
* Module type of modules representing extracted style sheets.
|
|
25
|
+
*/
|
|
26
|
+
export const EXTRACTED_STYLE_MODULE_TYPE = 'css/mini-extract';
|
|
27
|
+
/**
|
|
28
|
+
* Removes java script files of initial chunks which only consist of style
|
|
29
|
+
* sheets extracted into separate files like a dedicated "styles" entry. The
|
|
30
|
+
* remaining java script file would be (nearly) empty and useless.
|
|
31
|
+
*/
|
|
32
|
+
export class RemoveStyleOnlyScripts {
|
|
33
|
+
constructor(options = {}) {
|
|
34
|
+
_defineProperty(this, "defaultOptions", {
|
|
35
|
+
javaScriptFilePattern: /\.[cm]?js(?:\?.*)?$/
|
|
36
|
+
});
|
|
37
|
+
_defineProperty(this, "options", void 0);
|
|
38
|
+
this.options = {
|
|
39
|
+
...this.defaultOptions,
|
|
40
|
+
...options
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Determines whether given module is an extracted style sheet or its
|
|
45
|
+
* empty java script counterpart created by the extraction loader.
|
|
46
|
+
* NOTE: Style sheet modules export their class name mapping which has to
|
|
47
|
+
* be kept.
|
|
48
|
+
* @param module - Module to check.
|
|
49
|
+
* @param compilation - Current compilation.
|
|
50
|
+
* @returns Indicator.
|
|
51
|
+
*/
|
|
52
|
+
isExtractedStyle(module, compilation) {
|
|
53
|
+
if (module.type === EXTRACTED_STYLE_MODULE_TYPE) return true;
|
|
54
|
+
const loaders = module.loaders;
|
|
55
|
+
if (!(Array.isArray(loaders) && loaders.some(({
|
|
56
|
+
loader
|
|
57
|
+
}) => loader === this.options.loader))) return false;
|
|
58
|
+
const providedExports = compilation.moduleGraph.getProvidedExports(module);
|
|
59
|
+
return Array.isArray(providedExports) && providedExports.length === 0;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Determines whether java script files of given chunk can be removed
|
|
63
|
+
* safely.
|
|
64
|
+
* NOTE: Asynchronous chunks are still needed to load their style sheets
|
|
65
|
+
* and chunks hosting a runtime for other chunks are needed as well. Hot
|
|
66
|
+
* module replacement adds client modules so affected chunks are kept.
|
|
67
|
+
* @param chunk - Chunk to check.
|
|
68
|
+
* @param compilation - Current compilation.
|
|
69
|
+
* @returns Indicator.
|
|
70
|
+
*/
|
|
71
|
+
isStyleOnly(chunk, compilation) {
|
|
72
|
+
if (!chunk.isOnlyInitial()) return false;
|
|
73
|
+
for (const group of chunk.groupsIterable) if (group.chunks.length !== 1) return false;
|
|
74
|
+
for (const entrypoint of compilation.entrypoints.values()) if (entrypoint.getRuntimeChunk() === chunk && !chunk.isInGroup(entrypoint)) return false;
|
|
75
|
+
const {
|
|
76
|
+
chunkGraph
|
|
77
|
+
} = compilation;
|
|
78
|
+
if (chunkGraph.getNumberOfChunkModules(chunk) === 0) return false;
|
|
79
|
+
for (const module of chunkGraph.getChunkModulesIterable(chunk)) if (!this.isExtractedStyle(module, compilation)) return false;
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
apply(compiler) {
|
|
83
|
+
const name = 'RemoveStyleOnlyScripts';
|
|
84
|
+
compiler.hooks.thisCompilation.tap(name, compilation => {
|
|
85
|
+
compilation.hooks.processAssets.tap({
|
|
86
|
+
name,
|
|
87
|
+
/*
|
|
88
|
+
NOTE: Has to run before html plugins determine
|
|
89
|
+
their asset tags and source maps are generated.
|
|
90
|
+
*/
|
|
91
|
+
stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE
|
|
92
|
+
}, () => {
|
|
93
|
+
for (const chunk of compilation.chunks) if (this.isStyleOnly(chunk, compilation)) for (const file of Array.from(chunk.files)) if (this.options.javaScriptFilePattern.test(file)) {
|
|
94
|
+
chunk.files.delete(file);
|
|
95
|
+
compilation.deleteAsset(file);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export default RemoveStyleOnlyScripts;
|
package/dist/type.d.ts
CHANGED
|
@@ -87,6 +87,10 @@ export interface InPlaceAssetsIntoHTMLOptions {
|
|
|
87
87
|
javaScript: InPlaceAssetConfiguration | null;
|
|
88
88
|
htmlPlugin: typeof HtmlWebpackPlugin;
|
|
89
89
|
}
|
|
90
|
+
export interface RemoveStyleOnlyScriptsOptions {
|
|
91
|
+
javaScriptFilePattern: RegExp;
|
|
92
|
+
loader: string;
|
|
93
|
+
}
|
|
90
94
|
export interface AssetPathConfiguration {
|
|
91
95
|
base: string;
|
|
92
96
|
cascadingStyleSheet: string;
|
|
@@ -38,6 +38,7 @@ import getConfiguration from "./configurator.js";
|
|
|
38
38
|
import { determineAssetType, determineExternalRequest, determineModuleFilePath, getClosestPackageDescriptor, isFilePathInLocation, normalizePaths, stripLoader } from "./helper.js";
|
|
39
39
|
import InPlaceAssetsIntoHTML from "./plugins/InPlaceAssetsIntoHTML.js";
|
|
40
40
|
import HTMLTransformation from "./plugins/HTMLTransformation.js";
|
|
41
|
+
import RemoveStyleOnlyScripts from "./plugins/RemoveStyleOnlyScripts.js";
|
|
41
42
|
|
|
42
43
|
// Wait until optional filesystem modules have been loaded.
|
|
43
44
|
await importFilesystemAPI();
|
|
@@ -206,9 +207,18 @@ if (!(configuration.needed.javaScript || configuration.needed.javaScriptExtensio
|
|
|
206
207
|
///// endregion
|
|
207
208
|
///// region extract cascading style sheets
|
|
208
209
|
const cssOutputPath = configuration.files.compose.cascadingStyleSheet;
|
|
209
|
-
if (cssOutputPath && plugins.MiniCSSExtract)
|
|
210
|
-
|
|
211
|
-
|
|
210
|
+
if (cssOutputPath && plugins.MiniCSSExtract) {
|
|
211
|
+
pluginInstances.push(new plugins.MiniCSSExtract({
|
|
212
|
+
filename: typeof cssOutputPath === 'string' ? relative(configuration.path.target.base, cssOutputPath) : cssOutputPath
|
|
213
|
+
}));
|
|
214
|
+
/*
|
|
215
|
+
NOTE: Chunks consisting of extracted style sheets only would result in
|
|
216
|
+
nearly empty and useless java script files.
|
|
217
|
+
*/
|
|
218
|
+
pluginInstances.push(new RemoveStyleOnlyScripts({
|
|
219
|
+
loader: plugins.MiniCSSExtract.loader
|
|
220
|
+
}));
|
|
221
|
+
}
|
|
212
222
|
///// endregion
|
|
213
223
|
///// region performs implicit external logic
|
|
214
224
|
if (configuration.injection.external.modules === '__implicit__')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "weboptimizer",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.105-1",
|
|
4
4
|
"description": "A generic web optimizer, (module) bundler and development environment.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"webpack",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"lint:base": "eslint --config dist/eslint.config.js --no-warn-ignored src/*.ts src/*/*.ts src/test/*/*.ts",
|
|
70
70
|
"prepare": "yarn build",
|
|
71
71
|
"prettify": "yarn lint:base --fix || true",
|
|
72
|
-
"test": "yarn build:test && node --experimental-vm-modules node_modules/.bin/jest --config ./weboptimizerJest.json --noStackTrace --root-dir './' --test-regex '/dist/test/.+\\\\.js$' dist/test/browser.js dist/test/configurator.js dist/test/ejsLoader.js dist/test/helper.js dist/test/HTMLTransformation.js dist/test/InPlaceAssetsIntoHTML.js dist/test/stylelintConfigurator.js dist/test/index.js dist/test/webpackConfigurator.js",
|
|
72
|
+
"test": "yarn build:test && node --experimental-vm-modules node_modules/.bin/jest --config ./weboptimizerJest.json --noStackTrace --root-dir './' --test-regex '/dist/test/.+\\\\.js$' dist/test/browser.js dist/test/configurator.js dist/test/ejsLoader.js dist/test/helper.js dist/test/HTMLTransformation.js dist/test/InPlaceAssetsIntoHTML.js dist/test/RemoveStyleOnlyScripts.js dist/test/stylelintConfigurator.js dist/test/index.js dist/test/webpackConfigurator.js",
|
|
73
73
|
"test:coverage": "yarn test --ci --coverage --coverageReporters=text --coverageReporters=text-summary --silent --testLocationInResults",
|
|
74
74
|
"test:coverage:report": "yarn test:coverage --coverageDirectory=.coverage --coverageReporters=lcov --outputFile=lcov.info",
|
|
75
75
|
"test:watch": "yarn test --watch",
|
|
@@ -87,14 +87,14 @@
|
|
|
87
87
|
"babel-loader": "^10.1.1",
|
|
88
88
|
"babel-plugin-polyfill-corejs3": "^1.0.0",
|
|
89
89
|
"babel-plugin-transform-rewrite-imports": "^1.5.4",
|
|
90
|
-
"clientnode": "4.0.
|
|
90
|
+
"clientnode": "4.0.1531",
|
|
91
91
|
"core-js": "^3.51.0",
|
|
92
92
|
"ejs": "^7.0.2",
|
|
93
93
|
"exports-loader": "^5.0.0",
|
|
94
94
|
"extract-loader": "^5.1.0",
|
|
95
95
|
"glob-all": "^3.3.1",
|
|
96
96
|
"html-loader": "^5.1.0",
|
|
97
|
-
"html-minifier": "^
|
|
97
|
+
"html-minifier": "^5.0.1",
|
|
98
98
|
"html-webpack-plugin": "^5.6.8",
|
|
99
99
|
"imports-loader": "^5.0.0",
|
|
100
100
|
"jest-environment-jsdom": "^30.5.2",
|
|
@@ -111,7 +111,6 @@
|
|
|
111
111
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
112
112
|
"@types/ejs": "^3.1.5",
|
|
113
113
|
"@types/eslint": "^9.6.1",
|
|
114
|
-
"@types/html-minifier": "^4.0.6",
|
|
115
114
|
"@types/html-minifier-terser": "^7.0.2",
|
|
116
115
|
"@types/imagemin": "^9.0.1",
|
|
117
116
|
"@types/node": "^26.6.6",
|
|
@@ -124,7 +123,7 @@
|
|
|
124
123
|
"cssnano": "^9.9.0",
|
|
125
124
|
"eslint": "^10.14.0",
|
|
126
125
|
"eslint-config-google": "^0.14.0",
|
|
127
|
-
"eslint-plugin-jsdoc": "^65.4.
|
|
126
|
+
"eslint-plugin-jsdoc": "^65.4.3",
|
|
128
127
|
"favicons": "^7.3.1",
|
|
129
128
|
"favicons-webpack-plugin": "^6.0.1",
|
|
130
129
|
"globals": "^17.14.0",
|
|
@@ -143,20 +142,18 @@
|
|
|
143
142
|
"postcss-url": "^10.1.4",
|
|
144
143
|
"shx": "^0.4.0",
|
|
145
144
|
"style-loader": "^4.0.0",
|
|
146
|
-
"stylelint": "^
|
|
147
|
-
"stylelint-config-standard": "^
|
|
148
|
-
"stylelint-config-standard-scss": "^17.0.0",
|
|
145
|
+
"stylelint": "^18.0.0",
|
|
146
|
+
"stylelint-config-standard": "^41.0.0",
|
|
149
147
|
"terser-webpack-plugin": "^5.6.1",
|
|
150
148
|
"typescript-eslint": "^8.72.1",
|
|
151
149
|
"typescript-plugin-css-modules": "^5.3.0",
|
|
152
|
-
"web-documentation": "^1.0.
|
|
150
|
+
"web-documentation": "^1.0.72",
|
|
153
151
|
"workbox-webpack-plugin": "^7.4.1"
|
|
154
152
|
},
|
|
155
153
|
"peerDependencies": {
|
|
156
154
|
"@babel/eslint-parser": "*",
|
|
157
155
|
"@eslint/js": "*",
|
|
158
156
|
"@types/ejs": "*",
|
|
159
|
-
"@types/html-minifier": "*",
|
|
160
157
|
"@types/imagemin": "*",
|
|
161
158
|
"@types/node": "*",
|
|
162
159
|
"@types/webpack-env": "*",
|
|
@@ -201,9 +198,6 @@
|
|
|
201
198
|
"@types/ejs": {
|
|
202
199
|
"optional": true
|
|
203
200
|
},
|
|
204
|
-
"@types/html-minifier": {
|
|
205
|
-
"optional": true
|
|
206
|
-
},
|
|
207
201
|
"@types/imagemin": {
|
|
208
202
|
"optional": true
|
|
209
203
|
},
|