weboptimizer 4.0.103 → 4.0.104

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.
@@ -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) pluginInstances.push(new plugins.MiniCSSExtract({
210
- filename: typeof cssOutputPath === 'string' ? relative(configuration.path.target.base, cssOutputPath) : cssOutputPath
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.103",
3
+ "version": "4.0.104",
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",