Merge pull request #18318 from vector-im/palid/feature/css-hmr
Add CSS hot module reloadpull/18380/head
						commit
						8b56a55906
					
				|  | @ -0,0 +1,14 @@ | |||
| # If you want to have proper hot-reload css experience, define one and set this on. | ||||
| CSS_HOT_RELOAD=1 | ||||
| # Define which one theme you want to load for hot-reload purposes. | ||||
| # To use a single theme just uncomment a line with the theme you want to use. | ||||
| MATRIX_THEMES='light' | ||||
| #MATRIX_THEMES='dark' | ||||
| #MATRIX_THEMES='light-legacy' | ||||
| #MATRIX_THEMES='dark-legacy' | ||||
| #MATRIX_THEMES='light-custom' | ||||
| #MATRIX_THEMES='dark-custom' | ||||
| # You can load multiple themes at once, but switching between them may require full page reload. | ||||
| # It will also multiple compliation times by the number of turned on themes. | ||||
| # If you want to use multiple themes, define the combinations manually like below: | ||||
| #MATRIX_THEMES='light,dark' | ||||
|  | @ -21,3 +21,4 @@ electron/pub | |||
| /webpack-stats.json | ||||
| .vscode | ||||
| .vscode/ | ||||
| .env | ||||
|  |  | |||
							
								
								
									
										51
									
								
								README.md
								
								
								
								
							
							
						
						
									
										51
									
								
								README.md
								
								
								
								
							|  | @ -30,14 +30,14 @@ and [element-ios](https://github.com/vector-im/element-ios). | |||
| Getting Started | ||||
| =============== | ||||
| 
 | ||||
| The easiest way to test Element is to just use the hosted copy at https://app.element.io. | ||||
| The `develop` branch is continuously deployed to https://develop.element.io | ||||
| The easiest way to test Element is to just use the hosted copy at <https://app.element.io>. | ||||
| The `develop` branch is continuously deployed to <https://develop.element.io> | ||||
| for those who like living dangerously. | ||||
| 
 | ||||
| To host your own copy of Element, the quickest bet is to use a pre-built | ||||
| released version of Element: | ||||
| 
 | ||||
| 1. Download the latest version from https://github.com/vector-im/element-web/releases | ||||
| 1. Download the latest version from <https://github.com/vector-im/element-web/releases> | ||||
| 1. Untar the tarball on your web server | ||||
| 1. Move (or symlink) the `element-x.x.x` directory to an appropriate name | ||||
| 1. Configure the correct caching headers in your webserver (see below) | ||||
|  | @ -46,7 +46,7 @@ released version of Element: | |||
| 1. Enter the URL into your browser and log into Element! | ||||
| 
 | ||||
| Releases are signed using gpg and the OpenPGP standard, and can be checked against the public key located | ||||
| at https://packages.riot.im/element-release-key.asc. | ||||
| at <https://packages.riot.im/element-release-key.asc>. | ||||
| 
 | ||||
| Note that for the security of your chats will need to serve Element | ||||
| over HTTPS. Major browsers also do not allow you to use VoIP/video | ||||
|  | @ -72,7 +72,7 @@ access to Element (or other apps) due to sharing the same domain. | |||
| 
 | ||||
| We have put some coarse mitigations into place to try to protect against this | ||||
| situation, but it's still not good practice to do it in the first place.  See | ||||
| https://github.com/vector-im/element-web/issues/1977 for more details. | ||||
| <https://github.com/vector-im/element-web/issues/1977> for more details. | ||||
| 
 | ||||
| Configuration best practices | ||||
| ---------------------------- | ||||
|  | @ -80,15 +80,15 @@ Configuration best practices | |||
| Unless you have special requirements, you will want to add the following to | ||||
| your web server configuration when hosting Element Web: | ||||
| 
 | ||||
| - The `X-Frame-Options: SAMEORIGIN` header, to prevent Element Web from being | ||||
| * The `X-Frame-Options: SAMEORIGIN` header, to prevent Element Web from being | ||||
|   framed and protect from [clickjacking][owasp-clickjacking]. | ||||
| - The `frame-ancestors 'none'` directive to your `Content-Security-Policy` | ||||
| * The `frame-ancestors 'none'` directive to your `Content-Security-Policy` | ||||
|   header, as the modern replacement for `X-Frame-Options` (though both should be | ||||
|   included since not all browsers support it yet, see | ||||
|   [this][owasp-clickjacking-csp]). | ||||
| - The `X-Content-Type-Options: nosniff` header, to [disable MIME | ||||
| * The `X-Content-Type-Options: nosniff` header, to [disable MIME | ||||
|   sniffing][mime-sniffing]. | ||||
| - The `X-XSS-Protection: 1; mode=block;` header, for basic XSS protection in | ||||
| * The `X-XSS-Protection: 1; mode=block;` header, for basic XSS protection in | ||||
|   legacy browsers. | ||||
| 
 | ||||
| [mime-sniffing]: | ||||
|  | @ -127,10 +127,10 @@ guide](https://classic.yarnpkg.com/en/docs/install) if you do not have it alread | |||
| 1. Clone the repo: `git clone https://github.com/vector-im/element-web.git`. | ||||
| 1. Switch to the element-web directory: `cd element-web`. | ||||
| 1. Install the prerequisites: `yarn install`. | ||||
|    *  If you're using the `develop` branch, then it is recommended to set up a | ||||
|    * If you're using the `develop` branch, then it is recommended to set up a | ||||
|       proper development environment (see [Setting up a dev | ||||
|       environment](#setting-up-a-dev-environment) below). Alternatively, you | ||||
|       can use https://develop.element.io - the continuous integration release of | ||||
|       can use <https://develop.element.io> - the continuous integration release of | ||||
|       the develop branch. | ||||
| 1. Configure the app by copying `config.sample.json` to `config.json` and | ||||
|    modifying it. See the [configuration docs](docs/config.md) for details. | ||||
|  | @ -148,15 +148,16 @@ Running as a Desktop app | |||
| ======================== | ||||
| 
 | ||||
| Element can also be run as a desktop app, wrapped in Electron. You can download a | ||||
| pre-built version from https://element.io/get-started or, if you prefer, | ||||
| pre-built version from <https://element.io/get-started> or, if you prefer, | ||||
| build it yourself. | ||||
| 
 | ||||
| To build it yourself, follow the instructions at https://github.com/vector-im/element-desktop. | ||||
| To build it yourself, follow the instructions at <https://github.com/vector-im/element-desktop>. | ||||
| 
 | ||||
| Many thanks to @aviraldg for the initial work on the Electron integration. | ||||
| 
 | ||||
| Other options for running as a desktop app: | ||||
|  * @asdf:matrix.org points out that you can use nativefier and it just works(tm) | ||||
| 
 | ||||
| * @asdf:matrix.org points out that you can use nativefier and it just works(tm) | ||||
| 
 | ||||
| ```bash | ||||
| yarn global add nativefier | ||||
|  | @ -171,6 +172,7 @@ Running from Docker | |||
| 
 | ||||
| The Docker image can be used to serve element-web as a web server. The easiest way to use | ||||
| it is to use the prebuilt image: | ||||
| 
 | ||||
| ```bash | ||||
| docker run -p 80:80 vectorim/element-web | ||||
| ``` | ||||
|  | @ -178,11 +180,13 @@ docker run -p 80:80 vectorim/element-web | |||
| To supply your own custom `config.json`, map a volume to `/app/config.json`. For example, | ||||
| if your custom config was located at `/etc/element-web/config.json` then your Docker command | ||||
| would be: | ||||
| 
 | ||||
| ```bash | ||||
| docker run -p 80:80 -v /etc/element-web/config.json:/app/config.json vectorim/element-web | ||||
| ``` | ||||
| 
 | ||||
| To build the image yourself: | ||||
| 
 | ||||
| ```bash | ||||
| git clone https://github.com/vector-im/element-web.git element-web | ||||
| cd element-web | ||||
|  | @ -192,6 +196,7 @@ docker build . | |||
| 
 | ||||
| If you're building a custom branch, or want to use the develop branch, check out the appropriate | ||||
| element-web branch and then run: | ||||
| 
 | ||||
| ```bash | ||||
| docker build -t \ | ||||
|     --build-arg USE_CUSTOM_SDKS=true \ | ||||
|  | @ -224,6 +229,7 @@ Caching requirements | |||
| ==================== | ||||
| 
 | ||||
| Element requires the following URLs not to be cached, when/if you are serving Element from your own webserver: | ||||
| 
 | ||||
| ``` | ||||
| /config.*.json | ||||
| /i18n | ||||
|  | @ -261,6 +267,10 @@ internet.  So please don't depend on resources (JS libs, CSS, images, fonts) | |||
| hosted by external CDNs or servers but instead please package all dependencies | ||||
| into Element itself. | ||||
| 
 | ||||
| CSS hot-reload is currently an opt-in development feature, and if you want to have | ||||
| it working properly on your environment, create a `.env` file in this repository | ||||
| with proper environmental, see `.env.example` for documentation and example. | ||||
| 
 | ||||
| Setting up a dev environment | ||||
| ============================ | ||||
| 
 | ||||
|  | @ -302,14 +312,15 @@ yarn reskindex | |||
| yarn start | ||||
| ``` | ||||
| 
 | ||||
| 
 | ||||
| Wait a few seconds for the initial build to finish; you should see something like: | ||||
| 
 | ||||
| ``` | ||||
| [element-js] <s> [webpack.Progress] 100% | ||||
| [element-js] | ||||
| [element-js] ℹ 「wdm」:    1840 modules | ||||
| [element-js] ℹ 「wdm」: Compiled successfully. | ||||
| ``` | ||||
| 
 | ||||
|    Remember, the command will not terminate since it runs the web server | ||||
|    and rebuilds source files when they change. This development server also | ||||
|    disables caching, so do NOT use it in production. | ||||
|  | @ -317,7 +328,7 @@ Wait a few seconds for the initial build to finish; you should see something lik | |||
| Configure the app by copying `config.sample.json` to `config.json` and | ||||
| modifying it. See the [configuration docs](docs/config.md) for details. | ||||
| 
 | ||||
| Open http://127.0.0.1:8080/ in your browser to see your newly built Element. | ||||
| Open <http://127.0.0.1:8080/> in your browser to see your newly built Element. | ||||
| 
 | ||||
| **Note**: The build script uses inotify by default on Linux to monitor directories | ||||
| for changes. If the inotify limits are too low your build will fail silently or with | ||||
|  | @ -393,14 +404,14 @@ Triaging issues | |||
| We strive to completely cover all applicable issues with these core labels: | ||||
| 
 | ||||
| 1. __Type__ — Every issue is assigned a type: | ||||
|    - __[T-Defect](https://github.com/vector-im/element-web/labels/T-Defect):__ | ||||
|    * __[T-Defect](https://github.com/vector-im/element-web/labels/T-Defect):__ | ||||
|      Bugs, crashes, hangs, vulnerabilities, or other reported problems | ||||
|    - __[T-Enhancement](https://github.com/vector-im/element-web/labels/T-Enhancement):__ | ||||
|    * __[T-Enhancement](https://github.com/vector-im/element-web/labels/T-Enhancement):__ | ||||
|      New features, changes in functionality, performance boosts, user-facing | ||||
|      improvements | ||||
|    - __[T-Task](https://github.com/vector-im/element-web/labels/T-Task):__ | ||||
|    * __[T-Task](https://github.com/vector-im/element-web/labels/T-Task):__ | ||||
|      Refactoring, enabling or disabling functionality, other engineering tasks | ||||
|    - __[T-Other](https://github.com/vector-im/element-web/labels/T-Other):__ | ||||
|    * __[T-Other](https://github.com/vector-im/element-web/labels/T-Other):__ | ||||
|      Questions, user support, anything else | ||||
| 
 | ||||
| 2. __Severity__ — All issues labeled `T-Defect` are also assigned a severity: | ||||
|  |  | |||
|  | @ -46,7 +46,7 @@ | |||
|     "start": "concurrently --kill-others-on-fail --prefix \"{time} [{name}]\" -n reskindex,reskindex-react,res,element-js \"yarn reskindex:watch\" \"yarn reskindex:watch-react\" \"yarn start:res\" \"yarn start:js\"", | ||||
|     "start:https": "concurrently --kill-others-on-fail --prefix \"{time} [{name}]\" -n reskindex,reskindex-react,res,element-js \"yarn reskindex:watch\" \"yarn reskindex:watch-react\" \"yarn start:res\" \"yarn start:js --https\"", | ||||
|     "start:res": "yarn build:jitsi && node scripts/copy-res.js -w", | ||||
|     "start:js": "webpack-dev-server --host=0.0.0.0 --output-filename=bundles/_dev_/[name].js --output-chunk-filename=bundles/_dev_/[name].js -w --progress --mode development --disable-host-check", | ||||
|     "start:js": "webpack-dev-server --host=0.0.0.0 --output-filename=bundles/_dev_/[name].js --output-chunk-filename=bundles/_dev_/[name].js -w --progress --mode development --disable-host-check --hot", | ||||
|     "lint": "yarn lint:types && yarn lint:js && yarn lint:style", | ||||
|     "lint:js": "eslint --max-warnings 0 src", | ||||
|     "lint:js-fix": "eslint --fix src", | ||||
|  | @ -105,6 +105,7 @@ | |||
|     "concurrently": "^5.3.0", | ||||
|     "cpx": "^1.5.0", | ||||
|     "css-loader": "^3.6.0", | ||||
|     "dotenv": "^10.0.0", | ||||
|     "eslint": "7.18.0", | ||||
|     "eslint-config-google": "^0.14.0", | ||||
|     "eslint-plugin-matrix-org": "github:matrix-org/eslint-plugin-matrix-org#2306b3d4da4eba908b256014b979f1d3d43d2945", | ||||
|  | @ -142,6 +143,8 @@ | |||
|     "rimraf": "^3.0.2", | ||||
|     "shell-escape": "^0.2.0", | ||||
|     "simple-proxy-agent": "^1.1.0", | ||||
|     "string-replace-loader": "2", | ||||
|     "style-loader": "2", | ||||
|     "stylelint": "^13.9.0", | ||||
|     "stylelint-config-standard": "^20.0.0", | ||||
|     "stylelint-scss": "^3.18.0", | ||||
|  |  | |||
|  | @ -0,0 +1,46 @@ | |||
| /* | ||||
| Copyright 2021 The Matrix.org Foundation C.I.C. | ||||
| 
 | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
| 
 | ||||
|     http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| 
 | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| /** | ||||
|  * This code will be autoremoved on production builds. | ||||
|  * The purpose of this code is that the webpack's `string-replace-loader` | ||||
|  * pretty much search for this string in this specific file and replaces it | ||||
|  * like a macro before any previous compilations, which allows us to inject | ||||
|  * some css requires statements that are specific to the themes we have turned | ||||
|  * on by ourselves. Without that very specific workaround, webpack would just | ||||
|  * import all the CSSes, which would make the whole thing useless, as on my | ||||
|  * machine with i9 the recompilation for all themes turned ou would take way | ||||
|  * over 30s, which is definitely too high for nice css reloads speed. | ||||
|  * | ||||
|  * For more details, see webpack.config.js:184 (string-replace-loader) | ||||
|  */ | ||||
| if (process.env.NODE_ENV === 'development') { | ||||
|     ("use theming"); | ||||
|     /** | ||||
|      * Clean up old hot-module script injections as they hog up memory | ||||
|      * and anything other than the newest one is really not needed at all. | ||||
|      * We don't need to do it more frequently than every half a minute or so, | ||||
|      * but it's done to delay full page reload due to app slowness. | ||||
|      */ | ||||
|     setInterval(() => { | ||||
|         const elements = Array.from(document.querySelectorAll("script[src*=hot-update]")); | ||||
|         if (elements.length > 1) { | ||||
|             const oldInjects = elements.slice(0, elements.length - 1); | ||||
|             oldInjects.forEach(e => e.remove()); | ||||
|         } | ||||
|     }, 1000); | ||||
| } | ||||
| 
 | ||||
|  | @ -43,7 +43,7 @@ | |||
|         if (match) { | ||||
|             var title = match[1].charAt(0).toUpperCase() + match[1].slice(1); | ||||
|         %> | ||||
|            <link rel="stylesheet" disabled="disabled" title="<%= title %>" href="<%= file %>"> | ||||
|            <link rel="stylesheet" disabled="disabled" data-mx-theme="<%= title %>" title="<%= title %>" href="<%= file %>"> | ||||
|         <% } else { %> | ||||
|            <link rel="stylesheet" href="<%= file %>"> | ||||
|         <% } | ||||
|  |  | |||
|  | @ -25,6 +25,14 @@ require('gfm.css/gfm.css'); | |||
| require('highlight.js/styles/github.css'); | ||||
| require('katex/dist/katex.css'); | ||||
| 
 | ||||
| /** | ||||
|  * This require is necessary only for purposes of CSS hot reload, as otherwise | ||||
|  * webpack has some incredibly problems figuring out which css files should be | ||||
|  * hot reloaded, even with proper hints for the loader. | ||||
|  * | ||||
|  * On production build it's going to be an empty module, so don't worry about that. | ||||
|  */ | ||||
| require('./devcss'); | ||||
| // These are things that can run before the skin loads - be careful not to reference the react-sdk though.
 | ||||
| import { parseQsFromFragment } from "./url_utils"; | ||||
| import './modernizr'; | ||||
|  |  | |||
|  | @ -1,18 +1,34 @@ | |||
| /* eslint-disable quote-props */ | ||||
| 
 | ||||
| const dotenv = require('dotenv'); | ||||
| const path = require('path'); | ||||
| const webpack = require('webpack'); | ||||
| const HtmlWebpackPlugin = require('html-webpack-plugin'); | ||||
| const MiniCssExtractPlugin = require('mini-css-extract-plugin'); | ||||
| const TerserPlugin = require('terser-webpack-plugin'); | ||||
| const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); | ||||
| const HtmlWebpackInjectPreload = require('@principalstudio/html-webpack-inject-preload'); | ||||
| 
 | ||||
| dotenv.config(); | ||||
| let ogImageUrl = process.env.RIOT_OG_IMAGE_URL; | ||||
| if (!ogImageUrl) ogImageUrl = 'https://app.element.io/themes/element/img/logos/opengraph.png'; | ||||
| 
 | ||||
| const additionalPlugins = [ | ||||
|     // This is where you can put your customisation replacements.
 | ||||
| ]; | ||||
| const cssThemes = { | ||||
|     // CSS themes
 | ||||
|     "theme-legacy": "./node_modules/matrix-react-sdk/res/themes/legacy-light/css/legacy-light.scss", | ||||
|     "theme-legacy-dark": "./node_modules/matrix-react-sdk/res/themes/legacy-dark/css/legacy-dark.scss", | ||||
|     "theme-light": "./node_modules/matrix-react-sdk/res/themes/light/css/light.scss", | ||||
|     "theme-dark": "./node_modules/matrix-react-sdk/res/themes/dark/css/dark.scss", | ||||
|     "theme-light-custom": "./node_modules/matrix-react-sdk/res/themes/light-custom/css/light-custom.scss", | ||||
|     "theme-dark-custom": "./node_modules/matrix-react-sdk/res/themes/dark-custom/css/dark-custom.scss", | ||||
| }; | ||||
| 
 | ||||
| function getActiveThemes() { | ||||
|     // We want to use `light` theme by default if it's not defined.
 | ||||
|     const theme = process.env.MATRIX_THEMES ?? 'dark'; | ||||
|     const themes = theme.split(',').filter(x => x).map(x => x.trim()).filter(x => x); | ||||
|     return themes; | ||||
| } | ||||
| 
 | ||||
| module.exports = (env, argv) => { | ||||
|     let nodeEnv = argv.mode; | ||||
|  | @ -29,6 +45,8 @@ module.exports = (env, argv) => { | |||
|         // application to productions standards
 | ||||
|         nodeEnv = "production"; | ||||
|     } | ||||
|     const devMode = nodeEnv !== 'production'; | ||||
|     const useCssHotReload = process.env.CSS_HOT_RELOAD === '1' && devMode; | ||||
| 
 | ||||
|     const development = {}; | ||||
|     if (argv.mode === "production") { | ||||
|  | @ -45,9 +63,22 @@ module.exports = (env, argv) => { | |||
|     const reactSdkSrcDir = path.resolve(require.resolve("matrix-react-sdk/package.json"), '..', 'src'); | ||||
|     const jsSdkSrcDir = path.resolve(require.resolve("matrix-js-sdk/package.json"), '..', 'src'); | ||||
| 
 | ||||
|     const ACTIVE_THEMES = getActiveThemes(); | ||||
|     function getThemesImports() { | ||||
|         const imports = ACTIVE_THEMES.map((t, index) => { | ||||
|             const themeImportPath = cssThemes[`theme-${ t }`].replace('./node_modules/', ''); | ||||
|             return themeImportPath; | ||||
|         }); | ||||
|         const s = JSON.stringify(ACTIVE_THEMES); | ||||
|         return ` | ||||
|             window.MX_insertedThemeStylesCounter = 0; | ||||
|             window.MX_DEV_ACTIVE_THEMES = (${ s }); | ||||
|             ${ imports.map(i => `import("${ i }")`).join('\n') }; | ||||
|         `;
 | ||||
|     } | ||||
| 
 | ||||
|     return { | ||||
|         ...development, | ||||
| 
 | ||||
|         node: { | ||||
|             // Mock out the NodeFS module: The opus decoder imports this wrongly.
 | ||||
|             fs: 'empty', | ||||
|  | @ -59,14 +90,7 @@ module.exports = (env, argv) => { | |||
|             "jitsi": "./src/vector/jitsi/index.ts", | ||||
|             "usercontent": "./node_modules/matrix-react-sdk/src/usercontent/index.js", | ||||
|             "recorder-worklet": "./node_modules/matrix-react-sdk/src/audio/RecorderWorklet.ts", | ||||
| 
 | ||||
|             // CSS themes
 | ||||
|             "theme-legacy": "./node_modules/matrix-react-sdk/res/themes/legacy-light/css/legacy-light.scss", | ||||
|             "theme-legacy-dark": "./node_modules/matrix-react-sdk/res/themes/legacy-dark/css/legacy-dark.scss", | ||||
|             "theme-light": "./node_modules/matrix-react-sdk/res/themes/light/css/light.scss", | ||||
|             "theme-dark": "./node_modules/matrix-react-sdk/res/themes/dark/css/dark.scss", | ||||
|             "theme-light-custom": "./node_modules/matrix-react-sdk/res/themes/light-custom/css/light-custom.scss", | ||||
|             "theme-dark-custom": "./node_modules/matrix-react-sdk/res/themes/dark-custom/css/dark-custom.scss", | ||||
|             ...(useCssHotReload ? {} : cssThemes), | ||||
|         }, | ||||
| 
 | ||||
|         optimization: { | ||||
|  | @ -150,6 +174,14 @@ module.exports = (env, argv) => { | |||
|                 /olm[\\/](javascript[\\/])?olm\.js$/, | ||||
|             ], | ||||
|             rules: [ | ||||
|                 useCssHotReload && { | ||||
|                     test: /devcss\.ts$/, | ||||
|                     loader: 'string-replace-loader', | ||||
|                     options: { | ||||
|                         search: '"use theming";', | ||||
|                         replace: getThemesImports(), | ||||
|                     }, | ||||
|                 }, | ||||
|                 { | ||||
|                     test: /\.worker\.ts$/, | ||||
|                     loader: "worker-loader", | ||||
|  | @ -219,7 +251,7 @@ module.exports = (env, argv) => { | |||
| 
 | ||||
|                                     // It's important that this plugin is last otherwise we end
 | ||||
|                                     // up with broken CSS.
 | ||||
|                                     require('postcss-preset-env')({stage: 3, browsers: 'last 2 versions'}), | ||||
|                                     require('postcss-preset-env')({ stage: 3, browsers: 'last 2 versions' }), | ||||
|                                 ], | ||||
|                                 parser: "postcss-scss", | ||||
|                                 "local-plugins": true, | ||||
|  | @ -230,7 +262,40 @@ module.exports = (env, argv) => { | |||
|                 { | ||||
|                     test: /\.scss$/, | ||||
|                     use: [ | ||||
|                         MiniCssExtractPlugin.loader, | ||||
|                         /** | ||||
|                          * This code is hopeful that no .scss outside of our themes will be directly imported in any | ||||
|                          * of the JS/TS files. | ||||
|                          * Should be MUCH better with webpack 5, but we're stuck to this solution for now. | ||||
|                          */ | ||||
|                         useCssHotReload ? { | ||||
|                             loader: 'style-loader', | ||||
|                             /** | ||||
|                              * If we refactor the `theme.js` in `matrix-react-sdk` a little bit, | ||||
|                              * we could try using `lazyStyleTag` here to add and remove styles on demand, | ||||
|                              * that would nicely resolve issues of race conditions for themes, | ||||
|                              * at least for development purposes. | ||||
|                              */ | ||||
|                             options: { | ||||
| 
 | ||||
|                                 insert: function insertBeforeAt(element) { | ||||
|                                     const parent = document.querySelector('head'); | ||||
|                                     // We're in iframe
 | ||||
|                                     if (!window.MX_DEV_ACTIVE_THEMES) { | ||||
|                                         parent.appendChild(element); | ||||
|                                         return; | ||||
|                                     } | ||||
|                                     // Properly disable all other instances of themes
 | ||||
|                                     element.disabled = true; | ||||
|                                     element.onload = () => { | ||||
|                                         element.disabled = true; | ||||
|                                     }; | ||||
|                                     const theme = window.MX_DEV_ACTIVE_THEMES[window.MX_insertedThemeStylesCounter]; | ||||
|                                     element.setAttribute('data-mx-theme', theme); | ||||
|                                     window.MX_insertedThemeStylesCounter++; | ||||
|                                     parent.appendChild(element); | ||||
|                                 }, | ||||
|                             }, | ||||
|                         } : MiniCssExtractPlugin.loader, | ||||
|                         { | ||||
|                             loader: 'css-loader', | ||||
|                             options: { | ||||
|  | @ -257,7 +322,7 @@ module.exports = (env, argv) => { | |||
| 
 | ||||
|                                     // It's important that this plugin is last otherwise we end
 | ||||
|                                     // up with broken CSS.
 | ||||
|                                     require('postcss-preset-env')({stage: 3, browsers: 'last 2 versions'}), | ||||
|                                     require('postcss-preset-env')({ stage: 3, browsers: 'last 2 versions' }), | ||||
|                                 ], | ||||
|                                 parser: "postcss-scss", | ||||
|                                 "local-plugins": true, | ||||
|  | @ -370,13 +435,19 @@ module.exports = (env, argv) => { | |||
|                         }, | ||||
|                     ], | ||||
|                 }, | ||||
|             ], | ||||
|             ].filter(Boolean), | ||||
|         }, | ||||
| 
 | ||||
|         plugins: [ | ||||
|             new webpack.EnvironmentPlugin({ | ||||
|                 NODE_ENV: 'development', // use 'development' unless process.env.NODE_ENV is defined
 | ||||
|                 DEBUG: false, | ||||
|             }), | ||||
| 
 | ||||
|             // This exports our CSS using the splitChunks and loaders above.
 | ||||
|             new MiniCssExtractPlugin({ | ||||
|                 filename: 'bundles/[hash]/[name].css', | ||||
|                 filename: useCssHotReload ? "bundles/[name].css" : "bundles/[hash]/[name].css", | ||||
|                 chunkFilename: useCssHotReload ? "bundles/[name].css" : "bundles/[hash]/[name].css", | ||||
|                 ignoreOrder: false, // Enable to remove warnings about conflicting order
 | ||||
|             }), | ||||
| 
 | ||||
|  | @ -437,7 +508,6 @@ module.exports = (env, argv) => { | |||
|                 files: [{ match: /.*Inter.*\.woff2$/ }], | ||||
|             }), | ||||
| 
 | ||||
|             ...additionalPlugins, | ||||
|         ], | ||||
| 
 | ||||
|         output: { | ||||
|  | @ -457,17 +527,17 @@ module.exports = (env, argv) => { | |||
|         // configuration for the webpack-dev-server
 | ||||
|         devServer: { | ||||
|             // serve unwebpacked assets from webapp.
 | ||||
|             contentBase: './webapp', | ||||
|             contentBase: [ | ||||
|                 './webapp', | ||||
|             ], | ||||
| 
 | ||||
|             // Only output errors, warnings, or new compilations.
 | ||||
|             // This hides the massive list of modules.
 | ||||
|             stats: 'minimal', | ||||
| 
 | ||||
|             // hot module replacement doesn't work (I think we'd need react-hot-reload?)
 | ||||
|             // so webpack-dev-server reloads the page on every update which is quite
 | ||||
|             // tedious in Riot since that can take a while.
 | ||||
|             hot: false, | ||||
|             inline: false, | ||||
|             // hot: false,
 | ||||
|             // injectHot: false,
 | ||||
|             hotOnly: true, | ||||
|             inline: true, | ||||
|         }, | ||||
|     }; | ||||
| }; | ||||
|  |  | |||
							
								
								
									
										43
									
								
								yarn.lock
								
								
								
								
							
							
						
						
									
										43
									
								
								yarn.lock
								
								
								
								
							|  | @ -1555,7 +1555,7 @@ | |||
|   dependencies: | ||||
|     "@types/istanbul-lib-report" "*" | ||||
| 
 | ||||
| "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.7": | ||||
| "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.7", "@types/json-schema@^7.0.8": | ||||
|   version "7.0.8" | ||||
|   resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.8.tgz#edf1bf1dbf4e04413ca8e5b17b3b7d7d54b59818" | ||||
|   integrity sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg== | ||||
|  | @ -2020,7 +2020,7 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: | |||
|   resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" | ||||
|   integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== | ||||
| 
 | ||||
| ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4: | ||||
| ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: | ||||
|   version "6.12.6" | ||||
|   resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" | ||||
|   integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== | ||||
|  | @ -4180,6 +4180,11 @@ dot-prop@^5.2.0: | |||
|   dependencies: | ||||
|     is-obj "^2.0.0" | ||||
| 
 | ||||
| dotenv@^10.0.0: | ||||
|   version "10.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" | ||||
|   integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== | ||||
| 
 | ||||
| duplexer@^0.1.1: | ||||
|   version "0.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" | ||||
|  | @ -7349,6 +7354,15 @@ loader-utils@^1.0.0, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4 | |||
|     emojis-list "^3.0.0" | ||||
|     json5 "^1.0.1" | ||||
| 
 | ||||
| loader-utils@^2.0.0: | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" | ||||
|   integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== | ||||
|   dependencies: | ||||
|     big.js "^5.2.2" | ||||
|     emojis-list "^3.0.0" | ||||
|     json5 "^2.1.2" | ||||
| 
 | ||||
| locate-path@^3.0.0: | ||||
|   version "3.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" | ||||
|  | @ -10446,6 +10460,15 @@ schema-utils@^2.5.0, schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7 | |||
|     ajv "^6.12.4" | ||||
|     ajv-keywords "^3.5.2" | ||||
| 
 | ||||
| schema-utils@^3.0.0: | ||||
|   version "3.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" | ||||
|   integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== | ||||
|   dependencies: | ||||
|     "@types/json-schema" "^7.0.8" | ||||
|     ajv "^6.12.5" | ||||
|     ajv-keywords "^3.5.2" | ||||
| 
 | ||||
| select-hose@^2.0.0: | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" | ||||
|  | @ -10968,6 +10991,14 @@ string-length@^4.0.1: | |||
|     char-regex "^1.0.2" | ||||
|     strip-ansi "^6.0.0" | ||||
| 
 | ||||
| string-replace-loader@2: | ||||
|   version "2.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/string-replace-loader/-/string-replace-loader-2.3.0.tgz#7f29be7d73c94dd92eccd5c5a15651181d7ecd3d" | ||||
|   integrity sha512-HYBIHStViMKLZC/Lehxy42OuwsBaPzX/LjcF5mkJlE2SnHXmW6SW6eiHABTXnY8ZCm/REbdJ8qnA0ptmIzN0Ng== | ||||
|   dependencies: | ||||
|     loader-utils "^1.2.3" | ||||
|     schema-utils "^2.6.5" | ||||
| 
 | ||||
| string-width@^3.0.0, string-width@^3.1.0: | ||||
|   version "3.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" | ||||
|  | @ -11083,6 +11114,14 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: | |||
|   resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" | ||||
|   integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== | ||||
| 
 | ||||
| style-loader@2: | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-2.0.0.tgz#9669602fd4690740eaaec137799a03addbbc393c" | ||||
|   integrity sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ== | ||||
|   dependencies: | ||||
|     loader-utils "^2.0.0" | ||||
|     schema-utils "^3.0.0" | ||||
| 
 | ||||
| style-search@^0.1.0: | ||||
|   version "0.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/style-search/-/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902" | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Dariusz Niemczyk
						Dariusz Niemczyk