Can I embed IDE running on browser to any where in an existing html page?

[original thread by satya-dash]

Please see: https://github.com/theia-ide/theia/issues/1045 Looks like someone manages to do so

[satya-dash]

Thanks @anton-kosyakov . Will try and if it doesn’t work then will bother you again.

My response is the second comment. I was surprised that it works somehow. It is more feature request to me.

[satya-dash]

@anton-kosyakov The application runs well but do you know how to add the other functionalities (like monaco, debugger, etc.) in that ?

It should be there if you install corresponding extensions, like @theia/monaco, @theia/debug and so on

[satya-dash]

I tried adding @theia/monaco but after that when I load the module in the container it is throwing errors.

// import the monaco module
import monacoModule from '@theia/monaco/lib/browser/monaco-frontend-module';

// adding into the container
container.load(monacoModule);

So I believe there are lot of dependency on monaco. So how can i know which are the dependencies so that I can import them as well in my package.json file.

What kind of errors?

extensions should be self-contained

[satya-dash]

Uncaught Error: Cannot find module ‘vscode’

[satya-dash]

[satya-dash]

and in the terminal it is coming

ERROR in ./node_modules/onigasm/lib/onigasm.wasm
WebAssembly module is included in initial chunk.
This is not allowed, because WebAssembly download and compilation must happen asynchronous.
Add an async splitpoint (i. e. import()) somewhere between your entrypoint and the WebAssembly module:
* multi (webpack)-dev-server/client?http://localhost:8080 ./src --> ./src/index.ts --> ./src/app.ts --> ./node_modules/@theia/monaco/lib/browser/monaco-frontend-module.js --> ./node_modules/@theia/monaco/lib/browser/textmate/monaco-textmate-frontend-bindings.js --> ./node_modules/onigasm/lib/onigasm.wasm

wow

Is there a way to debug it somewhere?

do you have a custom webpack config?

[satya-dash]

I got the point i guess. I need to do that with promise. I will try and let you know if that is working or not.

[satya-dash]

Yes I try to replicate the webpack configuration as per need basis. Do you want me to post it here ?

you should not replicate webpack config, but use the original and mixin yours, otherwise it won’t work, there are a lot of assumptions

here is an example how to add custom bits to default configuration: https://github.com/theia-ide/theia/issues/766#issuecomment-341720642

[satya-dash]

Please have a look at the way I did it and comment on it.

// index.ts
import { runApplicationNew } from "./app";

const element = document.getElementById("react-container");
if (element != null) {
  runApplicationNew(element);
}

//app.ts
import 'reflect-metadata';
import { FrontendApplication } from '@theia/core/lib/browser';
import { Container, ContainerModule } from 'inversify';
import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
import { frontendApplicationModule } from '@theia/core/lib/browser/frontend-application-module';
import { messagingFrontendModule } from '@theia/core/lib/browser/messaging/messaging-frontend-module';
import { loggerFrontendModule } from '@theia/core/lib/browser/logger-frontend-module';
import browserMenuModule from '@theia/core/lib/browser/menu/browser-menu-module';

import { ThemeService } from '@theia/core/lib/browser/theming';

import "./index.css";

const getFrontendModule = (host: HTMLElement) => new ContainerModule((_bind, _unbind, _isBound, rebind) => {
  class MyFrontendApplication extends FrontendApplication {
    protected getHost(): Promise<HTMLElement> {
      return Promise.resolve(host);
    }
  }

  rebind(FrontendApplication).to(MyFrontendApplication).inSingletonScope();
});

