Create an online IDE with Angular 6 + NodeJS ~ Part #1

Ofir G
9 min readOct 14, 2018

--

Intro to the Series

What you will do on this series

In short, you will build a full-on online IDE project, an online tool where you can run your code in an independent environment, with your language of choice, any time anywhere.
We would lay the ground for any extensions so you could take it to another level, and make it your own product.

Intended Audience

Any inspire (beginner to intermediate) Angular and/or NodeJS developer, who wish to pick up some of Angular and NodeJS fundamentals principles and experience, through the process building of this project piece by piece.

Requirements

  • NodeJS & Angular installed on your work environment.
  • A beginner level knowledge in Angular Framework.
  • Basic knowledge in NodeJS.

Your Work Plan

I’ve divided this project into three parts :

Part 1 — you will create an angular project, build a nice looking responsive page, and integrate Ace (code editor library) in it.

Part 2 — for your server-side you’ll use NodeJS, create a quick express-typescript app boilerplate, ready for RESTful API implementation with ExpressJS library and Typescript.

Part 3 then you’ll implement your app API’s routes, you’ll use Request library for external services requests, and Lodash library assists.

Part 4 — then you’ll add logger service to your app, create test suites for your API’s routes with Mocha, Chai and Supertest libraries,

Part 5 — you’ll connect the client to the server, and fully complete the code editor page.

Part 6 — finally meet Heroku free web services where you’ll deploy everything too 🙌.

Part #1 — Create your IDE client side with Angular 💪

What you will do on this part

On this part of the project you will create a new Angular app, setup a code editor using the popular Ace library, with Bootstrap help setting a nice looking responsive page for your fancy code-editor.
To keep things clear, you will write some code and refactor it for a clean ng’ code style, little at a time.

Contents Table — Part #1

  • Introducing Ace Code Editor .
  • Let’s start Coding.
    ◢ Initial integration of Ace in to your code.
    ◢ Adding more features.
    ◢ Moving on to your page’s template.
  • Getting serious, put on your tough face — refactor your work.
    ◢ Dedicate a Component.
    ◢ Wrap it up in NgModule.

Introducing Ace Code Editor

let’s introduce Ace Code Editor, pretty popular wed code editor library.

Check
Ace’s Git for demos,
and
Ace Playground.

About Ace :

Ace is an embeddable code editor written in JavaScript. It matches the features and performance of native editors such as Sublime, Vim and TextMate. It can be easily embedded in any web page and JavaScript application. Ace is maintained as the primary editor for Cloud9 IDE and is the successor of the Mozilla Skywriter (Bespin) project.

We will mainly rely on Ace to achieve the code writing feel you got on you standard IDE.

Let’s start Coding

Initial integration of Ace in to your code

Assuming you got NodeJS and Angular (v 6 preferred) all set up, we can go.
So first you need to create a new angular project, than install Ace and Bootstrap (Bootstrap is not a must, but it’s sure are make things easier 🙌).

install ace-builds package ;

npm i ace-builds —-save

and for Bootstrap you can just paste the CDN link in src/index.html, or through NPM, I think you can manage that on your own …

The way that Ace lib works; you got a bunch of themes, languages and extension modules build in the package, and you can load them as you wish, according to your design and usage preferences, (see the docs here).

Let’s create a new component, it will function as your app’s main page.
If you’ll create the component manually then don’t forget to register it on app.module (add it to the declarations array), then delete all the default content in app.component.html and render your new component.

In the new component add the imports :

import * as ace from 'ace-builds'; // ace module ..// language package, choose your own 
import 'ace-builds/src-noconflict/mode-javascript';
// ui-theme package
import 'ace-builds/src-noconflict/theme-github';

add a div element for the Ace code to be hooked on, and add a tag to it so you could reference it on the component code.

<div class="code-editor" #codeEditor></div>

now, using @ViewChild decorator and ElementRef, you will hook Ace to your template, and actually see your new code-editor;

@ViewChild decorator and ElementRef are closely connected modules, they are part of angular core, and play a fundamental role in the Ng world .
The strategy of combining those two together is angular clean approach of directly accessing and manipulating the dom.

Ace Editor setup

The code is pretty straightforward, but still, let’s break it down :

line 16 ~ you’re referencing the div element tagged with #codeEditor as codeEditorElemRef class member.

lines 22–29 ~ you’re fetching the nativeElement (unwrapped dom element / raw HTML div element), defining the config options for the editor setup, then calling ace.edit with the element reference and the options to hook ace editor in.

line 30 ~ setting a theme for the editor, I choose “github”, you can choose any.

line 31 ~ setting the editor language, so it will react to keyword.

line 32 ~ setting a really nice feature — fold scope effect, I loved it ..

[you can view Ace’s importable modules on ace-builds/ace-modules.d.ts ]

Adding more features

First cool feature of Ace editor is Auto Completion ! 😁
add this to the imports :

import 'ace-builds/src-noconflict/ext-language_tools';

Add the line ace.require(‘ace/ext/language_tools’); to ngOnInit method,
than add the property enableBasicAutocompletion: true to the options you provide to ace.edit method, by just adding it you will see that typescript scream at you, this because that property is’not documented on the type ace.Ace.EditorOptions (might be a 🐛), so on your EditorOptions object you will assign an object with that property, and provide the merged result to ace.edit .

