Add a .env config and explanation how to use HMR

pull/18318/head
Dariusz Niemczyk 2021-08-01 17:05:33 +02:00 committed by Dariusz Niemczyk
parent b677edbc58
commit a9f3f873a5
No known key found for this signature in database
GPG Key ID: 0AD2F70C94CA5B03
6 changed files with 99 additions and 49 deletions

13
.env.example Normal file
View File

@ -0,0 +1,13 @@
# 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.
# You can load multiple themes at once, but switching between is quite buggy with the hot-reload turned on.
# 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'
# If you want to use multiple themes, define the combinations manually like below:
#MATRIX_THEMES='light,dark'

1
.gitignore vendored
View File

@ -21,3 +21,4 @@ electron/pub
/webpack-stats.json
.vscode
.vscode/
.env

View File

@ -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:

View File

@ -104,6 +104,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#main",

View File

@ -1,5 +1,6 @@
/* eslint-disable quote-props */
const dotenv = require('dotenv');
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
@ -21,24 +22,29 @@ const cssThemes = {
"theme-dark-custom": "./node_modules/matrix-react-sdk/res/themes/dark-custom/css/dark-custom.scss",
};
function getActiveThemes() {
const theme = process.env.MATRIX_THEMES ?? 'light,dark';
const themes = theme.split(',').filter(x => x).map(x => x.trim()).filter(x => x);
return themes;
let dotenvConfig = { parsed: {} };
try {
dotenvConfig = dotenv.config();
} catch (err) {
dotenvConfig = {
parsed: {
CSS_HOT_RELOAD: 0,
MATRIX_THEMES: 'light',
},
};
}
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')};
`;
const CSS_HOT_RELOAD = process.env.CSS_HOT_RELOAD ?? dotenvConfig.CSS_HOT_RELOAD;
const MATRIX_THEMES = process.env.MATRIX_THEMES ?? dotenvConfig.MATRIX_THEMES;
function getActiveThemes() {
// We want to use `light` theme by default if it's not defined.
const theme = MATRIX_THEMES;
const themes = theme.split(',').filter(x => x).map(x => x.trim()).filter(x => x);
if (themes.length > 1) {
throw new Error('Please see `.env.example` for proper hotreload&themes configuation.');
}
return themes;
}
module.exports = (env, argv) => {
@ -57,6 +63,7 @@ module.exports = (env, argv) => {
nodeEnv = "production";
}
const devMode = nodeEnv !== 'production';
const useCssHotReload = CSS_HOT_RELOAD === '1' && devMode;
const development = {};
if (argv.mode === "production") {
@ -73,16 +80,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,
watch: true,
watchOptions: {
aggregateTimeout: 200,
poll: 1000,
ignored: [/node_modules([\\]+|\/)+(?!matrix-react-sdk|matrix-js-sdk)/],
},
node: {
// Mock out the NodeFS module: The opus decoder imports this wrongly.
fs: 'empty',
@ -94,7 +107,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",
...(devMode ? {} : cssThemes),
...(useCssHotReload ? {} : cssThemes),
},
optimization: {
@ -178,7 +191,7 @@ module.exports = (env, argv) => {
/olm[\\/](javascript[\\/])?olm\.js$/,
],
rules: [
devMode && {
useCssHotReload && {
test: /devcss\.ts$/,
loader: 'string-replace-loader',
options: {
@ -217,7 +230,7 @@ module.exports = (env, argv) => {
{
test: /\.css$/,
use: [
devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
@ -271,8 +284,14 @@ module.exports = (env, argv) => {
* of the JS/TS files.
* Should be MUCH better with webpack 5, but we're stuck to this solution for now.
*/
devMode ? {
useCssHotReload ? {
loader: 'style-loader', options: {
/**
* 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.
*/
attributes: {
'data-mx-theme': 'replace_me',
},
@ -430,7 +449,7 @@ module.exports = (env, argv) => {
},
],
},
],
].filter(Boolean),
},
plugins: [

View File

@ -4024,6 +4024,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"