export const runApplicationNew = (appElement: HTMLElement) => {
  FrontendApplicationConfigProvider.set({
    applicationName: "Theia"
  });

  const container = new Container();
  container.load(frontendApplicationModule);
  container.load(messagingFrontendModule);
  container.load(loggerFrontendModule);
  container.load(getFrontendModule(appElement));


  function load(raw: { default: any; }) {
    return Promise.resolve(raw.default).then(module =>
        container.load(module)
    )
  }

  function start() {
    const themeService = ThemeService.get();
    themeService.loadUserTheme();

    const application = container.get(FrontendApplication);
    application.start();
  }

  Promise.resolve()
  .then(function () { return import('@theia/core/lib/browser/menu/browser-menu-module').then(load) })
  .then(function () { return import('@theia/core/lib/browser/window/browser-window-module').then(load) })
  .then(function () { return import('@theia/core/lib/browser/keyboard/browser-keyboard-module').then(load) })
  .then(function () { return import('@theia/output/lib/browser/output-frontend-module').then(load) })
  .then(function () { return import('@theia/filesystem/lib/browser/filesystem-frontend-module').then(load) })
  .then(function () { return import('@theia/filesystem/lib/browser/download/file-download-frontend-module').then(load) })
  .then(function () { return import('@theia/filesystem/lib/browser/file-dialog/file-dialog-module').then(load) })
  .then(function () { return import('@theia/variable-resolver/lib/browser/variable-resolver-frontend-module').then(load) })
  .then(function () { return import('@theia/workspace/lib/browser/workspace-frontend-module').then(load) })
  .then(function () { return import('@theia/languages/lib/browser/languages-frontend-module').then(load) })
  .then(function () { return import('@theia/editor/lib/browser/editor-frontend-module').then(load) })
  .then(function () { return import('@theia/navigator/lib/browser/navigator-frontend-module').then(load) })
  .then(function () { return import('@theia/markers/lib/browser/problem/problem-frontend-module').then(load) })
  .then(function () { return import('@theia/outline-view/lib/browser/outline-view-frontend-module').then(load) })
  .then(function () { return import('@theia/monaco/lib/browser/monaco-browser-module').then(load) })
  // .then(function () { return import('@theia/callhierarchy/lib/browser/callhierarchy-frontend-module').then(load) })
  .then(function () { return import('@theia/console/lib/browser/console-frontend-module').then(load) })
  .then(function () { return import('@theia/json/lib/browser/json-frontend-module').then(load) })
  .then(function () { return import('@theia/userstorage/lib/browser/user-storage-frontend-module').then(load) })
  .then(function () { return import('@theia/preferences/lib/browser/preference-frontend-module').then(load) })
  .then(function () { return import('@theia/terminal/lib/browser/terminal-frontend-module').then(load) })
  .then(function () { return import('@theia/task/lib/browser/task-frontend-module').then(load) })
  // .then(function () { return import('@theia/cpp/lib/browser/cpp-frontend-module').then(load) })
  .then(function () { return import('@theia/debug/lib/browser/debug-frontend-module').then(load) })
  // .then(function () { return import('@theia/editor-preview/lib/browser/editor-preview-frontend-module').then(load) })
  // .then(function () { return import('@theia/editorconfig/lib/browser/editorconfig-frontend-module').then(load) })
  .then(function () { return import('@theia/file-search/lib/browser/file-search-frontend-module').then(load) })
  .then(function () { return import('@theia/keymaps/lib/browser/keymaps-frontend-module').then(load) })
  .then(function () { return import('@theia/getting-started/lib/browser/getting-started-frontend-module').then(load) })
  .then(function () { return import('@theia/scm/lib/browser/scm-frontend-module').then(load) })
  // .then(function () { return import('@theia/git/lib/browser/git-frontend-module').then(load) })
  // .then(function () { return import('@theia/git/lib/browser/prompt/git-prompt-module').then(load) })
  // .then(function () { return import('@theia/java/lib/browser/java-frontend-module').then(load) })
  // .then(function () { return import('@theia/java-debug/lib/browser/java-debug-frontend-module').then(load) })
  // .then(function () { return import('@theia/merge-conflicts/lib/browser/merge-conflicts-frontend-module').then(load) })
  .then(function () { return import('@theia/messages/lib/browser/messages-frontend-module').then(load) })
  .then(function () { return import('@theia/mini-browser/lib/browser/mini-browser-frontend-module').then(load) })
  .then(function () { return import('@theia/search-in-workspace/lib/browser/search-in-workspace-frontend-module').then(load) })
  // .then(function () { return import('@theia/plugin-ext/lib/plugin-ext-frontend-module').then(load) })
  // .then(function () { return import('@theia/plugin-dev/lib/browser/plugin-dev-frontend-module').then(load) })
  // .then(function () { return import('@theia/plugin-ext-vscode/lib/browser/plugin-vscode-frontend-module').then(load) })
  // .then(function () { return import('@theia/preview/lib/browser/preview-frontend-module').then(load) })
  // .then(function () { return import('@theia/python/lib/browser/python-frontend-module').then(load) })
  .then(function () { return import('@theia/textmate-grammars/lib/browser/textmate-grammars-frontend-module').then(load) })
  // .then(function () { return import('@theia/typehierarchy/lib/browser/typehierarchy-frontend-module').then(load) })
  // .then(function () { return import('@theia/typescript/lib/browser/typescript-frontend-module').then(load) })
    .then(start).catch(reason => {
        console.error('Failed to start the frontend application.');
        if (reason) {
            console.error(reason);
        }
    });
}

