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 <[email protected]>
  • Loading branch information
akosyakov committed Oct 15, 2019
1 parent b98c5fb commit deafdb8
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 3 deletions.
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
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ 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', {
Expand Down Expand Up @@ -178,10 +179,15 @@ module.exports = {
to: 'vs/language/html'
}`)}
]),
// it should go after copy-plugin in order to compress monaco as well
new CompressionPlugin({
// enable reuse of compressed artifacts for incremental development
cache: development
}),
new CircularDependencyPlugin({
exclude: /(node_modules|examples)\\/./,
failOnError: false // https://github.com/nodejs/readable-stream/issues/280#issuecomment-297076462
}),
})
],
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();
}

}
Loading

0 comments on commit deafdb8

Please sign in to comment.