-
Notifications
You must be signed in to change notification settings - Fork 2.5k
/
Copy pathfrontend-generator.ts
134 lines (119 loc) · 5.04 KB
/
frontend-generator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
* Copyright (C) 2017 TypeFox and others.
*
* 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
*/
import { AbstractGenerator } from "./abstract-generator";
export class FrontendGenerator extends AbstractGenerator {
async generate(): Promise<void> {
const frontendModules = this.pck.targetFrontendModules;
await this.write(this.pck.frontend('index.html'), this.compileIndexHtml(frontendModules));
await this.write(this.pck.frontend('index.js'), this.compileIndexJs(frontendModules));
if (this.pck.isElectron()) {
await this.write(this.pck.frontend('electron-main.js'), this.compileElectronMain());
}
}
protected compileIndexHtml(frontendModules: Map<string, string>): string {
return `<!DOCTYPE html>
<html>
<head>${this.compileIndexHead(frontendModules)}${this.ifBrowser(`
<script type="text/javascript" src="./require.js" charset="utf-8"></script>`)}
<script type="text/javascript" src="./bundle.js" charset="utf-8"></script>
</head>
<body>
</body>
</html>`;
}
protected compileIndexHead(frontendModules: Map<string, string>): string {
return `
<meta charset="UTF-8">
<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<script type="text/javascript" src="https://www.promisejs.org/polyfills/promise-6.1.0.js" charset="utf-8"></script>`
}
protected compileIndexJs(frontendModules: Map<string, string>): string {
return `// @ts-check
require('reflect-metadata');
const { Container } = require('inversify');
const { FrontendApplication } = require('@theia/core/lib/browser');
const { frontendApplicationModule } = require('@theia/core/lib/browser/frontend-application-module');
const { messagingFrontendModule } = require('@theia/core/lib/browser/messaging/messaging-frontend-module');
const { loggerFrontendModule } = require('@theia/core/lib/browser/logger-frontend-module');
const container = new Container();
container.load(frontendApplicationModule);
container.load(messagingFrontendModule);
container.load(loggerFrontendModule);
function load(raw) {
return Promise.resolve(raw.default).then(module =>
container.load(module)
)
}
function start() {
const application = container.get(FrontendApplication);
application.start();
}
module.exports = Promise.resolve()${this.compileFrontendModuleImports(frontendModules)}
.then(start).catch(reason => {
console.error('Failed to start the frontend application.');
if (reason) {
console.error(reason);
}
});`;
}
protected compileElectronMain(): string {
return `// @ts-check
const cluster = require('cluster');
if (cluster.isMaster) {
// Workaround for https://github.com/electron/electron/issues/9225. Chrome has an issue where
// in certain locales (e.g. PL), image metrics are wrongly computed. We explicitly set the
// LC_NUMERIC to prevent this from happening (selects the numeric formatting category of the
// C locale, http://en.cppreference.com/w/cpp/locale/LC_categories).
if (process.env.LC_ALL) {
process.env.LC_ALL = 'C';
}
process.env.LC_NUMERIC = 'C';
const electron = require('electron');
electron.app.on('window-all-closed', function () {
if (process.platform !== 'darwin') {
electron.app.quit();
}
});
electron.app.on('ready', function () {
const path = require('path');
const { fork } = require('child_process');
// Check whether we are in bundled application or development mode.
const devMode = process.defaultApp || /node_modules[\\/]electron[\\/]/.test(process.execPath);
const mainWindow = new electron.BrowserWindow({ width: 1024, height: 728 });
const mainPath = path.join(__dirname, '..', 'backend', 'main');
const loadMainWindow = function(port) {
mainWindow.loadURL(\`file://\${path.join(__dirname, '../../lib/index.html')}?port=\${port}\`);
};
// We need to distinguish between bundled application and development mode when starting the clusters.
// https://github.com/electron/electron/issues/6337#issuecomment-230183287
if (devMode) {
require(mainPath).then(address => {
loadMainWindow(address.port);
}).catch((error) => {
console.error(error);
electron.app.exit(1);
});
} else {
const cp = fork(mainPath, process.argv, { stdio: [0, 1, 2, 'ipc'] });
cp.on('message', function (message) {
loadMainWindow(message);
});
cp.on('error', function (error) {
console.error(error);
electron.app.exit(1);
});
}
mainWindow.on('closed', function () {
electron.app.exit(0);
});
});
} else {
require('../backend/main');
}
`;
}
}