Skip to content

Commit

Permalink
fix #4285: statically compress webpack artifacts
Browse files Browse the repository at this point in the history
Signed-off-by: Anton Kosiakov <anton.kosyakov@typefox.io>
  • Loading branch information
akosyakov committed Oct 15, 2019
1 parent b98c5fb commit df42f06
Show file tree
Hide file tree
Showing 7 changed files with 259 additions and 24 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## v0.12.0

- [cli] enable static compression of build artifacts [#6266](https://github.com/eclipse-theia/theia/pull/6266)
- to disable pass `--no-static-compression` to `theia build` or `theia watch`.

Breaking changes:

- [plugin] don't block web socket with many plugins [6252](https://github.com/eclipse-theia/theia/pull/6252)
Expand All @@ -15,7 +18,7 @@ Breaking changes:
- `PluginDeployerHandler.getPluginMetadata` is replaced with `PluginDeployerHandler.getPluginDependencies` to access plugin dependencies.
- `HostedPluginServer.getDeployedMetadata` is replaced with `HostedPluginServer.getDeployedPluginIds` and `HostedPluginServer.getDeployedPlugins`
to fetch first only ids of deployed plugins and then deployed metadata for only yet not loaded plugins.
- `HostedPluginDeployerHandler.getDeployedFrontendMetadata` and `HostedPluginDeployerHandler.getDeployedBackendMetadata` are replaced with
- `HostedPluginDeployerHandler.getDeployedFrontendMetadata` and `HostedPluginDeployerHandler.getDeployedBackendMetadata` are replaced with
`HostedPluginDeployerHandler.getDeployedFrontendPluginIds`, `HostedPluginDeployerHandlergetDeployedBackendPluginIds` and `HostedPluginDeployerHandler.getDeployedPlugin` to featch first only ids and then deplyoed metadata fro only yet not loaded plugins.
- `PluginHost.init` can initialize plugins asynchronous, synchronous initialization is still supported.
- `HostedPluginReader.doGetPluginMetadata` is renamed to `HostedPluginReader.getPluginMetadata`.
Expand Down
1 change: 1 addition & 0 deletions dev-packages/application-manager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"babel-loader": "^8.0.6",
"bunyan": "^1.8.10",
"circular-dependency-plugin": "^5.0.0",
"@theia/compression-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^4.5.0",
"css-loader": "^0.28.1",
"electron-rebuild": "^1.8.6",
Expand Down
54 changes: 33 additions & 21 deletions dev-packages/application-manager/src/generator/webpack-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,50 @@ const webpack = require('webpack');
const yargs = require('yargs');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CircularDependencyPlugin = require('circular-dependency-plugin');
const CompressionPlugin = require('@theia/compression-webpack-plugin')
const outputPath = path.resolve(__dirname, 'lib');
const { mode } = yargs.option('mode', {
const { mode, staticCompression } = yargs.option('mode', {
description: "Mode to use",
choices: ["development", "production"],
default: "production"
}).option('static-compression', {
description: 'Controls whether to enable compression of static artifacts.',
type: 'boolean',
default: true
}).argv;
const development = mode === 'development';${this.ifMonaco(() => `
const monacoEditorCorePath = development ? '${this.resolve('@typefox/monaco-editor-core', 'dev/vs')}' : '${this.resolve('@typefox/monaco-editor-core', 'min/vs')}';
const monacoCssLanguagePath = '${this.resolve('monaco-css', 'release/min')}';
const monacoHtmlLanguagePath = '${this.resolve('monaco-html', 'release/min')}';`)}
const plugins = [new CopyWebpackPlugin([${this.ifMonaco(() => `
{
from: monacoEditorCorePath,
to: 'vs'
},
{
from: monacoCssLanguagePath,
to: 'vs/language/css'
},
{
from: monacoHtmlLanguagePath,
to: 'vs/language/html'
}`)}
])];
// it should go after copy-plugin in order to compress monaco as well
if (staticCompression) {
plugins.push(new CompressionPlugin({
// enable reuse of compressed artifacts for incremental development
cache: development
}));
}
plugins.push(new CircularDependencyPlugin({
exclude: /(node_modules|examples)\\/./,
failOnError: false // https://github.com/nodejs/readable-stream/issues/280#issuecomment-297076462
}));
module.exports = {
entry: path.resolve(__dirname, 'src-gen/frontend/index.js'),
output: {
Expand Down Expand Up @@ -163,26 +194,7 @@ module.exports = {
}`)}
},
devtool: 'source-map',
plugins: [
new CopyWebpackPlugin([${this.ifMonaco(() => `
{
from: monacoEditorCorePath,
to: 'vs'
},
{
from: monacoCssLanguagePath,
to: 'vs/language/css'
},
{
from: monacoHtmlLanguagePath,
to: 'vs/language/html'
}`)}
]),
new CircularDependencyPlugin({
exclude: /(node_modules|examples)\\/./,
failOnError: false // https://github.com/nodejs/readable-stream/issues/280#issuecomment-297076462
}),
],
plugins,
stats: {
warnings: true
}
Expand Down
36 changes: 35 additions & 1 deletion packages/core/src/node/backend-application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,19 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import * as path from 'path';
import * as http from 'http';
import * as https from 'https';
import * as express from 'express';
import * as yargs from 'yargs';
import * as fs from 'fs-extra';
import { inject, named, injectable } from 'inversify';
import { inject, named, injectable, postConstruct } from 'inversify';
import { ILogger, ContributionProvider, MaybePromise } from '../common';
import { CliContribution } from './cli';
import { Deferred } from '../common/promise-util';
import { environment } from '../common/index';
import { AddressInfo } from 'net';
import { ApplicationPackage } from '@theia/application-package';

export const BackendApplicationContribution = Symbol('BackendApplicationContribution');
export interface BackendApplicationContribution {
Expand Down Expand Up @@ -93,6 +95,9 @@ export class BackendApplication {

protected readonly app: express.Application = express();

@inject(ApplicationPackage)
protected readonly applicationPackage: ApplicationPackage;

constructor(
@inject(ContributionProvider) @named(BackendApplicationContribution)
protected readonly contributionsProvider: ContributionProvider<BackendApplicationContribution>,
Expand Down Expand Up @@ -124,6 +129,17 @@ export class BackendApplication {
}
}
}
}

@postConstruct()
protected init(): void {
this.app.get('*.js', this.serveGzipped.bind(this, 'text/javascript'));
this.app.get('*.js.map', this.serveGzipped.bind(this, 'application/json'));
this.app.get('*.css', this.serveGzipped.bind(this, 'text/css'));
this.app.get('*.wasm', this.serveGzipped.bind(this, 'application/wasm'));
this.app.get('*.gif', this.serveGzipped.bind(this, 'image/gif'));
this.app.get('*.png', this.serveGzipped.bind(this, 'image/png'));
this.app.get('*.svg', this.serveGzipped.bind(this, 'image/svg+xml'));

for (const contribution of this.contributionsProvider.getContributions()) {
if (contribution.configure) {
Expand Down Expand Up @@ -217,4 +233,22 @@ export class BackendApplication {
}
}

protected async serveGzipped(contentType: string, req: express.Request, res: express.Response, next: express.NextFunction): Promise<void> {
const acceptedEncodings = req.acceptsEncodings();

const gzUrl = `${req.url}.gz`;
const gzPath = path.join(this.applicationPackage.projectPath, 'lib', gzUrl);
if (acceptedEncodings.indexOf('gzip') === -1 || !(await fs.pathExists(gzPath))) {
next();
return;
}

req.url = gzUrl;

res.set('Content-Encoding', 'gzip');
res.set('Content-Type', contentType);

next();
}

}
4 changes: 4 additions & 0 deletions packages/task/src/node/test/task-test-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,15 @@ import taskBackendModule from '../task-backend-module';
import filesystemBackendModule from '@theia/filesystem/lib/node/filesystem-backend-module';
import workspaceServer from '@theia/workspace/lib/node/workspace-backend-module';
import { messagingBackendModule } from '@theia/core/lib/node/messaging/messaging-backend-module';
// tslint:disable-next-line:no-implicit-dependencies
import { ApplicationPackage } from '@theia/application-package/lib/application-package';

export function createTaskTestContainer(): Container {
const testContainer = new Container();

testContainer.load(backendApplicationModule);
testContainer.rebind(ApplicationPackage).toConstantValue({} as ApplicationPackage);

bindLogger(testContainer.bind.bind(testContainer));
testContainer.load(messagingBackendModule);
testContainer.load(processBackendModule);
Expand Down
5 changes: 5 additions & 0 deletions packages/terminal/src/node/test/terminal-test-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ import { backendApplicationModule } from '@theia/core/lib/node/backend-applicati
import processBackendModule from '@theia/process/lib/node/process-backend-module';
import { messagingBackendModule } from '@theia/core/lib/node/messaging/messaging-backend-module';
import terminalBackendModule from '../terminal-backend-module';
// tslint:disable-next-line:no-implicit-dependencies
import { ApplicationPackage } from '@theia/application-package/lib/application-package';

export function createTerminalTestContainer(): Container {
const container = new Container();

container.load(backendApplicationModule);
container.rebind(ApplicationPackage).toConstantValue({} as ApplicationPackage);

bindLogger(container.bind.bind(container));
container.load(messagingBackendModule);
container.load(processBackendModule);
Expand Down
Loading

0 comments on commit df42f06

Please sign in to comment.