//webpack.config.js
const HtmlWebPackPlugin = require("html-webpack-plugin");
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const outputPath = path.resolve(__dirname, 'dist');
const monacoEditorCorePath = '/home/satya/ide/theia-embedded-demo/node_modules/@typefox/monaco-editor-core/min/vs';
const monacoCssLanguagePath = '/home/satya/ide/theia-embedded-demo/node_modules/monaco-css/release/min';
const monacoHtmlLanguagePath = '/home/satya/ide/theia-embedded-demo/node_modules/monaco-html/release/min';

module.exports = {
  node: {
    net: "mock",
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      },
      {
        test: /\.html$/,
        use: [
          {
            loader: "html-loader"
          }
        ]
      },
      {
        test: /\.css$/,
        exclude: /\.useable\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.useable\.css$/,
        use: [
          {
            loader: 'style-loader/useable',
            options: {
              singleton: true,
              attrs: { id: 'theia-theme' },
            }
          },
          'css-loader'
        ]
      },
      {
        test: /\.(ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
        loader: 'url-loader?limit=10000&mimetype=image/svg+xml'
      },
      {
        test: /\.(jpg|png|gif)$/,
        loader: 'file-loader',
        options: {
            name: '[path][name].[hash].[ext]',
        }
      },
      {
        test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        loader: "url-loader?limit=10000&mimetype=application/font-woff"
      },
      {
        test: /node_modules[\\|/](vscode-languageserver-types|vscode-uri|jsonc-parser)/,
        use: { loader: 'umd-compat-loader' }
      },
      {
          test: /\.wasm$/,
          loader: "file-loader",
          type: "javascript/auto",
      },
      {
          test: /\.plist$/,
          loader: "file-loader",
      },
    ]
  },
  resolve: {
    extensions: [ '.tsx', '.ts', '.js' ],
    alias: {
      'vs': path.resolve(outputPath, monacoEditorCorePath),
      'vscode': require.resolve('monaco-languageclient/lib/vscode-compatibility')
    }
  },
  plugins: [
    new HtmlWebPackPlugin({
      template: "./src/index.html",
      filename: "./index.html"
    }),
    new CopyWebpackPlugin([
      {
          from: monacoEditorCorePath,
          to: 'vs'
      },
      {
          from: monacoCssLanguagePath,
          to: 'vs/language/css'
      },
      {
          from: monacoHtmlLanguagePath,
          to: 'vs/language/html'
      }
    ]),
  ]
};

I do `webpack --mode production` and try to serve through nodejs( same as the backend folder contains in the theia examples