Vue에 Code-mirror 적용해보기!

Sian·2020년 9월 23일
0

SpaceONE FrontEnd 개발

목록 보기
2/6
post-thumbnail

프로젝트에 새로운 Json Editor를 도입하는 임무를 맡게 되어서, 여러 라이브러리들을 검색하던 중 vue-codemirror(https://github.com/surmon-china/vue-codemirror#readme)라는 라이브러리를 찾게 되었다.
다른 후보군으로는 vue-prism-editor나 vue2-ace-editor도 있었는데, 전자는 훨씬 크기가 크고 후자는 문서화가 잘 안되어있고 업데이트도 안되는 것 같아 모든 면에서 더 나은 vue-codemirror를 선택하였다.

vue-codemirror를 설치하기 위해 우선 아래의 명령어를 실행한다.

npm install vue-codemirror --save

그리고 main.ts에 아래와 같이 명시한다.

import Codemirror from 'vue-codemirror';
import 'codemirror/lib/codemirror.css';

...
(생략)
...

Vue.use(Codemirror);

이제 프로젝트 내에서 Codemirror를 사용할 수 있다.
다만 진행중인 프로젝트의 컨벤션 상 라이브러리를 그대로 쓰지 않고 컴포넌트로 wrapping해야 하기 때문에 아래와 같이 html 코드를 작성한다. 이 부분은 프로젝트마다 다를 수 있다.

<template>
	<div class="p-text-editor">
      <codemirror
          ref="editor"
          v-model="proxyCode"
          :options="options"
          :mode="mode"
      />
    </div>
</template>

그리고 typescript 영역에는,

import {
    onMounted, reactive, toRefs, watch,
} from '@vue/composition-api';

import 'codemirror/mode/javascript/javascript';
import 'codemirror/addon/lint/json-lint';
import 'codemirror/addon/fold/brace-fold';
import 'codemirror/addon/fold/comment-fold';
import 'codemirror/addon/fold/foldcode';
import 'codemirror/addon/fold/foldgutter';
import 'codemirror/addon/fold/indent-fold';
import 'codemirror/addon/fold/markdown-fold';
import 'codemirror/addon/fold/xml-fold';
import 'codemirror/addon/edit/closebrackets';
import 'codemirror/addon/edit/closetag';

이렇게 필요한 addon을 공식 문서(https://codemirror.net/doc/manual.html#addons)에서 찾아 추가해준다. 진행중인 프로젝트의 요구사항은 1 depth 이상 들어가는 json은 모두 folding 해주어야 하고, json 형태로 보여주어야 하는 것이기에 위와 같이 추가하였다.

그리고 나서, 아래와 같이 props를 정의했다.

export default {
    name: 'PTextEditor',
    components: { },
    props: {
        code: {
            type: String,
            default: '',
            required: true,
        },
        options: {
            type: Object,
            default: () => ({
                tabSize: 4,
                styleActiveLine: true,
                lineNumbers: true,
                line: true,
                mode: 'application/json',
                lineWrapping: true,
                theme: 'ayu-mirage',
                matchBrackets: true,
                autoCloseBrackets: true,
                autoCloseTags: true,
                foldGutter: true,
                gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
            }),
        },
        mode: {
            type: String,
            default: 'edit',
            required: true,
        },
    },

프로젝트마다 props에 필요한 것들이나, 이 컴포넌트를 사용하는 쪽에서 json에 입력한 input(위의 코드에서는 code)을 정의하는 방식이 다르기 때문에 options 위주로 참고해주세요. 🙂

options에 정의한 내용들은 위에서 codemirror에 바인딩되는 codemirror 에디터 자체의 옵션들이다.
tab size, line 넘버 표기, json 형태, editor 테마, 괄호 자동 닫기, code Folding 기능 등을 명시하였다. 공식 문서에 더 자세한 옵션들이 존재한다.
중요한 점은 위와 같은 옵션을 사용하기 위해선 해당하는 addon을 import해야 한다는 것이다.

이 다음 setup()부터 return까지는 각 프로젝트마다 로직이 다르기 때문에 생략한다.

다만 이 때 중요한 점은, props로 받아온 값(여기서는 code)을 그대로 사용할 수 없기 때문에 getter와 setter를 만들어(props를 get해주고, update를 emit하는 set..) 바인딩해주어야 하는 것이다.
사용하는 쪽에선 .sync를 통해 데이터를 바인딩한다.

그리고 혹시라도 공식문서에 나와있는 것처럼 dom에 접근하는 action을 활용하고 싶을 때는,

const cm = editor.codemirror;

이런 식으로 ref에 접근한 후 해당 ref 안에 있는 codemirror를 사용하면 된다. (ex. cm.operation...)

사실 codemirror의 문서가 그다지 친절하진 않아서 해당 객체가 어떤 속성을 가지고 있는 지 debugger를 통해 모두 뜯어보기도 했는데, 힘들었지만 좋은 경험(삽질)이었던 것 같다.

로직을 다 작성한 후에는 이제 스타일링이 남았다.

<style lang="postcss">
    @import 'codemirror/theme/ayu-mirage.css';
    @import 'codemirror/addon/lint/lint.css';
    @import 'codemirror/lib/codemirror.css';
    @import 'codemirror/addon/fold/foldgutter.css';
    .p-text-editor {
        height: 100%;
        min-height: 5rem;
        .CodeMirror {
            font-family: Inconsolata, monospace;
            line-height: 1.5;
            height: fit-content;
            padding: 1rem;
        }
    }
</style>

진행중인 프로젝트에서는 postcss-easy-import라는 플러그인을 사용하기 때문에 위와 같이 import해주었고, 일반적인 방식으로 import해도 똑같이 동작한다.
테마나 린트, codemirror 자체 css 등을 import해준다.
그 후 editor를 스타일링 할 때는 .CodeMirror 클래스를 직접 접근해서 수정해주면 된다.

이렇게 프로젝트에 code mirror 적용을 할 수 있다. 😁 아래는 적용한 code mirror editor의 모습이다.

profile
https://sian-log-siyeons.vercel.app/ 이 곳으로 이전하였습니다.

0개의 댓글