From 6f92568a72c69bf186984de1b77dccaf9c064c23 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Mon, 6 Sep 2021 16:59:54 +0300 Subject: [PATCH 1/4] test: multiple themes based on entries --- README.md | 128 ++++++++++++++++++ package-lock.json | 85 ++++++++++++ package.json | 2 + .../expected/dark-theme.css | 3 + .../expected/light-theme.css | 3 + .../public/index.html | 15 ++ .../src/dark-theme/_vars.scss | 1 + .../multi-theme-based-on-entries/src/index.js | 28 ++++ .../src/light-theme/_vars.scss | 1 + .../src/style.scss | 3 + .../webpack.config.js | 57 ++++++++ 11 files changed, 326 insertions(+) create mode 100644 test/cases/multi-theme-based-on-entries/expected/dark-theme.css create mode 100644 test/cases/multi-theme-based-on-entries/expected/light-theme.css create mode 100644 test/cases/multi-theme-based-on-entries/public/index.html create mode 100644 test/cases/multi-theme-based-on-entries/src/dark-theme/_vars.scss create mode 100644 test/cases/multi-theme-based-on-entries/src/index.js create mode 100644 test/cases/multi-theme-based-on-entries/src/light-theme/_vars.scss create mode 100644 test/cases/multi-theme-based-on-entries/src/style.scss create mode 100644 test/cases/multi-theme-based-on-entries/webpack.config.js diff --git a/README.md b/README.md index 1c0905b0..adca50eb 100644 --- a/README.md +++ b/README.md @@ -911,6 +911,134 @@ module.exports = { }; ``` +### Multiple Themes + +**webpack.config.js** + +```js +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); + +module.exports = { + entry: { + "light-theme": { + import: ["./src/index.js", "./src/style.scss"], + }, + "dark-theme": { + import: ["./src/index.js", "./src/style.scss?dark"], + }, + }, + // For better runtime code caching + optimization: { + runtimeChunk: { + name: "runtime", + }, + }, + module: { + rules: [ + { + test: /\.s[ac]ss$/i, + oneOf: [ + { + resourceQuery: "?dark", + use: [ + Self.loader, + "css-loader", + { + loader: "sass-loader", + options: { + additionalData: `@use 'dark-theme/vars' as vars;`, + }, + }, + ], + }, + { + use: [ + Self.loader, + "css-loader", + { + loader: "sass-loader", + options: { + additionalData: `@use 'light-theme/vars' as vars;`, + }, + }, + ], + }, + ], + }, + ], + }, + plugins: [ + new MiniCssExtractPlugin({ + filename: "[name].css", + }), + ], +}; +``` + +**src/index.js** + +```js +let theme = "light"; + +document.onclick = () => { + console.log("CHANGING THEME..."); + + if (theme === "light") { + theme = "dark"; + } else { + theme = "light"; + } + + const themeElement = document.querySelector("#theme"); + + if (themeElement) { + themeElement.remove(); + } + + const linkElement = document.createElement("link"); + + linkElement.type = "text/css"; + linkElement.rel = "stylesheet"; + linkElement.href = `${theme}-theme.css`; + + document.getElementsByTagName("head")[0].appendChild(linkElement); + + console.log("THEME WAS CHANGED"); +}; +``` + +**src/dark-theme/\_vars** + +```scss +$background: black; +``` + +**src/light-theme/\_vars** + +```scss +$background: white; +``` + +**public/index.html** + +```html + + + + + + + Multiple Themes + + + + + + + + +``` + ### Media Query Plugin If you'd like to extract the media queries from the extracted CSS (so mobile users don't need to load desktop or tablet specific CSS anymore) you should use one of the following plugins: diff --git a/package-lock.json b/package-lock.json index 25ab70db..6a8cb0cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,6 +36,8 @@ "memfs": "^3.0.2", "npm-run-all": "^4.1.5", "prettier": "^2.3.2", + "sass": "^1.39.0", + "sass-loader": "^12.1.0", "standard-version": "^9.3.0", "webpack": "^5.48.0", "webpack-cli": "^4.7.2", @@ -11633,6 +11635,15 @@ "node": ">=6" } }, + "node_modules/klona": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz", + "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -14776,6 +14787,55 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "node_modules/sass": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.39.0.tgz", + "integrity": "sha512-F4o+RhJkNOIG0b6QudYU8c78ZADKZjKDk5cyrf8XTKWfrgbtyVVXImFstJrc+1pkQDCggyidIOytq6gS4gCCZg==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/sass-loader": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.1.0.tgz", + "integrity": "sha512-FVJZ9kxVRYNZTIe2xhw93n3xJNYZADr+q69/s98l9nTCrWASo+DR2Ot0s5xTKQDDEosUkatsGeHxcH4QBp5bSg==", + "dev": true, + "dependencies": { + "klona": "^2.0.4", + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0", + "sass": "^1.3.0", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, "node_modules/saxes": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", @@ -26188,6 +26248,12 @@ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, + "klona": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz", + "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==", + "dev": true + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -28557,6 +28623,25 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "sass": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.39.0.tgz", + "integrity": "sha512-F4o+RhJkNOIG0b6QudYU8c78ZADKZjKDk5cyrf8XTKWfrgbtyVVXImFstJrc+1pkQDCggyidIOytq6gS4gCCZg==", + "dev": true, + "requires": { + "chokidar": ">=3.0.0 <4.0.0" + } + }, + "sass-loader": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.1.0.tgz", + "integrity": "sha512-FVJZ9kxVRYNZTIe2xhw93n3xJNYZADr+q69/s98l9nTCrWASo+DR2Ot0s5xTKQDDEosUkatsGeHxcH4QBp5bSg==", + "dev": true, + "requires": { + "klona": "^2.0.4", + "neo-async": "^2.6.2" + } + }, "saxes": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", diff --git a/package.json b/package.json index 947fc76a..a6715cb9 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,8 @@ "memfs": "^3.0.2", "npm-run-all": "^4.1.5", "prettier": "^2.3.2", + "sass": "^1.39.0", + "sass-loader": "^12.1.0", "standard-version": "^9.3.0", "webpack": "^5.48.0", "webpack-cli": "^4.7.2", diff --git a/test/cases/multi-theme-based-on-entries/expected/dark-theme.css b/test/cases/multi-theme-based-on-entries/expected/dark-theme.css new file mode 100644 index 00000000..c4d554e0 --- /dev/null +++ b/test/cases/multi-theme-based-on-entries/expected/dark-theme.css @@ -0,0 +1,3 @@ +body { + background-color: black; +} diff --git a/test/cases/multi-theme-based-on-entries/expected/light-theme.css b/test/cases/multi-theme-based-on-entries/expected/light-theme.css new file mode 100644 index 00000000..cdf802a3 --- /dev/null +++ b/test/cases/multi-theme-based-on-entries/expected/light-theme.css @@ -0,0 +1,3 @@ +body { + background-color: white; +} diff --git a/test/cases/multi-theme-based-on-entries/public/index.html b/test/cases/multi-theme-based-on-entries/public/index.html new file mode 100644 index 00000000..60bc9273 --- /dev/null +++ b/test/cases/multi-theme-based-on-entries/public/index.html @@ -0,0 +1,15 @@ + + + + + + + Document + + + + + + + \ No newline at end of file diff --git a/test/cases/multi-theme-based-on-entries/src/dark-theme/_vars.scss b/test/cases/multi-theme-based-on-entries/src/dark-theme/_vars.scss new file mode 100644 index 00000000..2abe50c6 --- /dev/null +++ b/test/cases/multi-theme-based-on-entries/src/dark-theme/_vars.scss @@ -0,0 +1 @@ +$background: black; diff --git a/test/cases/multi-theme-based-on-entries/src/index.js b/test/cases/multi-theme-based-on-entries/src/index.js new file mode 100644 index 00000000..5656faba --- /dev/null +++ b/test/cases/multi-theme-based-on-entries/src/index.js @@ -0,0 +1,28 @@ +/* eslint-env browser */ + +let theme = "light"; + +document.onclick = () => { + // eslint-disable-next-line no-console + console.log("CHANGE THEME"); + + if (theme === "light") { + theme = "dark"; + } else { + theme = "light"; + } + + const themeElement = document.querySelector("#theme"); + + if (themeElement) { + themeElement.remove(); + } + + const linkElement = document.createElement("link"); + + linkElement.type = "text/css"; + linkElement.rel = "stylesheet"; + linkElement.href = `${theme}-theme.css`; + + document.getElementsByTagName("head")[0].appendChild(linkElement); +}; diff --git a/test/cases/multi-theme-based-on-entries/src/light-theme/_vars.scss b/test/cases/multi-theme-based-on-entries/src/light-theme/_vars.scss new file mode 100644 index 00000000..6a1fb84b --- /dev/null +++ b/test/cases/multi-theme-based-on-entries/src/light-theme/_vars.scss @@ -0,0 +1 @@ +$background: white; diff --git a/test/cases/multi-theme-based-on-entries/src/style.scss b/test/cases/multi-theme-based-on-entries/src/style.scss new file mode 100644 index 00000000..fb281175 --- /dev/null +++ b/test/cases/multi-theme-based-on-entries/src/style.scss @@ -0,0 +1,3 @@ +body { + background-color: vars.$background; +} diff --git a/test/cases/multi-theme-based-on-entries/webpack.config.js b/test/cases/multi-theme-based-on-entries/webpack.config.js new file mode 100644 index 00000000..fd4f2b56 --- /dev/null +++ b/test/cases/multi-theme-based-on-entries/webpack.config.js @@ -0,0 +1,57 @@ +import Self from "../../../src"; + +module.exports = { + entry: { + "light-theme": { + import: ["./src/index.js", "./src/style.scss"], + }, + "dark-theme": { + import: ["./src/index.js", "./src/style.scss?dark"], + }, + }, + // For better runtime code caching + optimization: { + runtimeChunk: { + name: "runtime", + }, + }, + module: { + rules: [ + { + test: /\.s[ac]ss$/i, + oneOf: [ + { + resourceQuery: "?dark", + use: [ + Self.loader, + "css-loader", + { + loader: "sass-loader", + options: { + additionalData: `@use 'dark-theme/vars' as vars;`, + }, + }, + ], + }, + { + use: [ + Self.loader, + "css-loader", + { + loader: "sass-loader", + options: { + additionalData: `@use 'light-theme/vars' as vars;`, + }, + }, + ], + }, + ], + }, + ], + }, + plugins: [ + new Self({ + filename: "[name].css", + }), + ], +}; From 4ca4630fff4ceaae8be85f5f426d6721d0a2faa4 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Mon, 6 Sep 2021 17:54:26 +0300 Subject: [PATCH 2/4] test: more tests --- README.md | 76 ++++++++++--------- .../public/index.html | 15 ---- .../multi-theme-based-on-entries/src/index.js | 28 ------- .../expected/dark.css} | 0 .../expected/main.css} | 0 .../public/index.html | 12 +++ .../src/dark-theme/_vars.scss | 0 .../src/index.js | 50 ++++++++++++ .../src/light-theme/_vars.scss | 0 .../src/style.scss | 0 .../webpack.config.js | 18 +---- .../expected/dark.css | 3 + .../expected/light.css | 3 + .../public/index.html | 11 +++ .../src/dark-theme/_vars.scss | 1 + .../src/index.js | 58 ++++++++++++++ .../src/light-theme/_vars.scss | 1 + .../src/style.scss | 3 + .../webpack.config.js | 49 ++++++++++++ 19 files changed, 237 insertions(+), 91 deletions(-) delete mode 100644 test/cases/multi-theme-based-on-entries/public/index.html delete mode 100644 test/cases/multi-theme-based-on-entries/src/index.js rename test/cases/{multi-theme-based-on-entries/expected/dark-theme.css => multiple-themes-async-loading-with-default-light/expected/dark.css} (100%) rename test/cases/{multi-theme-based-on-entries/expected/light-theme.css => multiple-themes-async-loading-with-default-light/expected/main.css} (100%) create mode 100644 test/cases/multiple-themes-async-loading-with-default-light/public/index.html rename test/cases/{multi-theme-based-on-entries => multiple-themes-async-loading-with-default-light}/src/dark-theme/_vars.scss (100%) create mode 100644 test/cases/multiple-themes-async-loading-with-default-light/src/index.js rename test/cases/{multi-theme-based-on-entries => multiple-themes-async-loading-with-default-light}/src/light-theme/_vars.scss (100%) rename test/cases/{multi-theme-based-on-entries => multiple-themes-async-loading-with-default-light}/src/style.scss (100%) rename test/cases/{multi-theme-based-on-entries => multiple-themes-async-loading-with-default-light}/webpack.config.js (74%) create mode 100644 test/cases/multiple-themes-async-loading/expected/dark.css create mode 100644 test/cases/multiple-themes-async-loading/expected/light.css create mode 100644 test/cases/multiple-themes-async-loading/public/index.html create mode 100644 test/cases/multiple-themes-async-loading/src/dark-theme/_vars.scss create mode 100644 test/cases/multiple-themes-async-loading/src/index.js create mode 100644 test/cases/multiple-themes-async-loading/src/light-theme/_vars.scss create mode 100644 test/cases/multiple-themes-async-loading/src/style.scss create mode 100644 test/cases/multiple-themes-async-loading/webpack.config.js diff --git a/README.md b/README.md index adca50eb..bfede678 100644 --- a/README.md +++ b/README.md @@ -919,20 +919,7 @@ module.exports = { const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { - entry: { - "light-theme": { - import: ["./src/index.js", "./src/style.scss"], - }, - "dark-theme": { - import: ["./src/index.js", "./src/style.scss?dark"], - }, - }, - // For better runtime code caching - optimization: { - runtimeChunk: { - name: "runtime", - }, - }, + entry: "./src/index.js", module: { rules: [ { @@ -968,8 +955,11 @@ module.exports = { ], }, plugins: [ - new MiniCssExtractPlugin({ + new Self({ filename: "[name].css", + attributes: { + id: "theme", + }, }), ], }; @@ -978,16 +968,16 @@ module.exports = { **src/index.js** ```js +import "./style.scss"; + let theme = "light"; +const themes = {}; -document.onclick = () => { - console.log("CHANGING THEME..."); +themes[theme] = document.querySelector("#theme"); - if (theme === "light") { - theme = "dark"; - } else { - theme = "light"; - } +async function loadTheme(newTheme) { + // eslint-disable-next-line no-console + console.log(`CHANGE THEME - ${newTheme}`); const themeElement = document.querySelector("#theme"); @@ -995,15 +985,36 @@ document.onclick = () => { themeElement.remove(); } - const linkElement = document.createElement("link"); + if (themes[newTheme]) { + // eslint-disable-next-line no-console + console.log(`THEME ALREADY LOADED - ${newTheme}`); + + document.head.appendChild(themes[newTheme]); + + return; + } + + if (newTheme === "dark") { + // eslint-disable-next-line no-console + console.log(`LOADING THEME - ${newTheme}`); - linkElement.type = "text/css"; - linkElement.rel = "stylesheet"; - linkElement.href = `${theme}-theme.css`; + import(/* webpackChunkName: "dark" */ "./style.scss?dark").then(() => { + themes[newTheme] = document.querySelector("#theme"); - document.getElementsByTagName("head")[0].appendChild(linkElement); + // eslint-disable-next-line no-console + console.log(`LOADED - ${newTheme}`); + }); + } +} + +document.onclick = () => { + if (theme === "light") { + theme = "dark"; + } else { + theme = "light"; + } - console.log("THEME WAS CHANGED"); + loadTheme(theme); }; ``` @@ -1027,14 +1038,11 @@ $background: white; - - Multiple Themes - - + Document + - - + ``` diff --git a/test/cases/multi-theme-based-on-entries/public/index.html b/test/cases/multi-theme-based-on-entries/public/index.html deleted file mode 100644 index 60bc9273..00000000 --- a/test/cases/multi-theme-based-on-entries/public/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - Document - - - - - - - \ No newline at end of file diff --git a/test/cases/multi-theme-based-on-entries/src/index.js b/test/cases/multi-theme-based-on-entries/src/index.js deleted file mode 100644 index 5656faba..00000000 --- a/test/cases/multi-theme-based-on-entries/src/index.js +++ /dev/null @@ -1,28 +0,0 @@ -/* eslint-env browser */ - -let theme = "light"; - -document.onclick = () => { - // eslint-disable-next-line no-console - console.log("CHANGE THEME"); - - if (theme === "light") { - theme = "dark"; - } else { - theme = "light"; - } - - const themeElement = document.querySelector("#theme"); - - if (themeElement) { - themeElement.remove(); - } - - const linkElement = document.createElement("link"); - - linkElement.type = "text/css"; - linkElement.rel = "stylesheet"; - linkElement.href = `${theme}-theme.css`; - - document.getElementsByTagName("head")[0].appendChild(linkElement); -}; diff --git a/test/cases/multi-theme-based-on-entries/expected/dark-theme.css b/test/cases/multiple-themes-async-loading-with-default-light/expected/dark.css similarity index 100% rename from test/cases/multi-theme-based-on-entries/expected/dark-theme.css rename to test/cases/multiple-themes-async-loading-with-default-light/expected/dark.css diff --git a/test/cases/multi-theme-based-on-entries/expected/light-theme.css b/test/cases/multiple-themes-async-loading-with-default-light/expected/main.css similarity index 100% rename from test/cases/multi-theme-based-on-entries/expected/light-theme.css rename to test/cases/multiple-themes-async-loading-with-default-light/expected/main.css diff --git a/test/cases/multiple-themes-async-loading-with-default-light/public/index.html b/test/cases/multiple-themes-async-loading-with-default-light/public/index.html new file mode 100644 index 00000000..061216f2 --- /dev/null +++ b/test/cases/multiple-themes-async-loading-with-default-light/public/index.html @@ -0,0 +1,12 @@ + + + + + + Document + + + + + + \ No newline at end of file diff --git a/test/cases/multi-theme-based-on-entries/src/dark-theme/_vars.scss b/test/cases/multiple-themes-async-loading-with-default-light/src/dark-theme/_vars.scss similarity index 100% rename from test/cases/multi-theme-based-on-entries/src/dark-theme/_vars.scss rename to test/cases/multiple-themes-async-loading-with-default-light/src/dark-theme/_vars.scss diff --git a/test/cases/multiple-themes-async-loading-with-default-light/src/index.js b/test/cases/multiple-themes-async-loading-with-default-light/src/index.js new file mode 100644 index 00000000..cce9cc7c --- /dev/null +++ b/test/cases/multiple-themes-async-loading-with-default-light/src/index.js @@ -0,0 +1,50 @@ +/* eslint-env browser */ +import "./style.scss"; + +let theme = "light"; +const themes = {}; + +themes[theme] = document.querySelector("#theme"); + +async function loadTheme(newTheme) { + // eslint-disable-next-line no-console + console.log(`CHANGE THEME - ${newTheme}`); + + const themeElement = document.querySelector("#theme"); + + if (themeElement) { + themeElement.remove(); + } + + if (themes[newTheme]) { + // eslint-disable-next-line no-console + console.log(`THEME ALREADY LOADED - ${newTheme}`); + + document.head.appendChild(themes[newTheme]); + + return; + } + + if (newTheme === "dark") { + // eslint-disable-next-line no-console + console.log(`LOADING THEME - ${newTheme}`); + + // eslint-disable-next-line import/no-unresolved + import(/* webpackChunkName: "dark" */ "./style.scss?dark").then(() => { + themes[newTheme] = document.querySelector("#theme"); + + // eslint-disable-next-line no-console + console.log(`LOADED - ${newTheme}`); + }); + } +} + +document.onclick = () => { + if (theme === "light") { + theme = "dark"; + } else { + theme = "light"; + } + + loadTheme(theme); +}; diff --git a/test/cases/multi-theme-based-on-entries/src/light-theme/_vars.scss b/test/cases/multiple-themes-async-loading-with-default-light/src/light-theme/_vars.scss similarity index 100% rename from test/cases/multi-theme-based-on-entries/src/light-theme/_vars.scss rename to test/cases/multiple-themes-async-loading-with-default-light/src/light-theme/_vars.scss diff --git a/test/cases/multi-theme-based-on-entries/src/style.scss b/test/cases/multiple-themes-async-loading-with-default-light/src/style.scss similarity index 100% rename from test/cases/multi-theme-based-on-entries/src/style.scss rename to test/cases/multiple-themes-async-loading-with-default-light/src/style.scss diff --git a/test/cases/multi-theme-based-on-entries/webpack.config.js b/test/cases/multiple-themes-async-loading-with-default-light/webpack.config.js similarity index 74% rename from test/cases/multi-theme-based-on-entries/webpack.config.js rename to test/cases/multiple-themes-async-loading-with-default-light/webpack.config.js index fd4f2b56..58c979cd 100644 --- a/test/cases/multi-theme-based-on-entries/webpack.config.js +++ b/test/cases/multiple-themes-async-loading-with-default-light/webpack.config.js @@ -1,20 +1,7 @@ import Self from "../../../src"; module.exports = { - entry: { - "light-theme": { - import: ["./src/index.js", "./src/style.scss"], - }, - "dark-theme": { - import: ["./src/index.js", "./src/style.scss?dark"], - }, - }, - // For better runtime code caching - optimization: { - runtimeChunk: { - name: "runtime", - }, - }, + entry: "./src/index.js", module: { rules: [ { @@ -52,6 +39,9 @@ module.exports = { plugins: [ new Self({ filename: "[name].css", + attributes: { + id: "theme", + }, }), ], }; diff --git a/test/cases/multiple-themes-async-loading/expected/dark.css b/test/cases/multiple-themes-async-loading/expected/dark.css new file mode 100644 index 00000000..c4d554e0 --- /dev/null +++ b/test/cases/multiple-themes-async-loading/expected/dark.css @@ -0,0 +1,3 @@ +body { + background-color: black; +} diff --git a/test/cases/multiple-themes-async-loading/expected/light.css b/test/cases/multiple-themes-async-loading/expected/light.css new file mode 100644 index 00000000..cdf802a3 --- /dev/null +++ b/test/cases/multiple-themes-async-loading/expected/light.css @@ -0,0 +1,3 @@ +body { + background-color: white; +} diff --git a/test/cases/multiple-themes-async-loading/public/index.html b/test/cases/multiple-themes-async-loading/public/index.html new file mode 100644 index 00000000..c51cce96 --- /dev/null +++ b/test/cases/multiple-themes-async-loading/public/index.html @@ -0,0 +1,11 @@ + + + + + + Document + + + + + \ No newline at end of file diff --git a/test/cases/multiple-themes-async-loading/src/dark-theme/_vars.scss b/test/cases/multiple-themes-async-loading/src/dark-theme/_vars.scss new file mode 100644 index 00000000..2abe50c6 --- /dev/null +++ b/test/cases/multiple-themes-async-loading/src/dark-theme/_vars.scss @@ -0,0 +1 @@ +$background: black; diff --git a/test/cases/multiple-themes-async-loading/src/index.js b/test/cases/multiple-themes-async-loading/src/index.js new file mode 100644 index 00000000..8c016077 --- /dev/null +++ b/test/cases/multiple-themes-async-loading/src/index.js @@ -0,0 +1,58 @@ +/* eslint-env browser */ + +let theme = "light"; + +const themes = {}; + +async function loadTheme(newTheme) { + // eslint-disable-next-line no-console + console.log(`CHANGE THEME - ${newTheme}`); + + const themeElement = document.querySelector("#theme"); + + if (themeElement) { + themeElement.remove(); + } + + if (themes[newTheme]) { + // eslint-disable-next-line no-console + // eslint-disable-next-line no-console + console.log(`THEME ALREADY LOADED - ${newTheme}`); + + document.head.appendChild(themes[newTheme]); + + return; + } + + // eslint-disable-next-line no-console + console.log(`LOADING THEME - ${newTheme}`); + + if (newTheme === "light") { + import(/* webpackChunkName: "light" */ "./style.scss").then(() => { + themes[newTheme] = document.querySelector("#theme"); + + // eslint-disable-next-line no-console + console.log(`LOADED - ${newTheme}`); + }); + } else { + // eslint-disable-next-line import/no-unresolved + import(/* webpackChunkName: "dark" */ "./style.scss?dark").then(() => { + themes[newTheme] = document.querySelector("#theme"); + + // eslint-disable-next-line no-console + console.log(`LOADED - ${newTheme}`); + }); + } +} + +document.onclick = () => { + if (theme === "light") { + theme = "dark"; + } else { + theme = "light"; + } + + loadTheme(theme); +}; + +loadTheme(theme); diff --git a/test/cases/multiple-themes-async-loading/src/light-theme/_vars.scss b/test/cases/multiple-themes-async-loading/src/light-theme/_vars.scss new file mode 100644 index 00000000..6a1fb84b --- /dev/null +++ b/test/cases/multiple-themes-async-loading/src/light-theme/_vars.scss @@ -0,0 +1 @@ +$background: white; diff --git a/test/cases/multiple-themes-async-loading/src/style.scss b/test/cases/multiple-themes-async-loading/src/style.scss new file mode 100644 index 00000000..fb281175 --- /dev/null +++ b/test/cases/multiple-themes-async-loading/src/style.scss @@ -0,0 +1,3 @@ +body { + background-color: vars.$background; +} diff --git a/test/cases/multiple-themes-async-loading/webpack.config.js b/test/cases/multiple-themes-async-loading/webpack.config.js new file mode 100644 index 00000000..9faf720d --- /dev/null +++ b/test/cases/multiple-themes-async-loading/webpack.config.js @@ -0,0 +1,49 @@ +// import Self from "../../../src"; + +const Self = require("../../../dist/cjs"); + +module.exports = { + entry: "./src/index.js", + module: { + rules: [ + { + test: /\.s[ac]ss$/i, + oneOf: [ + { + resourceQuery: "?dark", + use: [ + Self.loader, + "css-loader", + { + loader: "sass-loader", + options: { + additionalData: `@use 'dark-theme/vars' as vars;`, + }, + }, + ], + }, + { + use: [ + Self.loader, + "css-loader", + { + loader: "sass-loader", + options: { + additionalData: `@use 'light-theme/vars' as vars;`, + }, + }, + ], + }, + ], + }, + ], + }, + plugins: [ + new Self({ + filename: "[name].css", + attributes: { + id: "theme", + }, + }), + ], +}; From e72246a1068bc2b1c7871b75d4eac5f4299d5308 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Mon, 6 Sep 2021 18:00:09 +0300 Subject: [PATCH 3/4] docs: fix --- README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bfede678..bf483fab 100644 --- a/README.md +++ b/README.md @@ -1018,18 +1018,26 @@ document.onclick = () => { }; ``` -**src/dark-theme/\_vars** +**src/dark-theme/\_vars.scss** ```scss $background: black; ``` -**src/light-theme/\_vars** +**src/light-theme/\_vars.scss** ```scss $background: white; ``` +**src/styles.scss** + +```scss +body { + background-color: vars.$background; +} +``` + **public/index.html** ```html From bae3ce73293671d16eada61cdc147d2ced24b460 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Mon, 6 Sep 2021 18:05:05 +0300 Subject: [PATCH 4/4] test: fix --- test/cases/multiple-themes-async-loading/webpack.config.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/cases/multiple-themes-async-loading/webpack.config.js b/test/cases/multiple-themes-async-loading/webpack.config.js index 9faf720d..58c979cd 100644 --- a/test/cases/multiple-themes-async-loading/webpack.config.js +++ b/test/cases/multiple-themes-async-loading/webpack.config.js @@ -1,6 +1,4 @@ -// import Self from "../../../src"; - -const Self = require("../../../dist/cjs"); +import Self from "../../../src"; module.exports = { entry: "./src/index.js",