vue - codemirror + Java 컴 파 일 러 Java 웹 IDE 구현

9345 단어
배경
최근 에 동료 가 저 에 게 재 미 있 는 요 구 를 알려 주 었 습 니 다. 사용자 (응용 장면 에서 보통 다른 개발 자) 가 자바 코드 세 션 을 스스로 채 울 수 있 도록 합 니 다. 코드 세 션 의 내용 은 이미 정 해진 템 플 릿 류 의 계승 류 로 템 플 릿 류 의 정 의 를 실현 하 는 방법 입 니 다.우리 의 프로젝트 는 동적 컴 파일 코드 세 션 을 실현 하고 코드 세 션 과 사용자 작업 기록 의 맵 관 계 를 저장 하 며 업무 에서 코드 세 션 을 불 러 올 수 있 습 니 다.
이것 은 우리 가 템 플 릿 모드 의 구 조 를 제공 하 는 것 과 같 습 니 다. 템 플 릿 류 의 실현 류 는 외부 인터페이스 에 코드 세 션 을 채 워 서 동적 으로 이 루어 집 니 다.다른 개발 자 들 이 프로젝트 개발 에 직접 참여 하 게 하 는 것 에 비해 의심 할 여지없이:
  • 침입 위험 감소
  • 다른 개발 자 에 게 대부분의 실현 을 숨 겼 습 니 다
  • 조작 난이도 와 개발 문턱 낮 추기
  • 관리 하기 편리 함
  • ... 이것 은 간단 한 온라인 자바 개발 환경 을 실현 하고 기본 적 인 코드 작성, 컴 파일, 저장 기능 을 제공 하 는 것 과 같다.
    효과 시범vue-codemirrorJava Compiler 의 동적 컴 파일 을 바탕 으로 상기 수 요 를 실현 했다. 현재 완 성 된 웹 엔 드 IDE 의 주요 기능 점 은 다음 과 같다.
  • 페이지 에 자바 코드 블록 (코드 하 이 라이트, 줄 번호, 자동 완성 괄호 등)
  • 을 보 여 줍 니 다.
  • 서버 에서 템 플 릿 코드 를 가 져 오고 예제
  • 를 제공 합 니 다.
  • 실시 간 동적 컴 파일 및 컴 파일 결과 가 져 오기 (통과 / 실패 todo: 컴 파일 오류 정보 되 돌려 주기)
  • 입력 문자열 을 자바 Class 와 작은 기능 점 으로 불 러 옵 니 다. 자동 들 여 쓰기, 괄호 보완, 주제 전환, 연동 작성 등 입 니 다. 다음은 관련 된 기술 과 실현 방법 을 제시 합 니 다.
  • CodeMirror
    CodeMirror 는 다양한 부가 기능 과 다양한 언어 지원 을 지원 하 는 JS 라 이브 러 리 입 니 다. 저희 프로젝트 의 프론트 엔 드 는 Vue 프레임 워 크 를 사용 하여 CodeMirror 가 제공 하 는 플러그 인 을 편리 하 게 통합 하고 사용 하여 온라인 IDE 의 다양한 기능 을 구현 할 수 있 습 니 다. 참고: CodeMirror 홈 페이지
    끌어들이다
    설치 의존: "vue-codemirror": "^4.0.6" src 디 렉 터 리 에 있 는 main.js 에 도입:
    import VueCodeMirror from 'vue-codemirror'
    import 'codemirror/lib/codemirror.css'
    Vue.use(VueCodeMirror)
    

    쓰다
    새 구성 요소 JavaIDE.vue
      
      
          import codemirror from "codemirror/lib/codemirror";
          require("codemirror/mode/clike/clike.js");
          require("codemirror/addon/edit/closebrackets.js");
          components: {
              codemirror;
          }
          export default{
              data(){
                  return{
                    code: "",
                    cmOptions:{
                        mode: "text/x-java",  //Java  
                        theme: "darcula", //     
                        autofocus: true,  
                        lineNumbers: true,   //    
                        smartIndent: true, //     
                        autoCloseBrackets: true//       
                    }
                  }
              }
      
    

    구성 요 소 를 사용 하면 바 인 딩 된 값 (code) 과 다른 추가 옵션 (cmOption) 을 편리 하 게 조작 할 수 있 습 니 다. 구성 요 소 를 만 들 때 code 에 값 을 부여 하면 템 플 릿 코드 를 불 러 올 수 있 습 니 다.
    홈 페이지 에 따 르 면 우 리 는 CodeMirror 의 기본 구조 함 수 를 직접 사용 할 수 있 고 textarea DOM 요 소 를 구조 CodeMirror 대상 의 매개 변수 로 제공 할 수 있다.
    코드 블록 을 읽 기 전용 으로 설정 할 수 있 는 인자 readOnly 를 사용 할 수 있 습 니 다.
    연동 작성 유형 기능
    희망 실현: 위 상단 표시 줄 에 클래스 이름 을 입력 하고 코드 에 연동 하여 작성 합 니 다. 실현 방식: 정규 일치 코드 세 션 을 사용 한 다음 에 같은 방법 으로 교체 하고 동적 완성 클래스 이름 등 기능 을 실현 할 수 있 습 니 다.
    더 많은 JavaScript 정규 표현 식 참조
    입력 상자 에 감청 함수 추가 @input="changeClassName"
     changeClassName(className) {
        var reg = new RegExp(/public class .*? extends ActionParamBuilder/);
        this.code = this.code.replace(reg,
                        "public class " + className + " extends ActionParamBuilder"
       );
     }
    

    테마 전환
    테마 도입 css 스타일 파일
     import "codemirror/theme/eclipse.css";
     import "codemirror/theme/darcula.css";
     import "codemirror/theme/blackboard.css";
    

    String 배열 을 사용 하여 지원 하 는 테 마 를 정의 하고 Element-UI 제공 하 는 Select 구성 요소 지원 테마 전환 을 사용 합 니 다.
    
              
                 
                  
          
          
     
       
    
    
  • 사용 slot 선택 기 에 아이콘 을 삽입 하고 tooltip 기능 을 지원 하여 도구 모음 을 더욱 치밀 하 게 합 니 다. slot 슬롯 이라는 뜻 으로 봉 인 된 구성 요소 가 미리 남 겨 놓 은 사용자 정의 공간 입 니 다. slot = "" DOM 요 소 를 구성 요소 내부 에 넣 을 수 있어 매우 유연 합 니 다.
  • 양식 복사!important 키 워드 를 사용 하여 기 존 CodeMirror 스타일 을 덮어 씁 니 다. 이 스타일 을 부분 scoped 스타일 시트 가 아 닌 전역 에 두 십시오.
    .CodeMirror {
         height: 500px !important;
     }
    

    JavaCompiler
    들 어 오 는 코드 를 .java 파일 로 저장 하지 않 고 JavaCompiler 도 구 를 사용 하여 문자열 을 컴 파일 할 수 있 습 니 다.
    실시 간 동적 컴 파일 기능 을 실현 하기 위해 서 나 는 문자열 을 class 로 컴 파일 하 는 방법 을 검색 하고 동적 에이전트 의 실현 방향 도 보 았 다. 나중에 이 편 을 보 았 다. 자바 가 실 행 될 때 동적 으로 class 를 생 성 하 는 방법 은 이것 이 바로 내 가 원 하 는 것 임 을 발견 했다!
    자바 SDK (since 1.6) 에서 제공 하 는 자바 컴 파 일 러 도 구 를 사용 합 니 다. 이 도 구 는 컴 파일 방법 을 제공 합 니 다.
      CompilationTask getTask(Writer out,
                                JavaFileManager fileManager,
                                DiagnosticListener super JavaFileObject> diagnosticListener,
                                Iterable options,
                                Iterable classes,
                                Iterable extends JavaFileObject> compilationUnits);
    
  • JavaFileManager 사용자 정의 MemoryJavaFileManager, 계승 ForwardingJavaFileManager, 메모리 문자열 에서 자바 FileObject 를 읽 는 데 중점 을 두 는 것 은 다음 과 같은 방법 입 니 다.
  • 	JavaFileObject makeStringSource(String name, String code) {
    		return new MemoryInputJavaFileObject(name, code);
    	}
    	static class MemoryInputJavaFileObject extends SimpleJavaFileObject {
    		final String code;
    		MemoryInputJavaFileObject(String name, String code) {
    			super(URI.create("string:///" + name), Kind.SOURCE);
    			this.code = code;
    		}
    		@Override
    		public CharBuffer getCharContent(boolean ignoreEncodingErrors) {
    			return CharBuffer.wrap(code);
    		}
    	}
    
  • options 선택 가능 한 매개 변수 목록 은 외부 Jar 가방 의존 도 를 증가 시 킬 수 있 습 니 다. 우리 가 컴 파일 해 야 할 코드 에 의존 하 는 클래스 는 외부 Jar 가방 에서 유래 되 기 때문에 이 Jar 가방 을 사용 해 야 합 니 다 option. 이 단 계 는 구 덩이 를 밟 았 습 니 다. 사용 해 보지 않 았 기 때문에 어떻게 쓰 는 지 모 르 겠 습 니 다. 마지막 으로 정확 한 쓰기 방법 을 찾 았 습 니 다. List optionList =Arrays.asList("-extdirs",extLib);extLib 외부 jar 패키지 의 경로 (디 렉 터 리 주소) 입 니 다. 경로 구분자 로 여러 경 로 를 입력 할 수 있 습 니 다.
  • DiagnosticListener 진단 정보 감청 에 진단 정보 감청 기 를 추가 하면 우 리 는 잘못된 정 보 를 컴 파일 하여 이 정 보 를 전단 에 피드백 하여 실시 간 으로 컴 파일 하고 오 류 를 보고 하 는 기능 을 실현 할 수 있다. DiagnosticCollector diagnosticCollector = new DiagnosticCollector();
  • JavaFileObject 컴 파일 할 자바 대상 은 사용자 정의 클래스 MemoryJavaFileManagermakeStringSource 방법 을 호출 합 니 다. 컴 파일 유닛 에 들 어 갈 수 있 습 니 다. 전체 방법 은 다음 과 같 습 니 다.
  • public Map compile(String fileName, String source,String extLib) throws IOException {
    		try (MemoryJavaFileManager manager = new MemoryJavaFileManager(stdManager)) {
    			JavaFileObject javaFileObject = manager.makeStringSource(fileName, source);    
                //         size    javaObject  
                DiagnosticCollector diagnosticCollector = new DiagnosticCollector();
    			List optionList =Arrays.asList("-extdirs",extLib);
    			CompilationTask task = compiler.getTask(null, manager,diagnosticCollector, optionList, null, Arrays.asList(javaFileObject));
    			Boolean result = task.call();
    			if (result == null || !result.booleanValue()) {
    				throw new RuntimeException("Compilation failed.");
    			}
    			return manager.getClassBytes();
    		}
    	}
    

    호출 코드:
     Map results = javaStringCompiler.compile(className + ".java", CODE_TO_COMPILE, libDir);
    

    사용자 정의 ClassLoader
    '자바 프로 그래 밍 의 논리' 의 24.5 내용 을 참고 하면 사용자 정의 ClassLoader 를 사용 하여 사용자 코드 세 션 을 불 러 와 호출 가능 한 Class 대상 이 될 수 있 습 니 다.
  • 계승 URLClassLoader
  • 다시 쓰기 findClass 방법
  • class MemoryClassLoader extends URLClassLoader {
    
    	// class name to class bytes:
    	Map classBytes = new HashMap();
    
    	public MemoryClassLoader(Map classBytes) {
    		super(new URL[0], MemoryClassLoader.class.getClassLoader());
    		this.classBytes.putAll(classBytes);
    	}
    
    	@Override
    	protected Class> findClass(String name) throws ClassNotFoundException {
    		byte[] buf = classBytes.get(name);
    		if (buf == null) {
    			return super.findClass(name);
    		}
    		classBytes.remove(name);
    		return defineClass(name, buf, 0, buf.length);
    	}
    
    }
    

    사용자 정의 클래스 로 더 는 다음 과 같은 장점 이 있 습 니 다.
  • 메모리 에서 지정 한 jar 패키지 나 데이터베이스 / 네트워크 에서 읽 는 등 class 파일 바이트 코드 를 읽 는 방법 과 형식 을 사용자 정의 할 수 있 습 니 다
  • 격 리 를 실현 하면 같은 유형의 서로 다른 버 전
  • 을 사용 할 수 있다.
  • 열 배 치 를 실현 하고 동적 업데이트 류 의 내용
  • 총결산
    이 편 은 주로 지식 과 관련된다.
  • vue-codemirror 집적 및 사용
  • JavaCompiler 의 사용
  • JavaScript 정규 와 Vue 의 슬롯 slot
  • 사용자 정의 ClassLoader 동적 로드 실현
  • 좋은 웹페이지 즐겨찾기