Add autocompletion feature

Next feature you will configure is a Code Beautify 🌷
like before, add this extension to the imports :

import 'ace-builds/src-noconflict/ext-beautify';

Create a new member : private editorBeautify;, it will hold the beautify extension reference.
to initialize editorBeautify member with the extension reference, add this line to ngOnInit :

this.editorBeautify = ace.require(‘ace/ext/beautify’);

Now create a new method beautifyContent() ;

public beautifyContent() {
if (this.codeEditor && this.editorBeautify) {
const session = this.codeEditor.getSession();
this.editorBeautify.beautify(session);
}
}

by calling beautifyContent(), the editor content will be beautify.

One little thing, just for debugging, add this little method, so you could access and handle the code that’s being written on the editor :

private getCode() {
const code = this.codeEditor.getValue();
console.log(code);
}

at this point you just console log it, but you will soon send it to your sever .

Moving on to your page template

I’ll not explain it too much, instead I’ll go with you through the page layout diagram ;

The page layout

Each part in the layout marked with a number ;

head-bar, with title.

mode & theme controllers.

the code-editor input box.

buttons section.

output box.

There are some bootstrap usage (check the docs), and a bit of custom CSS:

Your end result should look something like this, clean and responsive 😎 .

Your responsive page

Getting serious, put on your tough face 😒

The first part is done and working nice, but we can do some refactoring.
Although it’s not a must, I highly recommend you to follow along and see how you can keep your code modular and organized.

Dedicate a Component

At this point all the code you’ve written is related to the code-editor [to that code we will add methods for sending data and receiving some], so it make sense to encapsulate everything code-editor related to it’s own module;

Create a new folder named ‘code-editor’, I’ve placed it under src/app/, so now my folders structure look like this:

src
|--app
| |--code-editor
| |--components /*components used on any of the pages*/
| |--pages /*components presented as pages*/

As for angular project folder structure, there are many many ways of doing it, 90% of them are OK, so you can go with what ever make sense to you.

in the “code-editor” folder create file name “code-editor.module.ts”, a ‘components’ folder, and in it, a new component named “code-editor” (shock !)

code-editor
|--components
| |--code-editor.component.css
| |--code-editor.component.html
| |--code-editor.component.ts
|--code-editor.module.ts
|--index.ts /* for all the module exports */

Side-Note — sometimes angular-cli mess things up when trying to generate nested components, so I suggest you to create it manually, (if so don’t forget adding it to the declaration in app.module).

First you need to handle the “code-editor” component, just copy paste literally everything from the old component to this one, copy the div element the code-editor hooks on, and the CSS code used on that div.

Code Editor on is own component

Now you separated all the code-editor’s logic from the main-page, it look better and even feel right !, but as for now, you don’t give any access to the content in the editor for any page who uses that component.

Time to export some staff !
We can add a lot of nice things, but for now we’ll keep it simple, so we need :

  • give read access to the editor content in any given time, for any component that uses is.
  • give write access for parent component to insert and edit the editor’s content.
  • export some events Ace lib provide for us.

To provide a read / write access to the content, you will simply add getContent and setContent methods (self explanatory).
The last thing is to export Ace “native” events for any components using your editor component, for now the “change” event will be it.

The “change” event emitted for any change occurred on the editor content. “change” event provide an object with some data, but to your proxy event you can add any additional data you wont to pass on to the listeners. you can think of any data to add ? yea, we will add the current content.

[Optional] — I added a @input decorated “content” member, although it seems like an overkill, the purpose of it is for initialized the content from outside.
In the future you might use it to initialize more of the editor component options.

The updated component code :

Code Editor refactored & updated

Wrap it up in NgModule

The last part is to wrap it up in a module, export the classes from index.ts and registering the module in app.module;

Here you simply declaring on the editor component and exporting it to your app.

If you’re not really familiar with NgModule (or just haven’t had the chance to create one), it’s fine. The goal of NgModule is basically maintaining a complete modularity in your work environment, (BTW NgModule = Angular libraries).

“NgModules consolidate components, directives, and pipes into cohesive blocks of functionality, each focused on a feature area, application business domain, workflow, or common collection of utilities.”

Side-Note — it’s could seem complicated for beginners, to me, at first, it looked like huge Tangela mess 😵, but as soon as you dive in to it the better, cause on those concepts the entire Angular framework stands, I really encourage you to read about it here.

in index.ts :

export * from './component/code-editor.component';
export * from './code-editor.module';

in app.module.ts :

Now, that the editor component registered in your app, all you need to do is use it in your page.
On the template, where the <div #codeEditor></div> is, insert the editor component selector, and on the page component code, similar to what you did before ;

Use the editor component in your page

Let’s review

  1. You installed “ace-builds” package, then you integrated Ace’s code-editor element in his simplistic form, using @ViewChild decorator and ElementRef.
  2. You added to the editor Autocompletion & Beautify features, with build-in extensions.
  3. You had a quick go thorough on your code-editor page layout, and then actually created the page template, using mainly in Bootstrap.
  4. Refactored the code-editor code in your page component to a separate component and finally wrapped it in a NgModule.

You’re done building your client side for this part.
On the next part — start your NodeJS server side boilerplate.

--

--