From 9b6b8b3a8393a62b7b7a3b38c0c52b694ed51e19 Mon Sep 17 00:00:00 2001 From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com> Date: Mon, 15 Feb 2021 15:36:44 +0300 Subject: [PATCH] fix: compatibility with webpack v5 --- package-lock.json | 281 ++++---- package.json | 12 +- src/CssDependency.js | 88 --- src/CssDependencyTemplate.js | 4 - src/CssLoadingRuntimeModule.js | 203 ------ src/CssModule.js | 164 ----- src/CssModuleFactory.js | 8 - src/index.js | 680 ++++++++++++++++-- src/loader.js | 74 +- src/utils.js | 19 + test/TestCache.test.js | 134 ++-- test/TestCases.test.js | 34 +- ...c4f3445.css => 0.f4055680253d27bc029e.css} | 0 ...52c4f3445.css => f4055680253d27bc029e.css} | 0 .../expected/webpack-5/main.js | 31 +- .../expected/webpack-5/common.js | 4 +- .../dependOn/expected/webpack-5/common.js | 4 +- .../expected/webpack-5/main.js | 99 +-- .../expected/webpack-5/main.js | 65 +- .../expected/webpack-5/main.js | 29 +- test/cases/hmr/expected/webpack-5/main.js | 6 +- .../expected/webpack-5/main.js | 1 + .../insert-string/expected/webpack-5/main.js | 1 + .../expected/webpack-5/main.js | 1 + test/cases/no-loader/index.js | 1 + test/cases/no-loader/style.css | 3 + test/cases/no-loader/webpack.config.js | 18 + .../expected/webpack-5/runtime~main.js | 4 +- 28 files changed, 1040 insertions(+), 928 deletions(-) delete mode 100644 src/CssDependency.js delete mode 100644 src/CssDependencyTemplate.js delete mode 100644 src/CssLoadingRuntimeModule.js delete mode 100644 src/CssModule.js delete mode 100644 src/CssModuleFactory.js rename test/cases/chunkFilename-fullhash/expected/webpack-5/{0.ff87ec1bb4052c4f3445.css => 0.f4055680253d27bc029e.css} (100%) rename test/cases/chunkFilename-fullhash/expected/webpack-5/{ff87ec1bb4052c4f3445.css => f4055680253d27bc029e.css} (100%) create mode 100644 test/cases/no-loader/index.js create mode 100644 test/cases/no-loader/style.css create mode 100644 test/cases/no-loader/webpack.config.js diff --git a/package-lock.json b/package-lock.json index a3980aeb..953de131 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,7 @@ "requires": true, "packages": { "": { - "version": "1.3.5", + "version": "1.3.6", "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", @@ -13,9 +13,9 @@ "webpack-sources": "^1.1.0" }, "devDependencies": { - "@babel/cli": "^7.12.13", - "@babel/core": "^7.12.13", - "@babel/preset-env": "^7.12.13", + "@babel/cli": "^7.12.16", + "@babel/core": "^7.12.16", + "@babel/preset-env": "^7.12.16", "@commitlint/cli": "^11.0.0", "@commitlint/config-conventional": "^11.0.0", "@webpack-contrib/defaults": "^6.3.0", @@ -24,11 +24,11 @@ "babel-jest": "^26.6.3", "bootstrap": "^4.6.0", "cross-env": "^7.0.3", - "css-loader": "^5.0.1", + "css-loader": "^5.0.2", "del": "^6.0.0", "del-cli": "^3.0.1", "es-check": "^5.2.0", - "eslint": "^7.19.0", + "eslint": "^7.20.0", "eslint-config-prettier": "^7.2.0", "eslint-plugin-import": "^2.22.1", "file-loader": "^6.2.0", @@ -40,7 +40,7 @@ "npm-run-all": "^4.1.5", "prettier": "^2.2.1", "standard-version": "^9.1.0", - "webpack": "^5.21.1", + "webpack": "^5.22.0", "webpack-cli": "^4.5.0", "webpack-dev-server": "^3.7.2" }, @@ -56,13 +56,11 @@ } }, "node_modules/@babel/cli": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.12.13.tgz", - "integrity": "sha512-Zto3HPeE0GRmaxobUl7NvFTo97NKe1zdAuWqTO8oka7nE0IIqZ4CFvuRZe1qf+ZMd7eHMhwqrecjwc10mjXo/g==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.12.16.tgz", + "integrity": "sha512-cKWkNCxbpjSuYLbdeJs4kOnyW1E2D65pu7SodXDOkzahIN/wSgT8geIqf6+pJTgCo47zrOMGcJTmjSFe5WKYwQ==", "dev": true, "dependencies": { - "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents", - "chokidar": "^3.4.0", "commander": "^4.0.1", "convert-source-map": "^1.1.0", "fs-readdir-recursive": "^1.1.0", @@ -109,16 +107,16 @@ "dev": true }, "node_modules/@babel/core": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.13.tgz", - "integrity": "sha512-BQKE9kXkPlXHPeqissfxo0lySWJcYdEP0hdtJOH/iJfDdhOCcgtNCjftCJg3qqauB4h+lz2N6ixM++b9DN1Tcw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.16.tgz", + "integrity": "sha512-t/hHIB504wWceOeaOoONOhu+gX+hpjfeN6YRBT209X/4sibZQfSF1I0HFRRlBe97UZZosGx5XwUg1ZgNbelmNw==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.12.13", + "@babel/generator": "^7.12.15", "@babel/helper-module-transforms": "^7.12.13", "@babel/helpers": "^7.12.13", - "@babel/parser": "^7.12.13", + "@babel/parser": "^7.12.16", "@babel/template": "^7.12.13", "@babel/traverse": "^7.12.13", "@babel/types": "^7.12.13", @@ -205,13 +203,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.13.tgz", - "integrity": "sha512-dXof20y/6wB5HnLOGyLh/gobsMvDNoekcC+8MCV2iaTd5JemhFkPD73QB+tK3iFC9P0xJC73B6MvKkyUfS9cCw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.16.tgz", + "integrity": "sha512-dBHNEEaZx7F3KoUYqagIhRIeqyyuI65xMndMZ3WwGwEBI609I4TleYQHcrS627vbKyNTXqShoN+fvYD9HuQxAg==", "dev": true, "dependencies": { "@babel/compat-data": "^7.12.13", - "@babel/helper-validator-option": "^7.12.11", + "@babel/helper-validator-option": "^7.12.16", "browserslist": "^4.14.5", "semver": "^5.5.0" }, @@ -393,9 +391,9 @@ "dev": true }, "node_modules/@babel/helper-validator-option": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz", - "integrity": "sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.16.tgz", + "integrity": "sha512-uCgsDBPUQDvzr11ePPo4TVEocxj8RXjUVSC/Y8N1YpVAI/XDdUwGJu78xmlGhTxj2ntaWM7n9LQdRtyhOzT2YQ==", "dev": true }, "node_modules/@babel/helper-wrap-function": { @@ -433,9 +431,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz", - "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -472,13 +470,16 @@ } }, "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz", - "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.16.tgz", + "integrity": "sha512-yiDkYFapVxNOCcBfLnsb/qdsliroM+vc3LHiZwS4gh7pFjo5Xq3BDhYBNn3H3ao+hWPvqeeTdU+s+FIvokov+w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-dynamic-import": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-export-namespace-from": { @@ -574,9 +575,9 @@ } }, "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.13.tgz", - "integrity": "sha512-0ZwjGfTcnZqyV3y9DSD1Yk3ebp+sIUpT2YDqP8hovzaNZnQq2Kd7PEqa6iOIUDBXBt7Jl3P7YAcEIL5Pz8u09Q==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.16.tgz", + "integrity": "sha512-O3ohPwOhkwji5Mckb7F/PJpJVJY3DpPsrt/F0Bk40+QMk9QpAIqeGusHWqu/mYqsM8oBa6TziL/2mbERWsUZjg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13", @@ -653,6 +654,9 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-export-namespace-from": { @@ -1160,19 +1164,19 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.13.tgz", - "integrity": "sha512-JUVlizG8SoFTz4LmVUL8++aVwzwxcvey3N0j1tRbMAXVEy95uQ/cnEkmEKHN00Bwq4voAV3imQGnQvpkLAxsrw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.16.tgz", + "integrity": "sha512-BXCAXy8RE/TzX416pD2hsVdkWo0G+tYd16pwnRV4Sc0fRwTLRS/Ssv8G5RLXUGQv7g4FG7TXkdDJxCjQ5I+Zjg==", "dev": true, "dependencies": { "@babel/compat-data": "^7.12.13", - "@babel/helper-compilation-targets": "^7.12.13", + "@babel/helper-compilation-targets": "^7.12.16", "@babel/helper-module-imports": "^7.12.13", "@babel/helper-plugin-utils": "^7.12.13", - "@babel/helper-validator-option": "^7.12.11", + "@babel/helper-validator-option": "^7.12.16", "@babel/plugin-proposal-async-generator-functions": "^7.12.13", "@babel/plugin-proposal-class-properties": "^7.12.13", - "@babel/plugin-proposal-dynamic-import": "^7.12.1", + "@babel/plugin-proposal-dynamic-import": "^7.12.16", "@babel/plugin-proposal-export-namespace-from": "^7.12.13", "@babel/plugin-proposal-json-strings": "^7.12.13", "@babel/plugin-proposal-logical-assignment-operators": "^7.12.13", @@ -1180,7 +1184,7 @@ "@babel/plugin-proposal-numeric-separator": "^7.12.13", "@babel/plugin-proposal-object-rest-spread": "^7.12.13", "@babel/plugin-proposal-optional-catch-binding": "^7.12.13", - "@babel/plugin-proposal-optional-chaining": "^7.12.13", + "@babel/plugin-proposal-optional-chaining": "^7.12.16", "@babel/plugin-proposal-private-methods": "^7.12.13", "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", "@babel/plugin-syntax-async-generators": "^7.8.0", @@ -2269,7 +2273,6 @@ "jest-resolve": "^26.6.2", "jest-util": "^26.6.2", "jest-worker": "^26.6.2", - "node-notifier": "^8.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -5743,26 +5746,33 @@ } }, "node_modules/css-loader": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.0.1.tgz", - "integrity": "sha512-cXc2ti9V234cq7rJzFKhirb2L2iPy8ZjALeVJAozXYz9te3r4eqLSixNAbMDJSgJEQywqXzs8gonxaboeKqwiw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.0.2.tgz", + "integrity": "sha512-gbkBigdcHbmNvZ1Cg6aV6qh6k9N6XOr8YWzISLQGrwk2mgOH8LLrizhkxbDhQtaLtktyKHD4970S0xwz5btfTA==", "dev": true, "dependencies": { "camelcase": "^6.2.0", "cssesc": "^3.0.0", - "icss-utils": "^5.0.0", + "icss-utils": "^5.1.0", "loader-utils": "^2.0.0", - "postcss": "^8.1.4", + "postcss": "^8.2.4", "postcss-modules-extract-imports": "^3.0.0", "postcss-modules-local-by-default": "^4.0.0", "postcss-modules-scope": "^3.0.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.1.0", "schema-utils": "^3.0.0", - "semver": "^7.3.2" + "semver": "^7.3.4" }, "engines": { "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.27.0 || ^5.0.0" } }, "node_modules/css-loader/node_modules/camelcase": { @@ -6764,12 +6774,12 @@ } }, "node_modules/eslint": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.19.0.tgz", - "integrity": "sha512-CGlMgJY56JZ9ZSYhJuhow61lMPPjUzWmChFya71Z/jilVos7mR/jPgaEfVGgMBY5DshbKdG8Ezb8FDCHcoMEMg==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.20.0.tgz", + "integrity": "sha512-qGi0CTcOGP2OtCQBgWZlQjcTuP0XkIpYFj25XtRTQSHC+umNnp7UMshr2G8SLsRFYDdAPFeHOsiteadmMH02Yw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", + "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.3.0", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -6781,7 +6791,7 @@ "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", "espree": "^7.3.1", - "esquery": "^1.2.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", "file-entry-cache": "^6.0.0", "functional-red-black-tree": "^1.0.1", @@ -7053,6 +7063,15 @@ "node": ">=4" } }, + "node_modules/eslint/node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, "node_modules/eslint/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -7309,9 +7328,9 @@ } }, "node_modules/esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -8770,7 +8789,6 @@ "minimist": "^1.2.5", "neo-async": "^2.6.0", "source-map": "^0.6.1", - "uglify-js": "^3.1.4", "wordwrap": "^1.0.0" }, "bin": { @@ -10617,7 +10635,6 @@ "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", "jest-regex-util": "^26.0.0", "jest-serializer": "^26.6.2", @@ -16721,9 +16738,9 @@ } }, "node_modules/terser": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.5.1.tgz", - "integrity": "sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.0.tgz", + "integrity": "sha512-vyqLMoqadC1uR0vywqOZzriDYzgEkNJFK4q9GeyOBHIbiECHiWLKcWfbQWAUaPfxkjDhapSlZB9f7fkMrvkVjA==", "dev": true, "dependencies": { "commander": "^2.20.0", @@ -16752,6 +16769,13 @@ }, "engines": { "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" } }, "node_modules/terser-webpack-plugin/node_modules/p-limit": { @@ -16764,6 +16788,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/terser/node_modules/commander": { @@ -17418,9 +17445,9 @@ } }, "node_modules/watchpack": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.0.tgz", - "integrity": "sha512-UjgD1mqjkG99+3lgG36at4wPnUXNvis2v1utwTgQ43C22c4LD71LsYMExdWXh4HZ+RmW+B0t1Vrg2GpXAkTOQw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", + "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", "dev": true, "dependencies": { "glob-to-regexp": "^0.4.1", @@ -17449,9 +17476,9 @@ } }, "node_modules/webpack": { - "version": "5.21.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.21.1.tgz", - "integrity": "sha512-H/fjQiDETEZDKoZm/LhvDBxOIKf9rfOdqb2pKTHRvBFMIRtwAwYlPCgBd0gc5xiDG5DqkxAiFZgAF/4H41wMuQ==", + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.22.0.tgz", + "integrity": "sha512-xqlb6r9RUXda/d9iA6P7YRTP1ChWeP50TEESKMMNIg0u8/Rb66zN9YJJO7oYgJTRyFyYi43NVC5feG45FSO1vQ==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.0", @@ -17820,7 +17847,6 @@ "anymatch": "^2.0.0", "async-each": "^1.0.1", "braces": "^2.3.2", - "fsevents": "^1.2.7", "glob-parent": "^3.1.0", "inherits": "^2.0.3", "is-binary-path": "^1.0.0", @@ -18592,9 +18618,9 @@ }, "dependencies": { "@babel/cli": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.12.13.tgz", - "integrity": "sha512-Zto3HPeE0GRmaxobUl7NvFTo97NKe1zdAuWqTO8oka7nE0IIqZ4CFvuRZe1qf+ZMd7eHMhwqrecjwc10mjXo/g==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.12.16.tgz", + "integrity": "sha512-cKWkNCxbpjSuYLbdeJs4kOnyW1E2D65pu7SodXDOkzahIN/wSgT8geIqf6+pJTgCo47zrOMGcJTmjSFe5WKYwQ==", "dev": true, "requires": { "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents", @@ -18633,16 +18659,16 @@ "dev": true }, "@babel/core": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.13.tgz", - "integrity": "sha512-BQKE9kXkPlXHPeqissfxo0lySWJcYdEP0hdtJOH/iJfDdhOCcgtNCjftCJg3qqauB4h+lz2N6ixM++b9DN1Tcw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.16.tgz", + "integrity": "sha512-t/hHIB504wWceOeaOoONOhu+gX+hpjfeN6YRBT209X/4sibZQfSF1I0HFRRlBe97UZZosGx5XwUg1ZgNbelmNw==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.12.13", + "@babel/generator": "^7.12.15", "@babel/helper-module-transforms": "^7.12.13", "@babel/helpers": "^7.12.13", - "@babel/parser": "^7.12.13", + "@babel/parser": "^7.12.16", "@babel/template": "^7.12.13", "@babel/traverse": "^7.12.13", "@babel/types": "^7.12.13", @@ -18717,13 +18743,13 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.13.tgz", - "integrity": "sha512-dXof20y/6wB5HnLOGyLh/gobsMvDNoekcC+8MCV2iaTd5JemhFkPD73QB+tK3iFC9P0xJC73B6MvKkyUfS9cCw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.16.tgz", + "integrity": "sha512-dBHNEEaZx7F3KoUYqagIhRIeqyyuI65xMndMZ3WwGwEBI609I4TleYQHcrS627vbKyNTXqShoN+fvYD9HuQxAg==", "dev": true, "requires": { "@babel/compat-data": "^7.12.13", - "@babel/helper-validator-option": "^7.12.11", + "@babel/helper-validator-option": "^7.12.16", "browserslist": "^4.14.5", "semver": "^5.5.0" } @@ -18896,9 +18922,9 @@ "dev": true }, "@babel/helper-validator-option": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz", - "integrity": "sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.16.tgz", + "integrity": "sha512-uCgsDBPUQDvzr11ePPo4TVEocxj8RXjUVSC/Y8N1YpVAI/XDdUwGJu78xmlGhTxj2ntaWM7n9LQdRtyhOzT2YQ==", "dev": true }, "@babel/helper-wrap-function": { @@ -18936,9 +18962,9 @@ } }, "@babel/parser": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz", - "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz", + "integrity": "sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { @@ -18963,12 +18989,12 @@ } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz", - "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.16.tgz", + "integrity": "sha512-yiDkYFapVxNOCcBfLnsb/qdsliroM+vc3LHiZwS4gh7pFjo5Xq3BDhYBNn3H3ao+hWPvqeeTdU+s+FIvokov+w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-dynamic-import": "^7.8.0" } }, @@ -19044,9 +19070,9 @@ } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.13.tgz", - "integrity": "sha512-0ZwjGfTcnZqyV3y9DSD1Yk3ebp+sIUpT2YDqP8hovzaNZnQq2Kd7PEqa6iOIUDBXBt7Jl3P7YAcEIL5Pz8u09Q==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.16.tgz", + "integrity": "sha512-O3ohPwOhkwji5Mckb7F/PJpJVJY3DpPsrt/F0Bk40+QMk9QpAIqeGusHWqu/mYqsM8oBa6TziL/2mbERWsUZjg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.12.13", @@ -19513,19 +19539,19 @@ } }, "@babel/preset-env": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.13.tgz", - "integrity": "sha512-JUVlizG8SoFTz4LmVUL8++aVwzwxcvey3N0j1tRbMAXVEy95uQ/cnEkmEKHN00Bwq4voAV3imQGnQvpkLAxsrw==", + "version": "7.12.16", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.16.tgz", + "integrity": "sha512-BXCAXy8RE/TzX416pD2hsVdkWo0G+tYd16pwnRV4Sc0fRwTLRS/Ssv8G5RLXUGQv7g4FG7TXkdDJxCjQ5I+Zjg==", "dev": true, "requires": { "@babel/compat-data": "^7.12.13", - "@babel/helper-compilation-targets": "^7.12.13", + "@babel/helper-compilation-targets": "^7.12.16", "@babel/helper-module-imports": "^7.12.13", "@babel/helper-plugin-utils": "^7.12.13", - "@babel/helper-validator-option": "^7.12.11", + "@babel/helper-validator-option": "^7.12.16", "@babel/plugin-proposal-async-generator-functions": "^7.12.13", "@babel/plugin-proposal-class-properties": "^7.12.13", - "@babel/plugin-proposal-dynamic-import": "^7.12.1", + "@babel/plugin-proposal-dynamic-import": "^7.12.16", "@babel/plugin-proposal-export-namespace-from": "^7.12.13", "@babel/plugin-proposal-json-strings": "^7.12.13", "@babel/plugin-proposal-logical-assignment-operators": "^7.12.13", @@ -19533,7 +19559,7 @@ "@babel/plugin-proposal-numeric-separator": "^7.12.13", "@babel/plugin-proposal-object-rest-spread": "^7.12.13", "@babel/plugin-proposal-optional-catch-binding": "^7.12.13", - "@babel/plugin-proposal-optional-chaining": "^7.12.13", + "@babel/plugin-proposal-optional-chaining": "^7.12.16", "@babel/plugin-proposal-private-methods": "^7.12.13", "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", "@babel/plugin-syntax-async-generators": "^7.8.0", @@ -23261,23 +23287,23 @@ } }, "css-loader": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.0.1.tgz", - "integrity": "sha512-cXc2ti9V234cq7rJzFKhirb2L2iPy8ZjALeVJAozXYz9te3r4eqLSixNAbMDJSgJEQywqXzs8gonxaboeKqwiw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.0.2.tgz", + "integrity": "sha512-gbkBigdcHbmNvZ1Cg6aV6qh6k9N6XOr8YWzISLQGrwk2mgOH8LLrizhkxbDhQtaLtktyKHD4970S0xwz5btfTA==", "dev": true, "requires": { "camelcase": "^6.2.0", "cssesc": "^3.0.0", - "icss-utils": "^5.0.0", + "icss-utils": "^5.1.0", "loader-utils": "^2.0.0", - "postcss": "^8.1.4", + "postcss": "^8.2.4", "postcss-modules-extract-imports": "^3.0.0", "postcss-modules-local-by-default": "^4.0.0", "postcss-modules-scope": "^3.0.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.1.0", "schema-utils": "^3.0.0", - "semver": "^7.3.2" + "semver": "^7.3.4" }, "dependencies": { "camelcase": { @@ -24077,12 +24103,12 @@ } }, "eslint": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.19.0.tgz", - "integrity": "sha512-CGlMgJY56JZ9ZSYhJuhow61lMPPjUzWmChFya71Z/jilVos7mR/jPgaEfVGgMBY5DshbKdG8Ezb8FDCHcoMEMg==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.20.0.tgz", + "integrity": "sha512-qGi0CTcOGP2OtCQBgWZlQjcTuP0XkIpYFj25XtRTQSHC+umNnp7UMshr2G8SLsRFYDdAPFeHOsiteadmMH02Yw==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", + "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.3.0", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -24094,7 +24120,7 @@ "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", "espree": "^7.3.1", - "esquery": "^1.2.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", "file-entry-cache": "^6.0.0", "functional-red-black-tree": "^1.0.1", @@ -24121,6 +24147,15 @@ "v8-compile-cache": "^2.0.3" }, "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -24492,9 +24527,9 @@ "dev": true }, "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -32027,9 +32062,9 @@ } }, "terser": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.5.1.tgz", - "integrity": "sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.0.tgz", + "integrity": "sha512-vyqLMoqadC1uR0vywqOZzriDYzgEkNJFK4q9GeyOBHIbiECHiWLKcWfbQWAUaPfxkjDhapSlZB9f7fkMrvkVjA==", "dev": true, "requires": { "commander": "^2.20.0", @@ -32597,9 +32632,9 @@ } }, "watchpack": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.0.tgz", - "integrity": "sha512-UjgD1mqjkG99+3lgG36at4wPnUXNvis2v1utwTgQ43C22c4LD71LsYMExdWXh4HZ+RmW+B0t1Vrg2GpXAkTOQw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", + "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", "dev": true, "requires": { "glob-to-regexp": "^0.4.1", @@ -32622,9 +32657,9 @@ "dev": true }, "webpack": { - "version": "5.21.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.21.1.tgz", - "integrity": "sha512-H/fjQiDETEZDKoZm/LhvDBxOIKf9rfOdqb2pKTHRvBFMIRtwAwYlPCgBd0gc5xiDG5DqkxAiFZgAF/4H41wMuQ==", + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.22.0.tgz", + "integrity": "sha512-xqlb6r9RUXda/d9iA6P7YRTP1ChWeP50TEESKMMNIg0u8/Rb66zN9YJJO7oYgJTRyFyYi43NVC5feG45FSO1vQ==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.0", diff --git a/package.json b/package.json index 1897af97..0eee0b01 100644 --- a/package.json +++ b/package.json @@ -48,9 +48,9 @@ "webpack-sources": "^1.1.0" }, "devDependencies": { - "@babel/cli": "^7.12.13", - "@babel/core": "^7.12.13", - "@babel/preset-env": "^7.12.13", + "@babel/cli": "^7.12.16", + "@babel/core": "^7.12.16", + "@babel/preset-env": "^7.12.16", "@commitlint/cli": "^11.0.0", "@commitlint/config-conventional": "^11.0.0", "@webpack-contrib/defaults": "^6.3.0", @@ -59,11 +59,11 @@ "babel-jest": "^26.6.3", "bootstrap": "^4.6.0", "cross-env": "^7.0.3", - "css-loader": "^5.0.1", + "css-loader": "^5.0.2", "del": "^6.0.0", "del-cli": "^3.0.1", "es-check": "^5.2.0", - "eslint": "^7.19.0", + "eslint": "^7.20.0", "eslint-config-prettier": "^7.2.0", "eslint-plugin-import": "^2.22.1", "file-loader": "^6.2.0", @@ -75,7 +75,7 @@ "npm-run-all": "^4.1.5", "prettier": "^2.2.1", "standard-version": "^9.1.0", - "webpack": "^5.21.1", + "webpack": "^5.22.0", "webpack-cli": "^4.5.0", "webpack-dev-server": "^3.7.2" }, diff --git a/src/CssDependency.js b/src/CssDependency.js deleted file mode 100644 index e4869ba1..00000000 --- a/src/CssDependency.js +++ /dev/null @@ -1,88 +0,0 @@ -import webpack from 'webpack'; - -class CssDependency extends webpack.Dependency { - constructor( - { identifier, content, media, sourceMap }, - context, - identifierIndex - ) { - super(); - - this.identifier = identifier; - this.identifierIndex = identifierIndex; - this.content = content; - this.media = media; - this.sourceMap = sourceMap; - this.context = context; - // eslint-disable-next-line no-undefined - this.assets = undefined; - // eslint-disable-next-line no-undefined - this.assetsInfo = undefined; - } - - getResourceIdentifier() { - return `css-module-${this.identifier}-${this.identifierIndex}`; - } - - // eslint-disable-next-line class-methods-use-this - getModuleEvaluationSideEffectsState() { - return webpack.ModuleGraphConnection.TRANSITIVE_ONLY; - } - - serialize(context) { - const { write } = context; - - write(this.identifier); - write(this.content); - write(this.media); - write(this.sourceMap); - write(this.context); - write(this.identifierIndex); - write(this.assets); - write(this.assetsInfo); - - super.serialize(context); - } - - deserialize(context) { - super.deserialize(context); - } -} - -if (webpack.util && webpack.util.serialization) { - webpack.util.serialization.register( - CssDependency, - 'mini-css-extract-plugin/dist/CssDependency', - null, - { - serialize(instance, context) { - instance.serialize(context); - }, - deserialize(context) { - const { read } = context; - const dep = new CssDependency( - { - identifier: read(), - content: read(), - media: read(), - sourceMap: read(), - }, - read(), - read() - ); - - const assets = read(); - const assetsInfo = read(); - - dep.assets = assets; - dep.assetsInfo = assetsInfo; - - dep.deserialize(context); - - return dep; - }, - } - ); -} - -export default CssDependency; diff --git a/src/CssDependencyTemplate.js b/src/CssDependencyTemplate.js deleted file mode 100644 index 747a61d6..00000000 --- a/src/CssDependencyTemplate.js +++ /dev/null @@ -1,4 +0,0 @@ -export default class CssDependencyTemplate { - // eslint-disable-next-line class-methods-use-this - apply() {} -} diff --git a/src/CssLoadingRuntimeModule.js b/src/CssLoadingRuntimeModule.js deleted file mode 100644 index ce16abc6..00000000 --- a/src/CssLoadingRuntimeModule.js +++ /dev/null @@ -1,203 +0,0 @@ -import { RuntimeGlobals, RuntimeModule, Template, util } from 'webpack'; - -import { MODULE_TYPE } from './utils'; - -const { - comparators: { compareModulesByIdentifier }, -} = util; - -const getCssChunkObject = (mainChunk, compilation) => { - const obj = {}; - const { chunkGraph } = compilation; - - for (const chunk of mainChunk.getAllAsyncChunks()) { - const modules = chunkGraph.getOrderedChunkModulesIterable( - chunk, - compareModulesByIdentifier - ); - for (const module of modules) { - if (module.type === MODULE_TYPE) { - obj[chunk.id] = 1; - break; - } - } - } - - return obj; -}; - -module.exports = class CssLoadingRuntimeModule extends RuntimeModule { - constructor(runtimeRequirements, runtimeOptions) { - super('css loading', 10); - this.runtimeRequirements = runtimeRequirements; - this.runtimeOptions = runtimeOptions; - } - - generate() { - const { chunk, compilation, runtimeRequirements } = this; - const { - runtimeTemplate, - outputOptions: { crossOriginLoading }, - } = compilation; - const chunkMap = getCssChunkObject(chunk, compilation); - - const withLoading = - runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers) && - Object.keys(chunkMap).length > 0; - const withHmr = runtimeRequirements.has( - RuntimeGlobals.hmrDownloadUpdateHandlers - ); - - if (!withLoading && !withHmr) return null; - - return Template.asString([ - `var createStylesheet = ${runtimeTemplate.basicFunction( - 'chunkId, fullhref, resolve, reject', - [ - 'var linkTag = document.createElement("link");', - this.runtimeOptions.attributes, - 'linkTag.rel = "stylesheet";', - this.runtimeOptions.linkType - ? `linkTag.type = ${JSON.stringify(this.runtimeOptions.linkType)};` - : '', - `var onLinkComplete = ${runtimeTemplate.basicFunction('event', [ - '// avoid mem leaks.', - 'linkTag.onerror = linkTag.onload = null;', - "if (event.type === 'load') {", - Template.indent(['resolve();']), - '} else {', - Template.indent([ - "var errorType = event && (event.type === 'load' ? 'missing' : event.type);", - 'var realHref = event && event.target && event.target.href || fullhref;', - 'var err = new Error("Loading CSS chunk " + chunkId + " failed.\\n(" + realHref + ")");', - 'err.code = "CSS_CHUNK_LOAD_FAILED";', - 'err.type = errorType;', - 'err.request = realHref;', - 'linkTag.parentNode.removeChild(linkTag)', - 'reject(err);', - ]), - '}', - ])}`, - 'linkTag.onerror = linkTag.onload = onLinkComplete;', - 'linkTag.href = fullhref;', - crossOriginLoading - ? Template.asString([ - `if (linkTag.href.indexOf(window.location.origin + '/') !== 0) {`, - Template.indent( - `linkTag.crossOrigin = ${JSON.stringify(crossOriginLoading)};` - ), - '}', - ]) - : '', - this.runtimeOptions.insert, - 'return linkTag;', - ] - )};`, - `var findStylesheet = ${runtimeTemplate.basicFunction('href, fullhref', [ - 'var existingLinkTags = document.getElementsByTagName("link");', - 'for(var i = 0; i < existingLinkTags.length; i++) {', - Template.indent([ - 'var tag = existingLinkTags[i];', - 'var dataHref = tag.getAttribute("data-href") || tag.getAttribute("href");', - 'if(tag.rel === "stylesheet" && (dataHref === href || dataHref === fullhref)) return tag;', - ]), - '}', - 'var existingStyleTags = document.getElementsByTagName("style");', - 'for(var i = 0; i < existingStyleTags.length; i++) {', - Template.indent([ - 'var tag = existingStyleTags[i];', - 'var dataHref = tag.getAttribute("data-href");', - 'if(dataHref === href || dataHref === fullhref) return tag;', - ]), - '}', - ])};`, - `var loadStylesheet = ${runtimeTemplate.basicFunction( - 'chunkId', - `return new Promise(${runtimeTemplate.basicFunction('resolve, reject', [ - `var href = ${RuntimeGlobals.require}.miniCssF(chunkId);`, - `var fullhref = ${RuntimeGlobals.publicPath} + href;`, - 'if(findStylesheet(href, fullhref)) return resolve();', - 'createStylesheet(chunkId, fullhref, resolve, reject);', - ])});` - )}`, - withLoading - ? Template.asString([ - '// object to store loaded CSS chunks', - 'var installedCssChunks = {', - Template.indent( - chunk.ids.map((id) => `${JSON.stringify(id)}: 0`).join(',\n') - ), - '};', - '', - `${ - RuntimeGlobals.ensureChunkHandlers - }.miniCss = ${runtimeTemplate.basicFunction('chunkId, promises', [ - `var cssChunks = ${JSON.stringify(chunkMap)};`, - 'if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);', - 'else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {', - Template.indent([ - `promises.push(installedCssChunks[chunkId] = loadStylesheet(chunkId).then(${runtimeTemplate.basicFunction( - '', - 'installedCssChunks[chunkId] = 0;' - )}, ${runtimeTemplate.basicFunction('e', [ - 'delete installedCssChunks[chunkId];', - 'throw e;', - ])}));`, - ]), - '}', - ])};`, - ]) - : '// no chunk loading', - '', - withHmr - ? Template.asString([ - 'var oldTags = [];', - 'var newTags = [];', - `var applyHandler = ${runtimeTemplate.basicFunction('options', [ - `return { dispose: ${runtimeTemplate.basicFunction('', [ - 'for(var i = 0; i < oldTags.length; i++) {', - Template.indent([ - 'var oldTag = oldTags[i];', - 'if(oldTag.parentNode) oldTag.parentNode.removeChild(oldTag);', - ]), - '}', - 'oldTags.length = 0;', - ])}, apply: ${runtimeTemplate.basicFunction('', [ - 'for(var i = 0; i < newTags.length; i++) newTags[i].rel = "stylesheet";', - 'newTags.length = 0;', - ])} };`, - ])}`, - `${ - RuntimeGlobals.hmrDownloadUpdateHandlers - }.miniCss = ${runtimeTemplate.basicFunction( - 'chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList', - [ - 'applyHandlers.push(applyHandler);', - `chunkIds.forEach(${runtimeTemplate.basicFunction('chunkId', [ - `var href = ${RuntimeGlobals.require}.miniCssF(chunkId);`, - `var fullhref = ${RuntimeGlobals.publicPath} + href;`, - 'const oldTag = findStylesheet(href, fullhref);', - 'if(!oldTag) return;', - `promises.push(new Promise(${runtimeTemplate.basicFunction( - 'resolve, reject', - [ - `var tag = createStylesheet(chunkId, fullhref, ${runtimeTemplate.basicFunction( - '', - [ - 'tag.as = "style";', - 'tag.rel = "preload";', - 'resolve();', - ] - )}, reject);`, - 'oldTags.push(oldTag);', - 'newTags.push(tag);', - ] - )}));`, - ])});`, - ] - )}`, - ]) - : '// no hmr', - ]); - } -}; diff --git a/src/CssModule.js b/src/CssModule.js deleted file mode 100644 index b7b48a83..00000000 --- a/src/CssModule.js +++ /dev/null @@ -1,164 +0,0 @@ -import webpack from 'webpack'; - -import { MODULE_TYPE } from './utils'; - -const TYPES = new Set([MODULE_TYPE]); -const CODE_GENERATION_RESULT = { - sources: new Map(), - runtimeRequirements: new Set(), -}; - -class CssModule extends webpack.Module { - constructor({ - context, - identifier, - identifierIndex, - content, - media, - sourceMap, - assets, - assetsInfo, - }) { - super(MODULE_TYPE, context); - - this.id = ''; - this._context = context; - this._identifier = identifier; - this._identifierIndex = identifierIndex; - this.content = content; - this.media = media; - this.sourceMap = sourceMap; - this.buildInfo = { - assets, - assetsInfo, - }; - this.buildMeta = {}; - } - - // no source() so webpack 4 doesn't do add stuff to the bundle - - size() { - return this.content.length; - } - - identifier() { - return `css|${this._identifier}|${this._identifierIndex}`; - } - - readableIdentifier(requestShortener) { - return `css ${requestShortener.shorten(this._identifier)}${ - this._identifierIndex ? ` (${this._identifierIndex})` : '' - }`; - } - - // eslint-disable-next-line class-methods-use-this - getSourceTypes() { - return TYPES; - } - - // eslint-disable-next-line class-methods-use-this - codeGeneration() { - return CODE_GENERATION_RESULT; - } - - nameForCondition() { - const resource = this._identifier.split('!').pop(); - const idx = resource.indexOf('?'); - - if (idx >= 0) { - return resource.substring(0, idx); - } - - return resource; - } - - updateCacheModule(module) { - this.content = module.content; - this.media = module.media; - this.sourceMap = module.sourceMap; - } - - // eslint-disable-next-line class-methods-use-this - needRebuild() { - return true; - } - - // eslint-disable-next-line class-methods-use-this - needBuild(context, callback) { - callback(null, false); - } - - build(options, compilation, resolver, fileSystem, callback) { - this.buildInfo = {}; - this.buildMeta = {}; - - callback(); - } - - updateHash(hash, context) { - super.updateHash(hash, context); - - hash.update(this.content); - hash.update(this.media || ''); - hash.update(this.sourceMap ? JSON.stringify(this.sourceMap) : ''); - } - - serialize(context) { - const { write } = context; - - write(this._context); - write(this._identifier); - write(this._identifierIndex); - write(this.content); - write(this.media); - write(this.sourceMap); - write(this.buildInfo); - - super.serialize(context); - } - - deserialize(context) { - super.deserialize(context); - } -} - -if (webpack.util && webpack.util.serialization) { - webpack.util.serialization.register( - CssModule, - 'mini-css-extract-plugin/dist/CssModule', - null, - { - serialize(instance, context) { - instance.serialize(context); - }, - deserialize(context) { - const { read } = context; - - const contextModule = read(); - const identifier = read(); - const identifierIndex = read(); - const content = read(); - const media = read(); - const sourceMap = read(); - const { assets, assetsInfo } = read(); - - const dep = new CssModule({ - context: contextModule, - identifier, - identifierIndex, - content, - media, - sourceMap, - assets, - assetsInfo, - }); - - dep.deserialize(context); - - return dep; - }, - } - ); -} - -export default CssModule; diff --git a/src/CssModuleFactory.js b/src/CssModuleFactory.js deleted file mode 100644 index 69bf2b9f..00000000 --- a/src/CssModuleFactory.js +++ /dev/null @@ -1,8 +0,0 @@ -import CssModule from './CssModule'; - -export default class CssModuleFactory { - // eslint-disable-next-line class-methods-use-this - create({ dependencies: [dependency] }, callback) { - callback(null, new CssModule(dependency)); - } -} diff --git a/src/index.js b/src/index.js index 1261c9ba..a30914fb 100644 --- a/src/index.js +++ b/src/index.js @@ -1,24 +1,9 @@ /* eslint-disable class-methods-use-this */ -import webpack from 'webpack'; - import { validate } from 'schema-utils'; -import CssModuleFactory from './CssModuleFactory'; -import CssDependencyTemplate from './CssDependencyTemplate'; -import CssDependency from './CssDependency'; import schema from './plugin-options.json'; -import { MODULE_TYPE, compareModulesByIdentifier } from './utils'; - -// webpack 5 exposes the sources property to ensure the right version of webpack-sources is used -const { ConcatSource, SourceMapSource, RawSource } = - // eslint-disable-next-line global-require - webpack.sources || require('webpack-sources'); - -const { - Template, - util: { createHash }, -} = webpack; +import { shared, MODULE_TYPE, compareModulesByIdentifier } from './utils'; const pluginName = 'mini-css-extract-plugin'; @@ -27,69 +12,289 @@ const REGEXP_CONTENTHASH = /\[contenthash(?::(\d+))?\]/i; const REGEXP_NAME = /\[name\]/i; const DEFAULT_FILENAME = '[name].css'; -if (webpack.util.serialization && webpack.util.serialization.registerLoader) { - const pathLength = `${pluginName}/dist`.length; +const TYPES = new Set([MODULE_TYPE]); +const CODE_GENERATION_RESULT = { + sources: new Map(), + runtimeRequirements: new Set(), +}; + +class MiniCssExtractPlugin { + static getCssModule(webpack) { + class CssModule extends webpack.Module { + constructor({ + context, + identifier, + identifierIndex, + content, + media, + sourceMap, + assets, + assetsInfo, + }) { + super(MODULE_TYPE, context); + + this.id = ''; + this._context = context; + this._identifier = identifier; + this._identifierIndex = identifierIndex; + this.content = content; + this.media = media; + this.sourceMap = sourceMap; + this.buildInfo = { + assets, + assetsInfo, + }; + this.buildMeta = {}; + } + + // no source() so webpack 4 doesn't do add stuff to the bundle + + size() { + return this.content.length; + } + + identifier() { + return `css|${this._identifier}|${this._identifierIndex}`; + } + + readableIdentifier(requestShortener) { + return `css ${requestShortener.shorten(this._identifier)}${ + this._identifierIndex ? ` (${this._identifierIndex})` : '' + }`; + } + + // eslint-disable-next-line class-methods-use-this + getSourceTypes() { + return TYPES; + } + + // eslint-disable-next-line class-methods-use-this + codeGeneration() { + return CODE_GENERATION_RESULT; + } + + nameForCondition() { + const resource = this._identifier.split('!').pop(); + const idx = resource.indexOf('?'); + + if (idx >= 0) { + return resource.substring(0, idx); + } + + return resource; + } + + updateCacheModule(module) { + this.content = module.content; + this.media = module.media; + this.sourceMap = module.sourceMap; + } + + // eslint-disable-next-line class-methods-use-this + needRebuild() { + return true; + } + + // eslint-disable-next-line class-methods-use-this + needBuild(context, callback) { + callback(null, false); + } + + build(options, compilation, resolver, fileSystem, callback) { + this.buildInfo = {}; + this.buildMeta = {}; + + callback(); + } + + updateHash(hash, context) { + super.updateHash(hash, context); + + hash.update(this.content); + hash.update(this.media || ''); + hash.update(this.sourceMap ? JSON.stringify(this.sourceMap) : ''); + } + + serialize(context) { + const { write } = context; + + write(this._context); + write(this._identifier); + write(this._identifierIndex); + write(this.content); + write(this.media); + write(this.sourceMap); + write(this.buildInfo); - webpack.util.serialization.registerLoader( - /^mini-css-extract-plugin\//, - (request) => { - // eslint-disable-next-line global-require, import/no-dynamic-require - require(`.${request.slice(pathLength)}`); + super.serialize(context); + } - return true; + deserialize(context) { + super.deserialize(context); + } } - ); -} -class MiniCssExtractPlugin { + if ( + webpack.util && + webpack.util.serialization && + webpack.util.serialization.register + ) { + webpack.util.serialization.register( + CssModule, + 'mini-css-extract-plugin/dist/CssModule', + null, + { + serialize(instance, context) { + instance.serialize(context); + }, + deserialize(context) { + const { read } = context; + + const contextModule = read(); + const identifier = read(); + const identifierIndex = read(); + const content = read(); + const media = read(); + const sourceMap = read(); + const { assets, assetsInfo } = read(); + + const dep = new CssModule({ + context: contextModule, + identifier, + identifierIndex, + content, + media, + sourceMap, + assets, + assetsInfo, + }); + + dep.deserialize(context); + + return dep; + }, + } + ); + } + + return CssModule; + } + + static getCssDependency(webpack) { + // eslint-disable-next-line no-shadow + class CssDependency extends webpack.Dependency { + constructor( + { identifier, content, media, sourceMap }, + context, + identifierIndex + ) { + super(); + + this.identifier = identifier; + this.identifierIndex = identifierIndex; + this.content = content; + this.media = media; + this.sourceMap = sourceMap; + this.context = context; + // eslint-disable-next-line no-undefined + this.assets = undefined; + // eslint-disable-next-line no-undefined + this.assetsInfo = undefined; + } + + getResourceIdentifier() { + return `css-module-${this.identifier}-${this.identifierIndex}`; + } + + // eslint-disable-next-line class-methods-use-this + getModuleEvaluationSideEffectsState() { + return webpack.ModuleGraphConnection.TRANSITIVE_ONLY; + } + + serialize(context) { + const { write } = context; + + write(this.identifier); + write(this.content); + write(this.media); + write(this.sourceMap); + write(this.context); + write(this.identifierIndex); + write(this.assets); + write(this.assetsInfo); + + super.serialize(context); + } + + deserialize(context) { + super.deserialize(context); + } + } + + if ( + webpack.util && + webpack.util.serialization && + webpack.util.serialization.register + ) { + webpack.util.serialization.register( + CssDependency, + 'mini-css-extract-plugin/dist/CssDependency', + null, + { + serialize(instance, context) { + instance.serialize(context); + }, + deserialize(context) { + const { read } = context; + const dep = new CssDependency( + { + identifier: read(), + content: read(), + media: read(), + sourceMap: read(), + }, + read(), + read() + ); + + const assets = read(); + const assetsInfo = read(); + + dep.assets = assets; + dep.assetsInfo = assetsInfo; + + dep.deserialize(context); + + return dep; + }, + } + ); + } + + return CssDependency; + } + constructor(options = {}) { validate(schema, options, { name: 'Mini CSS Extract Plugin', baseDataPath: 'options', }); - const insert = - typeof options.insert !== 'undefined' - ? typeof options.insert === 'function' - ? `(${options.insert.toString()})(linkTag)` - : Template.asString([ - `var target = document.querySelector("${options.insert}");`, - `target.parentNode.insertBefore(linkTag, target.nextSibling);`, - ]) - : Template.asString(['document.head.appendChild(linkTag);']); - - const attributes = - typeof options.attributes === 'object' ? options.attributes : {}; - - // Todo in next major release set default to "false" - const linkType = - options.linkType === true || typeof options.linkType === 'undefined' - ? 'text/css' - : options.linkType; - this.options = Object.assign( - { - filename: DEFAULT_FILENAME, - ignoreOrder: false, - }, + { filename: DEFAULT_FILENAME, ignoreOrder: false }, options ); this.runtimeOptions = { - insert, - linkType, + insert: options.insert, + linkType: + // Todo in next major release set default to "false" + options.linkType === true || typeof options.linkType === 'undefined' + ? 'text/css' + : options.linkType, + attributes: options.attributes, }; - this.runtimeOptions.attributes = Template.asString( - Object.entries(attributes).map((entry) => { - const [key, value] = entry; - - return `linkTag.setAttribute(${JSON.stringify(key)}, ${JSON.stringify( - value - )});`; - }) - ); - if (!this.options.chunkFilename) { const { filename } = this.options; @@ -117,24 +322,67 @@ class MiniCssExtractPlugin { /** @param {import("webpack").Compiler} compiler */ apply(compiler) { + const webpack = compiler.webpack + ? compiler.webpack + : // eslint-disable-next-line global-require + require('webpack'); + + // TODO bug in webpack, remove it after it will be fixed + // webpack tries to `require` loader firstly when serializer doesn't found + if ( + webpack.util && + webpack.util.serialization && + webpack.util.serialization.registerLoader + ) { + webpack.util.serialization.registerLoader( + /^mini-css-extract-plugin\//, + () => true + ); + } + const isWebpack4 = compiler.webpack ? false : typeof compiler.resolvers !== 'undefined'; if (!isWebpack4) { const { splitChunks } = compiler.options.optimization; + if (splitChunks) { if (splitChunks.defaultSizeTypes.includes('...')) { splitChunks.defaultSizeTypes.push(MODULE_TYPE); } } } + + // initializeCssDependency + // eslint-disable-next-line no-shadow + const { CssModule, CssDependency } = shared(webpack, (webpack) => { + // eslint-disable-next-line no-shadow + const CssModule = MiniCssExtractPlugin.getCssModule(webpack); + // eslint-disable-next-line no-shadow + const CssDependency = MiniCssExtractPlugin.getCssDependency(webpack); + + return { CssModule, CssDependency }; + }); + compiler.hooks.thisCompilation.tap(pluginName, (compilation) => { + class CssModuleFactory { + // eslint-disable-next-line class-methods-use-this + create({ dependencies: [dependency] }, callback) { + callback(null, new CssModule(dependency)); + } + } + compilation.dependencyFactories.set( CssDependency, new CssModuleFactory() ); + class CssDependencyTemplate { + // eslint-disable-next-line class-methods-use-this + apply() {} + } + compilation.dependencyTemplates.set( CssDependency, new CssDependencyTemplate() @@ -157,6 +405,7 @@ class MiniCssExtractPlugin { result.push({ render: () => this.renderContentAsset( + compiler, compilation, chunk, renderedModules, @@ -190,6 +439,7 @@ class MiniCssExtractPlugin { result.push({ render: () => this.renderContentAsset( + compiler, compilation, chunk, renderedModules, @@ -211,10 +461,11 @@ class MiniCssExtractPlugin { pluginName, (result, { chunk }) => { const { chunkGraph } = compilation; + const { HotUpdateChunk } = webpack; // We don't need hot update chunks for css // We will use the real asset instead to update - if (chunk instanceof webpack.HotUpdateChunk) { + if (chunk instanceof HotUpdateChunk) { return; } @@ -230,6 +481,7 @@ class MiniCssExtractPlugin { result.push({ render: () => this.renderContentAsset( + compiler, compilation, chunk, renderedModules, @@ -287,6 +539,9 @@ class MiniCssExtractPlugin { if (modules) { const { hashFunction, hashDigest, hashDigestLength } = outputOptions; + const createHash = compiler.webpack + ? compiler.webpack.util.createHash + : webpack.util.createHash; const hash = createHash(hashFunction); for (const m of modules) { @@ -300,6 +555,7 @@ class MiniCssExtractPlugin { } }); + const { Template } = webpack; const { mainTemplate } = compilation; if (isWebpack4) { @@ -417,7 +673,19 @@ class MiniCssExtractPlugin { ]), '}', 'var linkTag = document.createElement("link");', - this.runtimeOptions.attributes, + this.runtimeOptions.attributes + ? Template.asString( + Object.entries(this.runtimeOptions.attributes).map( + (entry) => { + const [key, value] = entry; + + return `linkTag.setAttribute(${JSON.stringify( + key + )}, ${JSON.stringify(value)});`; + } + ) + ) + : '', 'linkTag.rel = "stylesheet";', this.runtimeOptions.linkType ? `linkTag.type = ${JSON.stringify( @@ -458,7 +726,16 @@ class MiniCssExtractPlugin { '}', ]) : '', - this.runtimeOptions.insert, + typeof this.runtimeOptions.insert !== 'undefined' + ? typeof this.runtimeOptions.insert === 'function' + ? `(${this.runtimeOptions.insert.toString()})(linkTag)` + : Template.asString([ + `var target = document.querySelector("${this.runtimeOptions.insert}");`, + `target.parentNode.insertBefore(linkTag, target.nextSibling);`, + ]) + : Template.asString([ + 'document.head.appendChild(linkTag);', + ]), ]), '}).then(function() {', Template.indent(['installedCssChunks[chunkId] = 0;']), @@ -472,7 +749,257 @@ class MiniCssExtractPlugin { } ); } else { + const { RuntimeGlobals, runtime } = webpack; + + // eslint-disable-next-line no-shadow + const getCssChunkObject = (mainChunk, compilation) => { + const obj = {}; + const { chunkGraph } = compilation; + + for (const chunk of mainChunk.getAllAsyncChunks()) { + const modules = chunkGraph.getOrderedChunkModulesIterable( + chunk, + compareModulesByIdentifier + ); + for (const module of modules) { + if (module.type === MODULE_TYPE) { + obj[chunk.id] = 1; + break; + } + } + } + + return obj; + }; + + const { RuntimeModule } = webpack; + + class CssLoadingRuntimeModule extends RuntimeModule { + constructor(runtimeRequirements, runtimeOptions) { + super('css loading', 10); + + this.runtimeRequirements = runtimeRequirements; + this.runtimeOptions = runtimeOptions; + } + + generate() { + const { chunk, runtimeRequirements } = this; + const { + runtimeTemplate, + outputOptions: { crossOriginLoading }, + } = this.compilation; + const chunkMap = getCssChunkObject(chunk, this.compilation); + + const withLoading = + runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers) && + Object.keys(chunkMap).length > 0; + const withHmr = runtimeRequirements.has( + RuntimeGlobals.hmrDownloadUpdateHandlers + ); + + if (!withLoading && !withHmr) { + return null; + } + + return Template.asString([ + `var createStylesheet = ${runtimeTemplate.basicFunction( + 'chunkId, fullhref, resolve, reject', + [ + 'var linkTag = document.createElement("link");', + this.runtimeOptions.attributes + ? Template.asString( + Object.entries(this.runtimeOptions.attributes).map( + (entry) => { + const [key, value] = entry; + + return `linkTag.setAttribute(${JSON.stringify( + key + )}, ${JSON.stringify(value)});`; + } + ) + ) + : '', + 'linkTag.rel = "stylesheet";', + this.runtimeOptions.linkType + ? `linkTag.type = ${JSON.stringify( + this.runtimeOptions.linkType + )};` + : '', + `var onLinkComplete = ${runtimeTemplate.basicFunction( + 'event', + [ + '// avoid mem leaks.', + 'linkTag.onerror = linkTag.onload = null;', + "if (event.type === 'load') {", + Template.indent(['resolve();']), + '} else {', + Template.indent([ + "var errorType = event && (event.type === 'load' ? 'missing' : event.type);", + 'var realHref = event && event.target && event.target.href || fullhref;', + 'var err = new Error("Loading CSS chunk " + chunkId + " failed.\\n(" + realHref + ")");', + 'err.code = "CSS_CHUNK_LOAD_FAILED";', + 'err.type = errorType;', + 'err.request = realHref;', + 'linkTag.parentNode.removeChild(linkTag)', + 'reject(err);', + ]), + '}', + ] + )}`, + 'linkTag.onerror = linkTag.onload = onLinkComplete;', + 'linkTag.href = fullhref;', + crossOriginLoading + ? Template.asString([ + `if (linkTag.href.indexOf(window.location.origin + '/') !== 0) {`, + Template.indent( + `linkTag.crossOrigin = ${JSON.stringify( + crossOriginLoading + )};` + ), + '}', + ]) + : '', + typeof this.runtimeOptions.insert !== 'undefined' + ? typeof this.runtimeOptions.insert === 'function' + ? `(${this.runtimeOptions.insert.toString()})(linkTag)` + : Template.asString([ + `var target = document.querySelector("${this.runtimeOptions.insert}");`, + `target.parentNode.insertBefore(linkTag, target.nextSibling);`, + ]) + : Template.asString([ + 'document.head.appendChild(linkTag);', + ]), + 'return linkTag;', + ] + )};`, + `var findStylesheet = ${runtimeTemplate.basicFunction( + 'href, fullhref', + [ + 'var existingLinkTags = document.getElementsByTagName("link");', + 'for(var i = 0; i < existingLinkTags.length; i++) {', + Template.indent([ + 'var tag = existingLinkTags[i];', + 'var dataHref = tag.getAttribute("data-href") || tag.getAttribute("href");', + 'if(tag.rel === "stylesheet" && (dataHref === href || dataHref === fullhref)) return tag;', + ]), + '}', + 'var existingStyleTags = document.getElementsByTagName("style");', + 'for(var i = 0; i < existingStyleTags.length; i++) {', + Template.indent([ + 'var tag = existingStyleTags[i];', + 'var dataHref = tag.getAttribute("data-href");', + 'if(dataHref === href || dataHref === fullhref) return tag;', + ]), + '}', + ] + )};`, + `var loadStylesheet = ${runtimeTemplate.basicFunction( + 'chunkId', + `return new Promise(${runtimeTemplate.basicFunction( + 'resolve, reject', + [ + `var href = ${RuntimeGlobals.require}.miniCssF(chunkId);`, + `var fullhref = ${RuntimeGlobals.publicPath} + href;`, + 'if(findStylesheet(href, fullhref)) return resolve();', + 'createStylesheet(chunkId, fullhref, resolve, reject);', + ] + )});` + )}`, + withLoading + ? Template.asString([ + '// object to store loaded CSS chunks', + 'var installedCssChunks = {', + Template.indent( + chunk.ids + .map((id) => `${JSON.stringify(id)}: 0`) + .join(',\n') + ), + '};', + '', + `${ + RuntimeGlobals.ensureChunkHandlers + }.miniCss = ${runtimeTemplate.basicFunction( + 'chunkId, promises', + [ + `var cssChunks = ${JSON.stringify(chunkMap)};`, + 'if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);', + 'else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {', + Template.indent([ + `promises.push(installedCssChunks[chunkId] = loadStylesheet(chunkId).then(${runtimeTemplate.basicFunction( + '', + 'installedCssChunks[chunkId] = 0;' + )}, ${runtimeTemplate.basicFunction('e', [ + 'delete installedCssChunks[chunkId];', + 'throw e;', + ])}));`, + ]), + '}', + ] + )};`, + ]) + : '// no chunk loading', + '', + withHmr + ? Template.asString([ + 'var oldTags = [];', + 'var newTags = [];', + `var applyHandler = ${runtimeTemplate.basicFunction( + 'options', + [ + `return { dispose: ${runtimeTemplate.basicFunction('', [ + 'for(var i = 0; i < oldTags.length; i++) {', + Template.indent([ + 'var oldTag = oldTags[i];', + 'if(oldTag.parentNode) oldTag.parentNode.removeChild(oldTag);', + ]), + '}', + 'oldTags.length = 0;', + ])}, apply: ${runtimeTemplate.basicFunction('', [ + 'for(var i = 0; i < newTags.length; i++) newTags[i].rel = "stylesheet";', + 'newTags.length = 0;', + ])} };`, + ] + )}`, + `${ + RuntimeGlobals.hmrDownloadUpdateHandlers + }.miniCss = ${runtimeTemplate.basicFunction( + 'chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList', + [ + 'applyHandlers.push(applyHandler);', + `chunkIds.forEach(${runtimeTemplate.basicFunction( + 'chunkId', + [ + `var href = ${RuntimeGlobals.require}.miniCssF(chunkId);`, + `var fullhref = ${RuntimeGlobals.publicPath} + href;`, + 'const oldTag = findStylesheet(href, fullhref);', + 'if(!oldTag) return;', + `promises.push(new Promise(${runtimeTemplate.basicFunction( + 'resolve, reject', + [ + `var tag = createStylesheet(chunkId, fullhref, ${runtimeTemplate.basicFunction( + '', + [ + 'tag.as = "style";', + 'tag.rel = "preload";', + 'resolve();', + ] + )}, reject);`, + 'oldTags.push(oldTag);', + 'newTags.push(tag);', + ] + )}));`, + ] + )});`, + ] + )}`, + ]) + : '// no hmr', + ]); + } + } + const enabledChunks = new WeakSet(); + const handler = (chunk, set) => { if (enabledChunks.has(chunk)) { return; @@ -484,17 +1011,17 @@ class MiniCssExtractPlugin { typeof this.options.chunkFilename === 'string' && /\[(full)?hash(:\d+)?\]/.test(this.options.chunkFilename) ) { - set.add(webpack.RuntimeGlobals.getFullHash); + set.add(RuntimeGlobals.getFullHash); } - set.add(webpack.RuntimeGlobals.publicPath); + set.add(RuntimeGlobals.publicPath); compilation.addRuntimeModule( chunk, - new webpack.runtime.GetChunkFilenameRuntimeModule( + new runtime.GetChunkFilenameRuntimeModule( MODULE_TYPE, 'mini-css', - `${webpack.RuntimeGlobals.require}.miniCssF`, + `${RuntimeGlobals.require}.miniCssF`, (referencedChunk) => { if (!referencedChunk.contentHash[MODULE_TYPE]) { return false; @@ -508,9 +1035,6 @@ class MiniCssExtractPlugin { ) ); - // eslint-disable-next-line global-require - const CssLoadingRuntimeModule = require('./CssLoadingRuntimeModule'); - compilation.addRuntimeModule( chunk, new CssLoadingRuntimeModule(set, this.runtimeOptions) @@ -518,10 +1042,10 @@ class MiniCssExtractPlugin { }; compilation.hooks.runtimeRequirementInTree - .for(webpack.RuntimeGlobals.ensureChunkHandlers) + .for(RuntimeGlobals.ensureChunkHandlers) .tap(pluginName, handler); compilation.hooks.runtimeRequirementInTree - .for(webpack.RuntimeGlobals.hmrDownloadUpdateHandlers) + .for(RuntimeGlobals.hmrDownloadUpdateHandlers) .tap(pluginName, handler); } }); @@ -552,7 +1076,7 @@ class MiniCssExtractPlugin { return obj; } - renderContentAsset(compilation, chunk, modules, requestShortener) { + renderContentAsset(compiler, compilation, chunk, modules, requestShortener) { let usedModules; const [chunkGroup] = chunk.groupsIterable; @@ -691,6 +1215,12 @@ class MiniCssExtractPlugin { usedModules = modules; } + // TODO remove after drop webpack v4 + const { ConcatSource, SourceMapSource, RawSource } = compiler.webpack + ? compiler.webpack.sources + : // eslint-disable-next-line global-require + require('webpack-sources'); + const source = new ConcatSource(); const externalsSource = new ConcatSource(); diff --git a/src/loader.js b/src/loader.js index c7370666..450790c9 100644 --- a/src/loader.js +++ b/src/loader.js @@ -1,16 +1,9 @@ import path from 'path'; import loaderUtils from 'loader-utils'; -import NodeTemplatePlugin from 'webpack/lib/node/NodeTemplatePlugin'; -import NodeTargetPlugin from 'webpack/lib/node/NodeTargetPlugin'; -import LibraryTemplatePlugin from 'webpack/lib/LibraryTemplatePlugin'; -import SingleEntryPlugin from 'webpack/lib/SingleEntryPlugin'; -import LimitChunkCountPlugin from 'webpack/lib/optimize/LimitChunkCountPlugin'; -import NormalModule from 'webpack/lib/NormalModule'; import { validate } from 'schema-utils'; -import CssDependency from './CssDependency'; -import { findModuleById, evalModuleCode } from './utils'; +import { shared, findModuleById, evalModuleCode } from './utils'; import schema from './loader-options.json'; const pluginName = 'mini-css-extract-plugin'; @@ -66,14 +59,54 @@ export function pitch(request) { outputOptions ); + // TODO simplify after drop webpack v4 + // eslint-disable-next-line global-require + const webpack = this._compiler.webpack || require('webpack'); + + const { NodeTemplatePlugin } = webpack.node; + const NodeTargetPlugin = webpack.node.NodeTargetPlugin + ? webpack.node.NodeTargetPlugin + : // eslint-disable-next-line global-require + require('webpack/lib/node/NodeTargetPlugin'); + new NodeTemplatePlugin(outputOptions).apply(childCompiler); - new LibraryTemplatePlugin(null, 'commonjs2').apply(childCompiler); new NodeTargetPlugin().apply(childCompiler); - new SingleEntryPlugin(this.context, `!!${request}`, pluginName).apply( - childCompiler - ); + + const { EntryOptionPlugin } = webpack; + + if (EntryOptionPlugin) { + const { + library: { EnableLibraryPlugin }, + } = webpack; + + new EnableLibraryPlugin('commonjs2').apply(childCompiler); + + EntryOptionPlugin.applyEntryOption(childCompiler, this.context, { + child: { + library: { + type: 'commonjs2', + }, + import: [`!!${request}`], + }, + }); + } else { + const { LibraryTemplatePlugin, SingleEntryPlugin } = webpack; + + new LibraryTemplatePlugin(null, 'commonjs2').apply(childCompiler); + new SingleEntryPlugin(this.context, `!!${request}`, pluginName).apply( + childCompiler + ); + } + + const { LimitChunkCountPlugin } = webpack.optimize; + new LimitChunkCountPlugin({ maxChunks: 1 }).apply(childCompiler); + const NormalModule = webpack.NormalModule + ? webpack.NormalModule + : // eslint-disable-next-line global-require + require('webpack/lib/NormalModule'); + childCompiler.hooks.thisCompilation.tap( `${pluginName} loader`, (compilation) => { @@ -123,6 +156,8 @@ export function pitch(request) { compilation.assets[childFilename] && compilation.assets[childFilename].source(); + // console.log(source); + // Remove all chunk assets compilation.chunks.forEach((chunk) => { chunk.files.forEach((file) => { @@ -135,7 +170,7 @@ export function pitch(request) { const callback = this.async(); - childCompiler.runAsChild((err, entries, compilation) => { + childCompiler.runAsChild((error, entries, compilation) => { const assets = Object.create(null); const assetsInfo = new Map(); @@ -164,6 +199,15 @@ export function pitch(request) { } const count = identifierCountMap.get(dependency.identifier) || 0; + const { CssDependency } = shared(webpack, () => { + return {}; + }); + + if (!CssDependency) { + throw new Error( + "You forgot to add 'mini-css-extract-plugin' plugin (i.e. `{ plugins: [new MiniCssExtractPlugin()] }`), please read https://github.com/webpack-contrib/mini-css-extract-plugin#getting-started" + ); + } this._module.addDependency( (lastDep = new CssDependency(dependency, dependency.context, count)) @@ -177,8 +221,8 @@ export function pitch(request) { } }; - if (err) { - return callback(err); + if (error) { + return callback(error); } if (compilation.errors.length > 0) { diff --git a/src/utils.js b/src/utils.js index 772cd22d..98e5140e 100644 --- a/src/utils.js +++ b/src/utils.js @@ -49,7 +49,26 @@ function compareModulesByIdentifier(a, b) { return compareIds(a.identifier(), b.identifier()); } +const initializeCache = new WeakMap(); + +function shared(webpack, initializer) { + const cacheEntry = initializeCache.get(webpack); + + // eslint-disable-next-line no-undefined + if (cacheEntry !== undefined) { + return cacheEntry; + } + + const constructors = initializer(webpack); + const result = { ...constructors }; + + initializeCache.set(webpack, result); + + return result; +} + export { + shared, MODULE_TYPE, findModuleById, evalModuleCode, diff --git a/test/TestCache.test.js b/test/TestCache.test.js index f9d3e4b6..d488b5e0 100644 --- a/test/TestCache.test.js +++ b/test/TestCache.test.js @@ -43,33 +43,29 @@ describe('TestCache', () => { return; } - expect( - Object.keys(stats.compilation.assets).sort() - ).toMatchInlineSnapshot( - ` + expect(Object.keys(stats.compilation.assets).sort()) + .toMatchInlineSnapshot(` Array [ "main.css", "main.js", "static/react.svg", ] - ` - ); - expect( - Array.from(stats.compilation.emittedAssets).sort() - ).toMatchInlineSnapshot( - ` + `); + expect(Array.from(stats.compilation.emittedAssets).sort()) + .toMatchInlineSnapshot(` Array [ "main.css", "main.js", "static/react.svg", ] - ` - ); + `); expect(stats.compilation.warnings).toHaveLength(0); expect(stats.compilation.errors).toHaveLength(0); compiler1.close(() => { - resolve(); + process.nextTick(() => { + resolve(); + }); }); }); }); @@ -92,17 +88,14 @@ describe('TestCache', () => { return; } - expect( - Object.keys(stats.compilation.assets).sort() - ).toMatchInlineSnapshot( - ` + expect(Object.keys(stats.compilation.assets).sort()) + .toMatchInlineSnapshot(` Array [ "main.css", "main.js", "static/react.svg", ] - ` - ); + `); expect( Array.from(stats.compilation.emittedAssets).sort() ).toMatchInlineSnapshot(`Array []`); @@ -110,7 +103,9 @@ describe('TestCache', () => { expect(stats.compilation.errors).toHaveLength(0); compiler2.close(() => { - resolve(); + process.nextTick(() => { + resolve(); + }); }); }); }); @@ -152,28 +147,22 @@ describe('TestCache', () => { return; } - expect( - Object.keys(stats.compilation.assets).sort() - ).toMatchInlineSnapshot( - ` + expect(Object.keys(stats.compilation.assets).sort()) + .toMatchInlineSnapshot(` Array [ "main.css", "main.js", "static/react.svg", ] - ` - ); - expect( - Array.from(stats.compilation.emittedAssets).sort() - ).toMatchInlineSnapshot( - ` + `); + expect(Array.from(stats.compilation.emittedAssets).sort()) + .toMatchInlineSnapshot(` Array [ "main.css", "main.js", "static/react.svg", ] - ` - ); + `); expect(stats.compilation.warnings).toHaveLength(0); expect(stats.compilation.errors).toHaveLength(0); @@ -203,17 +192,14 @@ describe('TestCache', () => { return; } - expect( - Object.keys(stats.compilation.assets).sort() - ).toMatchInlineSnapshot( - ` + expect(Object.keys(stats.compilation.assets).sort()) + .toMatchInlineSnapshot(` Array [ "main.css", "main.js", "static/react.svg", ] - ` - ); + `); expect( Array.from(stats.compilation.emittedAssets).sort() ).toMatchInlineSnapshot(`Array []`); @@ -270,16 +256,13 @@ describe('TestCache', () => { return; } - expect( - Object.keys(stats.compilation.assets).sort() - ).toMatchInlineSnapshot( - ` + expect(Object.keys(stats.compilation.assets).sort()) + .toMatchInlineSnapshot(` Array [ "main.css", "main.js", ] - ` - ); + `); expect(Array.from(stats.compilation.emittedAssets).sort()) .toMatchInlineSnapshot(` Array [ @@ -319,16 +302,13 @@ describe('TestCache', () => { return; } - expect( - Object.keys(stats.compilation.assets).sort() - ).toMatchInlineSnapshot( - ` + expect(Object.keys(stats.compilation.assets).sort()) + .toMatchInlineSnapshot(` Array [ "main.css", "main.js", ] - ` - ); + `); expect( Array.from(stats.compilation.emittedAssets).sort() ).toMatchInlineSnapshot(`Array []`); @@ -385,28 +365,22 @@ describe('TestCache', () => { return; } - expect( - Object.keys(stats.compilation.assets).sort() - ).toMatchInlineSnapshot( - ` + expect(Object.keys(stats.compilation.assets).sort()) + .toMatchInlineSnapshot(` Array [ "main.css", "main.js", "static/react.svg", ] - ` - ); - expect( - Array.from(stats.compilation.emittedAssets).sort() - ).toMatchInlineSnapshot( - ` + `); + expect(Array.from(stats.compilation.emittedAssets).sort()) + .toMatchInlineSnapshot(` Array [ "main.css", "main.js", "static/react.svg", ] - ` - ); + `); expect(stats.compilation.warnings).toHaveLength(0); expect(stats.compilation.errors).toHaveLength(0); @@ -439,17 +413,14 @@ describe('TestCache', () => { return; } - expect( - Object.keys(stats.compilation.assets).sort() - ).toMatchInlineSnapshot( - ` + expect(Object.keys(stats.compilation.assets).sort()) + .toMatchInlineSnapshot(` Array [ "main.css", "main.js", "static/react.svg", ] - ` - ); + `); expect( Array.from(stats.compilation.emittedAssets).sort() ).toMatchInlineSnapshot(`Array []`); @@ -506,28 +477,22 @@ describe('TestCache', () => { return; } - expect( - Object.keys(stats.compilation.assets).sort() - ).toMatchInlineSnapshot( - ` + expect(Object.keys(stats.compilation.assets).sort()) + .toMatchInlineSnapshot(` Array [ "main.css", "main.js", "static/react.svg", ] - ` - ); - expect( - Array.from(stats.compilation.emittedAssets).sort() - ).toMatchInlineSnapshot( - ` + `); + expect(Array.from(stats.compilation.emittedAssets).sort()) + .toMatchInlineSnapshot(` Array [ "main.css", "main.js", "static/react.svg", ] - ` - ); + `); expect(stats.compilation.warnings).toHaveLength(0); expect(stats.compilation.errors).toHaveLength(0); @@ -560,17 +525,14 @@ describe('TestCache', () => { return; } - expect( - Object.keys(stats.compilation.assets).sort() - ).toMatchInlineSnapshot( - ` + expect(Object.keys(stats.compilation.assets).sort()) + .toMatchInlineSnapshot(` Array [ "main.css", "main.js", "static/react.svg", ] - ` - ); + `); expect( Array.from(stats.compilation.emittedAssets).sort() ).toMatchInlineSnapshot(`Array []`); diff --git a/test/TestCases.test.js b/test/TestCases.test.js index d433ff73..541d3138 100644 --- a/test/TestCases.test.js +++ b/test/TestCases.test.js @@ -127,18 +127,42 @@ describe('TestCases', () => { ); } - webpack(webpackConfig, (err, stats) => { - if (err) { - done(err); + webpack(webpackConfig, (error, stats) => { + if (error) { + done(error); + return; } + if (stats.hasErrors()) { + const errorsPath = path.join(directoryForCase, './errors.test.js'); + + if (fs.existsSync(errorsPath)) { + const { errors } = stats.compilation; + // eslint-disable-next-line global-require, import/no-dynamic-require + const errorFilters = require(errorsPath); + const filteredErrors = errors.filter( + // eslint-disable-next-line no-shadow + (error) => + !errorFilters.some((errorFilter) => errorFilter.test(error)) + ); + + if (filteredErrors.length > 0) { + done(new Error(`Errors:\n${filteredErrors.join(',\n')}`)); + + return; + } + + done(); + + return; + } + done(new Error(stats.toString())); + return; } - done(); - if (stats.hasErrors() && stats.hasWarnings()) { done( new Error( diff --git a/test/cases/chunkFilename-fullhash/expected/webpack-5/0.ff87ec1bb4052c4f3445.css b/test/cases/chunkFilename-fullhash/expected/webpack-5/0.f4055680253d27bc029e.css similarity index 100% rename from test/cases/chunkFilename-fullhash/expected/webpack-5/0.ff87ec1bb4052c4f3445.css rename to test/cases/chunkFilename-fullhash/expected/webpack-5/0.f4055680253d27bc029e.css diff --git a/test/cases/chunkFilename-fullhash/expected/webpack-5/ff87ec1bb4052c4f3445.css b/test/cases/chunkFilename-fullhash/expected/webpack-5/f4055680253d27bc029e.css similarity index 100% rename from test/cases/chunkFilename-fullhash/expected/webpack-5/ff87ec1bb4052c4f3445.css rename to test/cases/chunkFilename-fullhash/expected/webpack-5/f4055680253d27bc029e.css diff --git a/test/cases/chunkFilename-fullhash/expected/webpack-5/main.js b/test/cases/chunkFilename-fullhash/expected/webpack-5/main.js index 8213bd24..bbcf2627 100644 --- a/test/cases/chunkFilename-fullhash/expected/webpack-5/main.js +++ b/test/cases/chunkFilename-fullhash/expected/webpack-5/main.js @@ -1,18 +1,7 @@ /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ -/* 0 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _style_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); - - -/* eslint-disable-next-line no-unused-expressions */ -__webpack_require__.e(/* import() | async */ 0).then(__webpack_require__.bind(__webpack_require__, 2)); - - -/***/ }), +/* 0 */, /* 1 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { @@ -83,7 +72,7 @@ __webpack_require__.r(__webpack_exports__); /******/ /******/ /* webpack/runtime/getFullHash */ /******/ (() => { -/******/ __webpack_require__.h = () => ("ff87ec1bb4052c4f3445") +/******/ __webpack_require__.h = () => ("f4055680253d27bc029e") /******/ })(); /******/ /******/ /* webpack/runtime/global */ @@ -349,9 +338,17 @@ __webpack_require__.r(__webpack_exports__); /******/ })(); /******/ /************************************************************************/ -/******/ // startup -/******/ // Load entry module -/******/ __webpack_require__(0); -/******/ // This entry module used 'exports' so it can't be inlined +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _style_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); + + +/* eslint-disable-next-line no-unused-expressions */ +__webpack_require__.e(/* import() | async */ 0).then(__webpack_require__.bind(__webpack_require__, 2)); + +})(); + /******/ })() ; \ No newline at end of file diff --git a/test/cases/dependOn-multiple-files-per-entry/expected/webpack-5/common.js b/test/cases/dependOn-multiple-files-per-entry/expected/webpack-5/common.js index 9a86a260..019baa31 100644 --- a/test/cases/dependOn-multiple-files-per-entry/expected/webpack-5/common.js +++ b/test/cases/dependOn-multiple-files-per-entry/expected/webpack-5/common.js @@ -174,7 +174,9 @@ __webpack_require__.r(__webpack_exports__); /******/ })(); /******/ /************************************************************************/ +/******/ /******/ // run startup -/******/ __webpack_require__.x(); +/******/ var __webpack_exports__ = __webpack_require__.x(); +/******/ /******/ })() ; \ No newline at end of file diff --git a/test/cases/dependOn/expected/webpack-5/common.js b/test/cases/dependOn/expected/webpack-5/common.js index 827b5b8c..750a9115 100644 --- a/test/cases/dependOn/expected/webpack-5/common.js +++ b/test/cases/dependOn/expected/webpack-5/common.js @@ -156,7 +156,9 @@ __webpack_require__.r(__webpack_exports__); /******/ })(); /******/ /************************************************************************/ +/******/ /******/ // run startup -/******/ __webpack_require__.x(); +/******/ var __webpack_exports__ = __webpack_require__.x(); +/******/ /******/ })() ; \ No newline at end of file diff --git a/test/cases/es-module-concatenation-modules/expected/webpack-5/main.js b/test/cases/es-module-concatenation-modules/expected/webpack-5/main.js index 4861f43e..4f1059be 100644 --- a/test/cases/es-module-concatenation-modules/expected/webpack-5/main.js +++ b/test/cases/es-module-concatenation-modules/expected/webpack-5/main.js @@ -1,9 +1,39 @@ /******/ (() => { // webpackBootstrap /******/ "use strict"; -/******/ var __webpack_modules__ = ([ -/* 0 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - +/******/ // The require scope +/******/ var __webpack_require__ = {}; +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); @@ -59,66 +89,5 @@ const c = "foo__c"; // eslint-disable-next-line no-console console.log(index_namespaceObject); - -/***/ }) -/******/ ]); -/************************************************************************/ -/******/ // The module cache -/******/ var __webpack_module_cache__ = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = __webpack_module_cache__[moduleId] = { -/******/ // no module.id needed -/******/ // no module.loaded needed -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/************************************************************************/ -/******/ /* webpack/runtime/define property getters */ -/******/ (() => { -/******/ // define getter functions for harmony exports -/******/ __webpack_require__.d = (exports, definition) => { -/******/ for(var key in definition) { -/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { -/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); -/******/ } -/******/ } -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/hasOwnProperty shorthand */ -/******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) -/******/ })(); -/******/ -/******/ /* webpack/runtime/make namespace object */ -/******/ (() => { -/******/ // define __esModule on exports -/******/ __webpack_require__.r = (exports) => { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ })(); -/******/ -/************************************************************************/ -/******/ // startup -/******/ // Load entry module -/******/ __webpack_require__(0); -/******/ // This entry module used 'exports' so it can't be inlined /******/ })() ; \ No newline at end of file diff --git a/test/cases/es-module-concatenation/expected/webpack-5/main.js b/test/cases/es-module-concatenation/expected/webpack-5/main.js index 8130cc45..394a6125 100644 --- a/test/cases/es-module-concatenation/expected/webpack-5/main.js +++ b/test/cases/es-module-concatenation/expected/webpack-5/main.js @@ -1,9 +1,22 @@ /******/ (() => { // webpackBootstrap /******/ "use strict"; -/******/ var __webpack_modules__ = ([ -/* 0 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - +/******/ // The require scope +/******/ var __webpack_require__ = {}; +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); @@ -21,49 +34,5 @@ __webpack_require__.r(__webpack_exports__); - -/***/ }) -/******/ ]); -/************************************************************************/ -/******/ // The module cache -/******/ var __webpack_module_cache__ = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = __webpack_module_cache__[moduleId] = { -/******/ // no module.id needed -/******/ // no module.loaded needed -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/************************************************************************/ -/******/ /* webpack/runtime/make namespace object */ -/******/ (() => { -/******/ // define __esModule on exports -/******/ __webpack_require__.r = (exports) => { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ })(); -/******/ -/************************************************************************/ -/******/ // startup -/******/ // Load entry module -/******/ __webpack_require__(0); -/******/ // This entry module used 'exports' so it can't be inlined /******/ })() ; \ No newline at end of file diff --git a/test/cases/es-named-export/expected/webpack-5/main.js b/test/cases/es-named-export/expected/webpack-5/main.js index ba7da461..263668f4 100644 --- a/test/cases/es-named-export/expected/webpack-5/main.js +++ b/test/cases/es-named-export/expected/webpack-5/main.js @@ -1,18 +1,7 @@ /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ -/* 0 */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _style_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); - - -// eslint-disable-next-line no-console -console.log({ css: _style_css__WEBPACK_IMPORTED_MODULE_0__.default, aClass: _style_css__WEBPACK_IMPORTED_MODULE_0__.aClass, bClass: _style_css__WEBPACK_IMPORTED_MODULE_0__.bClass, cClass: _style_css__WEBPACK_IMPORTED_MODULE_0__.cClass }); - - -/***/ }), +/* 0 */, /* 1 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { @@ -83,9 +72,17 @@ const cClass = "foo__style__cClass"; /******/ })(); /******/ /************************************************************************/ -/******/ // startup -/******/ // Load entry module -/******/ __webpack_require__(0); -/******/ // This entry module used 'exports' so it can't be inlined +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _style_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); + + +// eslint-disable-next-line no-console +console.log({ css: _style_css__WEBPACK_IMPORTED_MODULE_0__.default, aClass: _style_css__WEBPACK_IMPORTED_MODULE_0__.aClass, bClass: _style_css__WEBPACK_IMPORTED_MODULE_0__.bClass, cClass: _style_css__WEBPACK_IMPORTED_MODULE_0__.cClass }); + +})(); + /******/ })() ; \ No newline at end of file diff --git a/test/cases/hmr/expected/webpack-5/main.js b/test/cases/hmr/expected/webpack-5/main.js index 8c81628c..3e152eac 100644 --- a/test/cases/hmr/expected/webpack-5/main.js +++ b/test/cases/hmr/expected/webpack-5/main.js @@ -1402,9 +1402,11 @@ module.exports = function (urlString) { /******/ })(); /******/ /************************************************************************/ +/******/ /******/ // module cache are used so entry inlining is disabled /******/ // startup -/******/ // Load entry module -/******/ __webpack_require__(0); +/******/ // Load entry module and return exports +/******/ var __webpack_exports__ = __webpack_require__(0); +/******/ /******/ })() ; \ No newline at end of file diff --git a/test/cases/insert-function/expected/webpack-5/main.js b/test/cases/insert-function/expected/webpack-5/main.js index 93fb438c..c3a65f34 100644 --- a/test/cases/insert-function/expected/webpack-5/main.js +++ b/test/cases/insert-function/expected/webpack-5/main.js @@ -328,6 +328,7 @@ /******/ })(); /******/ /************************************************************************/ +var __webpack_exports__ = {}; /* eslint-env browser */ // eslint-disable-next-line diff --git a/test/cases/insert-string/expected/webpack-5/main.js b/test/cases/insert-string/expected/webpack-5/main.js index 85ac07ee..311cfdd8 100644 --- a/test/cases/insert-string/expected/webpack-5/main.js +++ b/test/cases/insert-string/expected/webpack-5/main.js @@ -323,6 +323,7 @@ /******/ })(); /******/ /************************************************************************/ +var __webpack_exports__ = {}; /* eslint-env browser */ // eslint-disable-next-line diff --git a/test/cases/insert-undefined/expected/webpack-5/main.js b/test/cases/insert-undefined/expected/webpack-5/main.js index a995fc12..cf865187 100644 --- a/test/cases/insert-undefined/expected/webpack-5/main.js +++ b/test/cases/insert-undefined/expected/webpack-5/main.js @@ -322,6 +322,7 @@ /******/ })(); /******/ /************************************************************************/ +var __webpack_exports__ = {}; /* eslint-env browser */ // eslint-disable-next-line diff --git a/test/cases/no-loader/index.js b/test/cases/no-loader/index.js new file mode 100644 index 00000000..aa3357bf --- /dev/null +++ b/test/cases/no-loader/index.js @@ -0,0 +1 @@ +import './style.css'; diff --git a/test/cases/no-loader/style.css b/test/cases/no-loader/style.css new file mode 100644 index 00000000..67ce83e4 --- /dev/null +++ b/test/cases/no-loader/style.css @@ -0,0 +1,3 @@ +body { + background: red; +} diff --git a/test/cases/no-loader/webpack.config.js b/test/cases/no-loader/webpack.config.js new file mode 100644 index 00000000..acadf575 --- /dev/null +++ b/test/cases/no-loader/webpack.config.js @@ -0,0 +1,18 @@ +import Self from '../../../src'; + +module.exports = { + entry: './index.js', + module: { + rules: [ + { + test: /\.css$/, + use: ['css-loader'], + }, + ], + }, + plugins: [ + new Self({ + filename: '[name].css', + }), + ], +}; diff --git a/test/cases/runtime/expected/webpack-5/runtime~main.js b/test/cases/runtime/expected/webpack-5/runtime~main.js index d267a9d5..6fc3c86a 100644 --- a/test/cases/runtime/expected/webpack-5/runtime~main.js +++ b/test/cases/runtime/expected/webpack-5/runtime~main.js @@ -328,7 +328,9 @@ /******/ })(); /******/ /************************************************************************/ +/******/ /******/ // run startup -/******/ __webpack_require__.x(); +/******/ var __webpack_exports__ = __webpack_require__.x(); +/******/ /******/ })() ; \ No newline at end of file