How to make an online compiler

Time:2020-3-23

Before the article starts, I’ll show you my own online compilerJS-Encoder:

Click here for a preview.

How to make an online compiler

About three or four months ago, I began to have the idea of making online compilers. Before that, I had contact with many online compilers, such as codepen, jsbin, jsfiddle, etc., which are very excellent and have a huge user group of compilers.

I have always been very interested in the implementation of online compilers, which support many languages, code discoloration, many shortcut keys and some personalized settings, which makes the online compilers look not too different from the compiler software we download locally. I have no idea how to implement these complex functions, so I observedCodePenandJsBinThe code found that they both used a tool called codemirror.

codemirror

codemirrorIs a browserJavaScriptThe realization of multi-functional text editor. It is specially used for editing code, and with many language patterns and plug-ins, it can achieve more advanced editing functions.

So these compilers rely oncodemirrorTo achieve this,codemirrorIt’s such a complex tool that it took me two days to get familiar with its configuration items.codemirrorIt’s a direct operationDOMAnd my project is usingVue + WebpackBuilt, which violatesVue Data drivenSo I’m herenpmThe tool Vue codemirror was found on theVueHow to build a code editor

codemirrorThere are many configuration items. I used the following configuration in my own project. If you want to see all the configurations, you can see here

cmOptions: {
        // codemirror config
        Flattenspans: false, // by default, codemirror merges two spans that use the same class into one. Disable this feature by setting this to false
        Tabsize: 2, // number of indented spaces
        Mode: '', // mode
        Theme: 'monokai', // theme
        Smartindent: true, // smart indent or not
        Linenumbers: true, // display line numbers
        Matchbrackets: true, // match symbols
        Linewisecopycut: true, // if no text is selected during copying or cutting, the whole line of cursor will be automatically operated
        IndentWithTabs: true, // when indenting, do you need to replace n*tab width spaces with n tab characters
        Electricchars: true, // whether to indent again when the input may change the current indent
        Indentunit: 2, // indent unit, default 2
        Autoclosetags: true, // automatically close Tags
        Autoclosebackets: true, // enter brackets automatically
        Foldgutter: true, // allow folding at line number position
        Cursorheight: 1, // cursor height
        Keymap: 'sublime', // shortcut key collection
        extraKeys: {
          'Ctrl-Alt': 'autocomplete',
          'Ctrl-Q': cm => {
            cm.foldCode(cm.getCursor())
          }
        }, // smart tips
        Gutters: ['codemirror line numbers', 'codemirror foldgutter'], // used to add extra gutters
        Styleactiveline: true // activate the current line style
      },

These configurations are only a small part, but they are enough to achieve the functions I want

modeRepresents the language used by the current editor

themeIt represents the color used by the editor. There are many colors officially supported, but there is no color preview, so I directly use the color I am familiar withmonokaiAs a theme, because I like it bettervscodeSo I foundmonokai.cssFile and modify many styles, although in the end and realvscodeThere’s a difference in the theme, but I did my best A kind of

keymapI set it assublimesublimeMost shortcuts on are available

I should have explained the other configurations in the notes, so I won’t explain them here

codemirrorThe effect is good

How to make an online compiler

Yes.codemirrorThe most difficult problem of this artifact has been solved, but there are many small problems to be solved

layout

There are many references for layoutJsBinBecause I think its interface looks simple and comfortable

JsBinThe layout is aunt jam’s:

How to make an online compiler

It is divided into five windows. You can drag the mouse over the boundary of two windows to change the window size

How to make an online compiler

Dragging the mouse will increase the width of one window and decrease the width of the other window, but the sum of the two windows will not change

My thinking is:

Obtain the width of two adjacent windows when clicking the border, calculate the horizontal moving distance of the mouse when dragging the mouse, and increase or decrease the width of the two windows accordingly

Since these five windows are all sub components of the same level, it is difficult for one window to get the width of another window, so I put the width of these five windows on theVuexThe width of each window followsVuexChange due to change of width information in

Successful results:

How to make an online compiler

To avoid the problem of two windows overlapping, I setmin-width: 100px;Style

In addition to the problem of two windows, it is also necessary to make sure that the width of all windows changes with the width of the browser:

How to make an online compiler

This effect is also easy to achieve, as long as the width of each window is added or subtracted when the browser width changesChange width / number of windowsThat’s all right.

Iframe

This is my first real contactiframeThis thing, maybe it’s very simple, but I did spend a lot of effort on it

I’ve solved the problem of window dragging, but it’s notiframeIt’s invalid. I was confused all the time and couldn’t find the reason. At last, I suddenly thought:

iframeIs a separate new page, iniframeEvents triggered outside will not affectiframeItself, when I drag the border with the mouse, if the mouse entersiframeThe drag event is invalid, so you need to give theiframeAdd a transparent mask layer on it, so that there will be no drag problem

When the user doesn’t input any characters for a period of time or directly clicks the run button, theHTMLCSSandJavaScriptCode putiframeMedium,iframeIt will show the final effect, so I will put the content in the editor in theVuexin

Compile

codemirrorMany functions can be realized, but he doesn’t do compiling, such asJsBinandCodePenSuch a compiler does not only support ordinaryHTMLCSSandJavaScriptThey also support many preprocessing languages of these three languages

For example, I choseTypeScriptAs a preprocessing language, the compiler needs toTypeScriptTranslate intoJavaScriptPass it on againiframe

BecauseJS-EncoderIt is a compiler without background, so it is necessary to introduce other preprocessing languagesnpmPackage and file to compile, such as in the implementationSassandScssI introducedSass.jsandSass.worker.jsTo compile:

async function compileSass(code) {
  // scss&sass
  if (!loadFiles.get('sass')) {
    const Sass = await require('./sass')
    Sass.setWorkerUrl('static/js/sass.worker.js')
    loadFiles.set('sass', Sass)
  }

  const defSass = loadFiles.get('sass')
  const sass = new defSass()
  
  return new Promise((resolve, reject) => {
    sass.compile(code, result => {
      if (result.status === 0) resolve(result.text)
      else reject(new Error('fail to get result'))
    })
  })
}

HereloadFilesIt is only used to judge whether these files have been introduced or not. I see this compilation method in the official document

at presentJS-EncoderSupportMarkDownSassScssLessStylusTypeScriptandCoffeeScript, support will be considered laterLiveScriptandJSX(React)

Set up

stayJS-EncoderIn addition to the preprocessing language selection, there are the following settings

  • Delay execution time

    • I set up every editable windowwatchThe change of monitoring value and frequent input will lead to frequent triggering of methods. Therefore, I set the anti shake function. Only when the user does not enter any characters in the set delay time can the code be executed
  • Convert space with the same width as tab to tab
  • CDN

    • You can add externalCDN, which will be executedJavaScriptIntroduced beforeCDN
  • CSS

    • You can add externalCSS, which will be executedCSSPass beforelinkIntroduce

summary

JS-EncoderIt has been two months since the official development, because of academic reasons, there is not too much time to invest in the development. at presentJS-EncoderIt is still a semi-finished product. In addition to some basic functions, there are many functions that are not or are being implemented. If you are interested, you can focus on this project on GitHub. I will continue to update this article as more features are implemented.

Recommended Today

Histogram, a common function of Prometheus_ Some counterintuitive problems of quantile

Author: disking histogram_quantilePrometheus is a function commonly used by Prometheus. For example, the p99 response time of a service is often used to measure the quality of service. But it’s hard to understand exactly what it means, especially for non-technical students. On the other hand, even senior R & D students often find out when […]