diff --git a/.vscode/launch.json b/.vscode/launch.json index a1d23fdac8795..f7aaac0ea93ef 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,12 +8,13 @@ "type": "node", "request": "launch", "name": "Launch Backend", - "program": "${workspaceRoot}/examples/browser/lib/backend/main.js", + "program": "${workspaceRoot}/examples/browser/src-gen/backend/main.js", "args": [ "--loglevel=debug" ], "sourceMaps": true, "outFiles": [ + "${workspaceRoot}/examples/browser/src-gen/backend/main.js", "${workspaceRoot}/examples/browser/lib/**/*.js", "${workspaceRoot}/examples/browser/node_modules/theia-core/lib/**/*.js" ] @@ -22,13 +23,14 @@ "type": "node", "request": "launch", "name": "Launch Backend (eclipse.jdt.ls)", - "program": "${workspaceRoot}/examples/browser/lib/backend/main.js", + "program": "${workspaceRoot}/examples/browser/src-gen/backend/main.js", "args": [ "--loglevel=debug", "--root-dir=${workspaceRoot}/../eclipse.jdt.ls/org.eclipse.jdt.ls.core" ], "sourceMaps": true, "outFiles": [ + "${workspaceRoot}/examples/browser/src-gen/backend/main.js", "${workspaceRoot}/examples/browser/lib/**/*.js", "${workspaceRoot}/examples/browser/node_modules/theia-core/lib/**/*.js" ] diff --git a/config/webpack/paths.js b/config/webpack/paths.js index 464d2635c8864..a753927d64d1a 100644 --- a/config/webpack/paths.js +++ b/config/webpack/paths.js @@ -3,9 +3,9 @@ const path = require('path'); module.exports = function (dirname) { return { PROJECT_ROOT: path.resolve(dirname, '.'), - SRC: path.resolve(dirname, 'src'), + SRC_GEN: path.resolve(dirname, 'src-gen'), BUILD_ROOT: path.resolve(dirname, 'lib'), - ENTRY: path.resolve(dirname, 'lib/frontend/index.js'), + ENTRY: path.resolve(dirname, 'src-gen/frontend/index.js'), NODE_MODULES: path.resolve(dirname, 'node_modules') }; }; \ No newline at end of file diff --git a/config/webpack/webpack.config.js b/config/webpack/webpack.config.js index bf8bcd1efee8a..f784c78d98e3d 100644 --- a/config/webpack/webpack.config.js +++ b/config/webpack/webpack.config.js @@ -9,14 +9,13 @@ const electronConfiguration = require('./webpack.config.electron'); const webConfiguration = require('./webpack.config.web'); const CopyWebpackPlugin = require('copy-webpack-plugin'); -const monacoEditorPath = './node_modules/monaco-editor-core/dev/vs'; +const monacoEditorPath = './node_modules/monaco-editor-core/min/vs'; const monacoLanguagesPath = './node_modules/monaco-languages/release'; const monacoCssLanguagePath = './node_modules/monaco-css/release/min'; const monacoTsLanguagePath = './node_modules/monaco-typescript/release'; const monacoJsonLanguagePath = './node_modules/monaco-json/release/min'; const monacoHtmlLanguagePath = './node_modules/monaco-html/release/min'; - module.exports = function (dirname, config = {}) { const commonConfiguration = { diff --git a/examples/browser/package.json b/examples/browser/package.json index eb587dc36d7ee..cdffced30ca35 100644 --- a/examples/browser/package.json +++ b/examples/browser/package.json @@ -13,23 +13,18 @@ "bootstrap": "npm install ../../config/local-dependency-manager && npm run localinstall", "clean": "rimraf lib", "prepare": "npm run clean && npm run build", - "build": "npm run build:localdeps && npm run build:app", - "build:app": "npm run build:backend && npm run build:frontend", - "build:backend": "tsc && npm run lint", - "build:frontend": "webpack && cp src-gen/frontend/index.html lib/frontend", + "build": "npm run build:localdeps && npm run build:frontend", + "build:frontend": "webpack && cp src-gen/frontend/index.html lib", "start": "npm run start:app", "start:app": "concurrently --names backend,webpack-server --prefix \"[{name}]\" \"npm run start:backend\" \"npm run start:frontend\"", - "start:backend": "node ./lib/backend/main.js | bunyan", - "start:backend:debug": "node ./lib/backend/main.js --loglevel=debug | bunyan", + "start:backend": "node ./src-gen/backend/main.js | bunyan", + "start:backend:debug": "node ./src-gen/backend/main.js --loglevel=debug | bunyan", "start:frontend": "webpack-dev-server --open", "cold:start": "npm run clean && npm run build && npm start", - "watch": "concurrently --names watch-deps,watch-app --prefix \"[{name}]\" \"npm run watch:localdeps\" \"npm run watch:app\"", - "watch:app": "concurrently --names watch-backend,watch-frontend --prefix \"[{name}]\" \"npm run watch:backend\" \"npm run watch:frontend\"", - "watch:backend": "tsc --watch", + "watch": "concurrently --names watch-deps,watch-frontend --prefix \"[{name}]\" \"npm run watch:localdeps\" \"npm run watch:frontend\"", "watch:frontend": "npm run build:frontend && webpack --watch", "localinstall": "ldm install --dev --original-sources", "build:localdeps": "ldm run build && ldm sync --original-sources", - "lint": "tslint -c ../../config/tslint/tslint.json --project ./tsconfig.json", "watch:localdeps": "ldm watch --sync --run=watch --original-sources", "test:ui": "wdio wdio.conf.js" }, @@ -65,4 +60,4 @@ "localDevDependencies": { "local-dependency-manager": "../../config/local-dependency-manager" } -} +} \ No newline at end of file diff --git a/examples/browser/src-gen/backend/main.js b/examples/browser/src-gen/backend/main.js new file mode 100644 index 0000000000000..9704e743a2925 --- /dev/null +++ b/examples/browser/src-gen/backend/main.js @@ -0,0 +1,42 @@ +/* + * 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 + */ + +// @ts-check +require('reflect-metadata'); +const path = require('path'); +const express = require('express'); +const { Container, injectable } = require('inversify'); + +const { BackendApplication, backendApplicationModule, loggerBackendModule } = require('theia-core/lib/application/node'); +const { messagingBackendModule } = require("theia-core/lib/messaging/node"); + +const fileSystemBackendModule = require("theia-core/lib/filesystem/node/filesystem-backend-module").default; +const workspaceBackendModule = require("theia-core/lib/workspace/node/workspace-backend-module").default; +const terminalBackendModule = require('theia-core/lib/terminal/node/terminal-backend-module').default; +const languagesBackendModule = require('theia-core/lib/languages/node/languages-backend-module').default; +const javaBackendModule = require('theia-core/lib/java/node/java-backend-module').default; +const pythonBackendModule = require('theia-core/lib/python/node/python-backend-module').default; +const cppBackendModule = require('theia-core/lib/cpp/node/cpp-backend-module').default; + +const container = new Container(); +container.load(backendApplicationModule); +container.load(messagingBackendModule); +container.load(loggerBackendModule); + +container.load(fileSystemBackendModule); +container.load(workspaceBackendModule); +container.load(languagesBackendModule); +container.load(terminalBackendModule); +container.load(javaBackendModule); +container.load(pythonBackendModule); +container.load(cppBackendModule); + +const application = container.get(BackendApplication); +application.use(express.static(path.join(__dirname, '../../lib'), { + index: 'index.html' +})); +application.start(); \ No newline at end of file diff --git a/examples/browser/src-gen/backend/main.ts b/examples/browser/src-gen/backend/main.ts deleted file mode 100644 index 1af0cfccaa002..0000000000000 --- a/examples/browser/src-gen/backend/main.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 'reflect-metadata'; -import * as path from 'path'; -import * as express from 'express'; -import { Container, injectable } from 'inversify'; - -import { BackendApplication, BackendApplicationContribution, backendApplicationModule } from 'theia-core/lib/application/node'; -import { messagingBackendModule } from 'theia-core/lib/messaging/node'; -import { loggerBackendModule } from 'theia-core/lib/application/node'; - -import backend_1 from 'theia-core/lib/filesystem/node/filesystem-backend-module'; -import backend_2 from 'theia-core/lib/workspace/node/workspace-backend-module'; -import backend_3 from 'theia-core/lib/terminal/node/terminal-backend-module'; -import backend_4 from 'theia-core/lib/languages/node/languages-backend-module'; -import backend_5 from 'theia-core/lib/java/node/java-backend-module'; -import backend_6 from 'theia-core/lib/python/node/python-backend-module'; -import backend_7 from 'theia-core/lib/cpp/node/cpp-backend-module'; - -@injectable() -class StaticServer implements BackendApplicationContribution { - configure(app: express.Application): void { - app.use(express.static(path.join(__dirname, '..'), { - index: path.join('frontend', 'index.html') - })); - } -} - -const container = new Container(); -container.load(backendApplicationModule); -container.load(messagingBackendModule); -container.load(loggerBackendModule); - -container.load(backend_1); -container.load(backend_2); -container.load(backend_3); -container.load(backend_4); -container.load(backend_5); -container.load(backend_6); -container.load(backend_7); - -container.bind(BackendApplicationContribution).to(StaticServer); -const application = container.get(BackendApplication); -application.start(); \ No newline at end of file diff --git a/examples/browser/src-gen/frontend/index.html b/examples/browser/src-gen/frontend/index.html index 6e26ac106bc52..5893d7984ed9c 100644 --- a/examples/browser/src-gen/frontend/index.html +++ b/examples/browser/src-gen/frontend/index.html @@ -5,8 +5,8 @@ - - + + diff --git a/examples/browser/src-gen/frontend/index.js b/examples/browser/src-gen/frontend/index.js new file mode 100644 index 0000000000000..d70cd1cb70e9d --- /dev/null +++ b/examples/browser/src-gen/frontend/index.js @@ -0,0 +1,42 @@ +/* + * 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 + */ + +// @ts-check +import { Container } from 'inversify'; +import { FrontendApplication, frontendApplicationModule } from 'theia-core/lib/application/browser'; +import { messagingFrontendModule } from 'theia-core/lib/messaging/browser'; +import { loggerFrontendModule } from 'theia-core/lib/application/browser'; + +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(); +} + +import('theia-core/lib/application/browser/menu/browser-menu-module').then(load) + .then(function () { return import('theia-core/lib/application/browser/clipboard/browser-clipboard-module').then(load) }) + .then(function () { return import('theia-core/lib/filesystem/browser/filesystem-frontend-module').then(load) }) + .then(function () { return import('theia-core/lib/workspace/browser/workspace-frontend-module').then(load) }) + .then(function () { return import('theia-core/lib/navigator/browser/navigator-frontend-module').then(load) }) + .then(function () { return import('theia-core/lib/terminal/browser/terminal-frontend-module').then(load) }) + .then(function () { return import('theia-core/lib/editor/browser/editor-frontend-module').then(load) }) + .then(function () { return import('theia-core/lib/monaco/browser/monaco-browser-module').then(load) }) + .then(function () { return import('theia-core/lib/languages/browser/languages-frontend-module').then(load) }) + .then(function () { return import('theia-core/lib/java/browser/java-frontend-module').then(load) }) + .then(function () { return import('theia-core/lib/python/browser/python-frontend-module').then(load) }) + .then(function () { return import('theia-core/lib/cpp/browser/cpp-frontend-module').then(load) }) + .then(start); \ No newline at end of file diff --git a/examples/browser/src-gen/frontend/index.ts b/examples/browser/src-gen/frontend/index.ts deleted file mode 100644 index ec878a276294a..0000000000000 --- a/examples/browser/src-gen/frontend/index.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 - */ - -window.onload = () => { - const w = window; - w.require(["vs/editor/editor.main"], () => { - w.require([ - 'vs/basic-languages/src/monaco.contribution', - 'vs/language/css/monaco.contribution', - 'vs/language/typescript/src/monaco.contribution', - 'vs/language/html/monaco.contribution', - 'vs/language/json/monaco.contribution', - 'vs/platform/commands/common/commands', - 'vs/platform/actions/common/actions', - 'vs/platform/keybinding/common/keybindingsRegistry', - 'vs/platform/keybinding/common/keybindingResolver', - 'vs/base/common/keyCodes', - 'vs/editor/browser/standalone/simpleServices' - ], (basic: any, css: any, ts: any, html: any, json: any, commands: any, actions: any, registry: any, resolver: any, - keyCodes: any, simpleServices: any) => { - - const global: any = self; - global.monaco.commands = commands; - global.monaco.actions = actions; - global.monaco.keybindings = Object.assign(registry, resolver, keyCodes); - global.monaco.services = simpleServices; - require('./main'); - }); - }); -}; \ No newline at end of file diff --git a/examples/browser/src-gen/frontend/main.ts b/examples/browser/src-gen/frontend/main.ts deleted file mode 100644 index e71d6496bacc4..0000000000000 --- a/examples/browser/src-gen/frontend/main.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 { Container } from 'inversify'; -import { FrontendApplication, frontendApplicationModule } from 'theia-core/lib/application/browser'; -import { messagingFrontendModule } from 'theia-core/lib/messaging/browser'; -import { loggerFrontendModule } from 'theia-core/lib/application/browser'; - -import frontend_1 from 'theia-core/lib/application/browser/menu/browser-menu-module'; -import frontend_2 from 'theia-core/lib/application/browser/clipboard/browser-clipboard-module'; -import frontend_3 from 'theia-core/lib/filesystem/browser/filesystem-frontend-module'; -import frontend_4 from 'theia-core/lib/workspace/browser/workspace-frontend-module'; -import frontend_5 from 'theia-core/lib/navigator/browser/navigator-frontend-module'; -import frontend_6 from 'theia-core/lib/editor/browser/editor-frontend-module'; -import frontend_7 from 'theia-core/lib/monaco/browser/monaco-frontend-module'; -import frontend_8 from 'theia-core/lib/terminal/browser/terminal-frontend-module'; -import frontend_9 from 'theia-core/lib/languages/browser/languages-frontend-module'; -import frontend_10 from 'theia-core/lib/java/browser/java-frontend-module'; -import frontend_11 from 'theia-core/lib/python/browser/python-frontend-module'; -import frontend_12 from 'theia-core/lib/cpp/browser/cpp-frontend-module'; - -const container = new Container(); -container.load(frontendApplicationModule); -container.load(messagingFrontendModule); -container.load(loggerFrontendModule); - -container.load(frontend_1); -container.load(frontend_2); -container.load(frontend_3); -container.load(frontend_4); -container.load(frontend_5); -container.load(frontend_6); -container.load(frontend_7); -container.load(frontend_8); -container.load(frontend_9); -container.load(frontend_10); -container.load(frontend_11); -container.load(frontend_12); - -const application = container.get(FrontendApplication); -application.start(); \ No newline at end of file diff --git a/examples/browser/tsconfig.json b/examples/browser/tsconfig.json deleted file mode 100644 index 80907ed61195f..0000000000000 --- a/examples/browser/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compilerOptions": { - "declaration": false, - "noImplicitAny": true, - "noEmitOnError": true, - "noImplicitThis": true, - "noUnusedLocals": true, - "strictNullChecks": true, - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "module": "commonjs", - "moduleResolution": "node", - "target": "es5", - "outDir": "lib", - "lib": [ - "es6", - "dom" - ], - "sourceMap": true - }, - "include": [ - "src-gen" - ] -} diff --git a/examples/electron/package.json b/examples/electron/package.json index 9ea10da7671af..794738b7b72f6 100644 --- a/examples/electron/package.json +++ b/examples/electron/package.json @@ -17,17 +17,13 @@ "clean": "rimraf lib", "postinstall": "electron-rebuild", "prepare": "npm run clean && npm run build", - "build": "npm run build:localdeps && npm run build:app", - "build:app": "npm run build:backend && npm run build:frontend", - "build:backend": "tsc && npm run lint", - "build:frontend": "webpack --target electron && cp src/frontend/index.html lib/frontend", + "build": "npm run build:localdeps && npm run build:frontend", + "build:frontend": "webpack --target electron && cp src-gen/frontend/index.html lib", "build:localdeps": "ldm run build && ldm sync --original-sources", - "lint": "tslint -c ../../config/tslint/tslint.json --project ./tsconfig.json", - "start": "electron ./lib/frontend/electron-main.js | bunyan", - "start:debug": "electron ./lib/frontend/electron-main.js --loglevel=debug | bunyan", + "start": "electron ./src-gen/frontend/electron-main.js | bunyan", + "start:debug": "electron ./src-gen/frontend/electron-main.js --loglevel=debug | bunyan", "cold:start": "npm run clean && npm run build && npm start", - "watch": "concurrently --names watch-deps,watch-backend,watch-frontend --prefix \"[{name}]\" \"npm run watch:localdeps\" \"npm run watch:backend\" \"npm run watch:frontend\"", - "watch:backend": "tsc --watch", + "watch": "concurrently --names watch-deps,watch-frontend --prefix \"[{name}]\" \"npm run watch:localdeps\" \"npm run watch:frontend\"", "watch:frontend": "npm run build:frontend && webpack --watch", "watch:localdeps": "ldm watch --sync --run=watch --original-sources", "test": "electron-mocha --timeout 60000 --require ts-node/register test/**/*.espec.ts", diff --git a/examples/electron/src-gen/backend/main.js b/examples/electron/src-gen/backend/main.js new file mode 100644 index 0000000000000..1c424dfa5d9f5 --- /dev/null +++ b/examples/electron/src-gen/backend/main.js @@ -0,0 +1,42 @@ +/* + * 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 + */ + +// @ts-check +require('reflect-metadata'); +const path = require('path'); +const express = require('express'); +const { Container, injectable } = require("inversify"); + +const { BackendApplication, backendApplicationModule, loggerBackendModule } = require("theia-core/lib/application/node"); +const { messagingBackendModule } = require("theia-core/lib/messaging/node"); + +const fileSystemBackendModule = require("theia-core/lib/filesystem/node/filesystem-backend-module").default; +const workspaceBackendModule = require("theia-core/lib/workspace/node/workspace-backend-module").default; +const terminalBackendModule = require('theia-core/lib/terminal/node/terminal-backend-module').default; +const languagesBackendModule = require('theia-core/lib/languages/node/languages-backend-module').default; +const javaBackendModule = require('theia-core/lib/java/node/java-backend-module').default; +const pythonBackendModule = require('theia-core/lib/python/node/python-backend-module').default; +const cppBackendModule = require('theia-core/lib/cpp/node/cpp-backend-module').default; + +const container = new Container(); +container.load(backendApplicationModule); +container.load(messagingBackendModule); +container.load(loggerBackendModule); + +container.load(fileSystemBackendModule); +container.load(workspaceBackendModule); +container.load(languagesBackendModule); +container.load(terminalBackendModule); +container.load(javaBackendModule); +container.load(pythonBackendModule); +container.load(cppBackendModule); + +const application = container.get(BackendApplication); +application.use(express.static(path.join(__dirname, '../../lib'), { + index: 'index.html' +})); +application.start(); diff --git a/examples/electron/src/frontend/electron-main.ts b/examples/electron/src-gen/frontend/electron-main.js similarity index 71% rename from examples/electron/src/frontend/electron-main.ts rename to examples/electron/src-gen/frontend/electron-main.js index e95e0807510e8..4cb5fb4b52cfb 100644 --- a/examples/electron/src/frontend/electron-main.ts +++ b/examples/electron/src-gen/frontend/electron-main.js @@ -5,6 +5,8 @@ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 */ +// @ts-check + // 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 @@ -14,23 +16,24 @@ if (process.env.LC_ALL) { } process.env.LC_NUMERIC = 'C'; -import * as electron from 'electron'; -import * as path from 'path'; +const electron = require('electron'); +const path = require('path'); -let mainWindow: Electron.BrowserWindow | undefined = undefined; +let mainWindow = undefined; -electron.app.on('window-all-closed', () => { +electron.app.on('window-all-closed', function () { if (process.platform !== 'darwin') { electron.app.quit(); } }); -electron.app.on('ready', () => { - require("../backend/main"); // start the express server +electron.app.on('ready', function () { + // start the express server + require("../backend/main"); mainWindow = new electron.BrowserWindow({ width: 1024, height: 728 }); mainWindow.webContents.openDevTools(); - mainWindow.loadURL(`file://${path.join(__dirname, 'index.html')}`); - mainWindow.on('closed', () => { + mainWindow.loadURL(`file://${path.join(__dirname, '../../lib/index.html')}`); + mainWindow.on('closed', function () { mainWindow = undefined; }); }); \ No newline at end of file diff --git a/examples/electron/src-gen/frontend/index.html b/examples/electron/src-gen/frontend/index.html new file mode 100644 index 0000000000000..6301020868a5b --- /dev/null +++ b/examples/electron/src-gen/frontend/index.html @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/electron/src-gen/frontend/index.js b/examples/electron/src-gen/frontend/index.js new file mode 100644 index 0000000000000..20310ad0efece --- /dev/null +++ b/examples/electron/src-gen/frontend/index.js @@ -0,0 +1,42 @@ +/* + * 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 + */ + +// @ts-check +import { Container } from 'inversify'; +import { FrontendApplication, frontendApplicationModule } from 'theia-core/lib/application/browser'; +import { messagingFrontendModule } from 'theia-core/lib/messaging/browser'; +import { loggerFrontendModule } from 'theia-core/lib/application/browser'; + +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(); +} + +import('theia-core/lib/application/electron-browser/menu/electron-menu-module').then(load) + .then(function () { return import('theia-core/lib/application/electron-browser/clipboard/electron-clipboard-module').then(load) }) + .then(function () { return import('theia-core/lib/filesystem/browser/filesystem-frontend-module').then(load) }) + .then(function () { return import('theia-core/lib/workspace/browser/workspace-frontend-module').then(load) }) + .then(function () { return import('theia-core/lib/navigator/browser/navigator-frontend-module').then(load) }) + .then(function () { return import('theia-core/lib/terminal/browser/terminal-frontend-module').then(load) }) + .then(function () { return import('theia-core/lib/editor/browser/editor-frontend-module').then(load) }) + .then(function () { return import('theia-core/lib/monaco/electron-browser/monaco-electron-module').then(load) }) + .then(function () { return import('theia-core/lib/languages/browser/languages-frontend-module').then(load) }) + .then(function () { return import('theia-core/lib/java/browser/java-frontend-module').then(load) }) + .then(function () { return import('theia-core/lib/python/browser/python-frontend-module').then(load) }) + .then(function () { return import('theia-core/lib/cpp/browser/cpp-frontend-module').then(load) }) + .then(start); \ No newline at end of file diff --git a/examples/electron/src/backend/main.ts b/examples/electron/src/backend/main.ts deleted file mode 100644 index a528db1b1881d..0000000000000 --- a/examples/electron/src/backend/main.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 'reflect-metadata'; -import * as path from 'path'; -import * as express from 'express'; -import { Container, injectable } from "inversify"; - -import { BackendApplication, BackendApplicationContribution, backendApplicationModule } from "theia-core/lib/application/node"; -import { messagingBackendModule } from "theia-core/lib/messaging/node"; -import { loggerBackendModule } from 'theia-core/lib/application/node'; - -import fileSystemBackendModule from "theia-core/lib/filesystem/node/filesystem-backend-module"; -import workspaceBackendModule from "theia-core/lib/workspace/node/workspace-backend-module"; -import terminalBackendModule from 'theia-core/lib/terminal/node/terminal-backend-module'; -import languagesBackendModule from 'theia-core/lib/languages/node/languages-backend-module'; -import javaBackendModule from 'theia-core/lib/java/node/java-backend-module'; -import pythonBackendModule from 'theia-core/lib/python/node/python-backend-module'; -import cppBackendModule from 'theia-core/lib/cpp/node/cpp-backend-module'; - -@injectable() -class StaticServer implements BackendApplicationContribution { - configure(app: express.Application): void { - app.use(express.static(path.join(__dirname, '..'), { - index: path.join('frontend', 'index.html') - })); - } -} - -const container = new Container(); -container.load(backendApplicationModule); -container.load(messagingBackendModule); -container.load(loggerBackendModule); - -container.load(fileSystemBackendModule); -container.load(workspaceBackendModule); -container.load(languagesBackendModule); -container.load(terminalBackendModule); -container.load(javaBackendModule); -container.load(pythonBackendModule); -container.load(cppBackendModule); - -container.bind(BackendApplicationContribution).to(StaticServer); -const application = container.get(BackendApplication); -application.start(); diff --git a/examples/electron/src/frontend/index.html b/examples/electron/src/frontend/index.html deleted file mode 100644 index da172b28ec5fd..0000000000000 --- a/examples/electron/src/frontend/index.html +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/electron/src/frontend/index.ts b/examples/electron/src/frontend/index.ts deleted file mode 100644 index e2399eb1cd859..0000000000000 --- a/examples/electron/src/frontend/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * 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 - */ - -require('./main'); \ No newline at end of file diff --git a/examples/electron/src/frontend/main.ts b/examples/electron/src/frontend/main.ts deleted file mode 100644 index 4b21d4e3d639f..0000000000000 --- a/examples/electron/src/frontend/main.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 { Container } from 'inversify'; -import { FrontendApplication, frontendApplicationModule } from 'theia-core/lib/application/browser'; -import { messagingFrontendModule } from 'theia-core/lib/messaging/browser'; -import { loggerFrontendModule } from 'theia-core/lib/application/browser'; - -import electronMenuModule from 'theia-core/lib/application/electron-browser/menu/electron-menu-module'; -import electronClipboardModule from 'theia-core/lib/application/electron-browser/clipboard/electron-clipboard-module'; -import fileSystemFrontendModule from 'theia-core/lib/filesystem/browser/filesystem-frontend-module'; -import workspaceFrontendModule from 'theia-core/lib/workspace/browser/workspace-frontend-module'; -import navigatorFrontendModule from 'theia-core/lib/navigator/browser/navigator-frontend-module'; -import editorFrontendModule from 'theia-core/lib/editor/browser/editor-frontend-module'; -import monacoFrontendModule from 'theia-core/lib/monaco/browser/monaco-frontend-module'; -import terminalFrontendModule from 'theia-core/lib/terminal/browser/terminal-frontend-module'; -import languagesFrontendModule from 'theia-core/lib/languages/browser/languages-frontend-module'; -import javaFrontendModule from 'theia-core/lib/java/browser/java-frontend-module'; -import pythonFrontendModule from 'theia-core/lib/python/browser/python-frontend-module'; -import cppFrontendModule from 'theia-core/lib/cpp/browser/cpp-frontend-module'; - -const container = new Container(); -container.load(frontendApplicationModule); -container.load(messagingFrontendModule); -container.load(loggerFrontendModule); - -container.load(electronMenuModule); -container.load(electronClipboardModule); -container.load(fileSystemFrontendModule); -container.load(workspaceFrontendModule); -container.load(navigatorFrontendModule); -container.load(editorFrontendModule); -container.load(monacoFrontendModule); -container.load(terminalFrontendModule); -container.load(languagesFrontendModule); -container.load(javaFrontendModule); -container.load(pythonFrontendModule); -container.load(cppFrontendModule); - -const application = container.get(FrontendApplication); -application.start(); \ No newline at end of file diff --git a/examples/electron/tsconfig.json b/examples/electron/tsconfig.json deleted file mode 100644 index 2fdd135835bcf..0000000000000 --- a/examples/electron/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compilerOptions": { - "declaration": false, - "noImplicitAny": true, - "noEmitOnError": true, - "noImplicitThis": true, - "noUnusedLocals": true, - "strictNullChecks": true, - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "module": "commonjs", - "moduleResolution": "node", - "target": "es5", - "outDir": "lib", - "lib": [ - "es6", - "dom" - ], - "sourceMap": true - }, - "include": [ - "src" - ] -} \ No newline at end of file diff --git a/package.json b/package.json index d25eb4637e244..4958020fc8e7f 100644 --- a/package.json +++ b/package.json @@ -133,14 +133,15 @@ "frontend": "lib/navigator/browser/navigator-frontend-module" }, { - "frontend": "lib/editor/browser/editor-frontend-module" + "frontend": "lib/terminal/browser/terminal-frontend-module", + "backend": "lib/terminal/node/terminal-backend-module" }, { - "frontend": "lib/monaco/browser/monaco-frontend-module" + "frontend": "lib/editor/browser/editor-frontend-module" }, { - "frontend": "lib/terminal/browser/terminal-frontend-module", - "backend": "lib/terminal/node/terminal-backend-module" + "frontend": "lib/monaco/browser/monaco-browser-module", + "frontendElectron": "lib/monaco/electron-browser/monaco-electron-module" }, { "frontend": "lib/languages/browser/languages-frontend-module", diff --git a/src/application/node/backend-application.ts b/src/application/node/backend-application.ts index 31dde3212e8fb..db6ffed055f9c 100644 --- a/src/application/node/backend-application.ts +++ b/src/application/node/backend-application.ts @@ -22,7 +22,7 @@ export interface BackendApplicationContribution { @injectable() export class BackendApplication { - protected app: express.Application; + protected readonly app: express.Application = express(); constructor( @inject(ContributionProvider) @named(BackendApplicationContribution) @@ -35,22 +35,24 @@ export class BackendApplication { logger.error(error.stack); } }); + for (const contribution of this.contributionsProvider.getContributions()) { + if (contribution.configure) { + contribution.configure(this.app); + } + } + } + + use(...handlers: express.Handler[]): void { + this.app.use(...handlers); } start(port: number = 3000): Promise { - const contributions = this.contributionsProvider.getContributions() - this.app = express(); - for (const contrib of contributions) { - if (contrib.configure) { - contrib.configure(this.app); - } - } return new Promise(resolve => { const server = this.app.listen(port, () => { this.logger.info(`Theia app listening on port ${port}.`); resolve(); }); - for (const contrib of contributions) { + for (const contrib of this.contributionsProvider.getContributions()) { if (contrib.onStart) { contrib.onStart(server); } diff --git a/src/monaco/browser/monaco-browser-module.ts b/src/monaco/browser/monaco-browser-module.ts new file mode 100644 index 0000000000000..1b6ad63457e78 --- /dev/null +++ b/src/monaco/browser/monaco-browser-module.ts @@ -0,0 +1,19 @@ +/* + * 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 { ContainerModule } from "inversify"; +import { loadMonaco } from "./monaco-loader"; + +export { ContainerModule }; + +const amdRequire = (window).require; +export default loadMonaco(amdRequire) + .then(() => + import('./monaco-frontend-module') + ).then(module => + module.default + ); \ No newline at end of file diff --git a/src/monaco/browser/monaco-loader.ts b/src/monaco/browser/monaco-loader.ts new file mode 100644 index 0000000000000..03bca342dd88e --- /dev/null +++ b/src/monaco/browser/monaco-loader.ts @@ -0,0 +1,34 @@ +/* + * 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 + */ + +export function loadMonaco(vsRequire: any): Promise { + return new Promise(resolve => { + vsRequire(["vs/editor/editor.main"], () => { + vsRequire([ + 'vs/basic-languages/src/monaco.contribution', + 'vs/language/css/monaco.contribution', + 'vs/language/typescript/src/monaco.contribution', + 'vs/language/html/monaco.contribution', + 'vs/language/json/monaco.contribution', + 'vs/platform/commands/common/commands', + 'vs/platform/actions/common/actions', + 'vs/platform/keybinding/common/keybindingsRegistry', + 'vs/platform/keybinding/common/keybindingResolver', + 'vs/base/common/keyCodes', + 'vs/editor/browser/standalone/simpleServices' + ], (basic: any, css: any, ts: any, html: any, json: any, commands: any, actions: any, registry: any, resolver: any, + keyCodes: any, simpleServices: any) => { + const global: any = self; + global.monaco.commands = commands; + global.monaco.actions = actions; + global.monaco.keybindings = Object.assign(registry, resolver, keyCodes); + global.monaco.services = simpleServices; + resolve(); + }); + }); + }); +}; \ No newline at end of file diff --git a/src/monaco/electron-browser/monaco-electron-module.ts b/src/monaco/electron-browser/monaco-electron-module.ts new file mode 100644 index 0000000000000..c8692ba52cdd6 --- /dev/null +++ b/src/monaco/electron-browser/monaco-electron-module.ts @@ -0,0 +1,48 @@ +/* + * 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 { ContainerModule } from "inversify"; +import { loadMonaco } from "../browser/monaco-loader"; +import { FileUri } from "../../application/node/file-uri"; + +export { ContainerModule }; + +const g = global; +const s = self; + +// Monaco uses a custom amd loader that over-rides node's require. +// Keep a reference to node's require so we can restore it after executing the amd loader file. +const nodeRequire = g.require; + +const loadAmdRequire = new Promise(resolve => { + const vsLoader = document.createElement('script'); + vsLoader.type = 'text/javascript'; + vsLoader.src = './vs/loader.js'; + vsLoader.charset = 'utf-8'; + vsLoader.addEventListener('load', () => { + // Save Monaco's amd require and restore Node's require + const amdRequire = g.require; + g.require = nodeRequire; + + const baseUrl = FileUri.create(__dirname).toString(); + amdRequire.config({ baseUrl }); + + // workaround monaco-css not understanding the environment + s.module = undefined; + + // workaround monaco-typescript not understanding the environment + s.process.browser = true; + + resolve(amdRequire); + }); + document.body.appendChild(vsLoader); +}); + +export default loadAmdRequire + .then(amdRequire => loadMonaco(amdRequire)) + .then(() => import('../browser/monaco-frontend-module')) + .then(module => module.default); \ No newline at end of file