[근무 일지] VS Code Extension 스터디2

타키탸키·2022년 4월 22일
0

근무 일지

목록 보기
12/16
  • 스크립트 언어
    • 기존에 존재하는 SW를 제어하기 위한 용도로 쓰이는 언어
    • 응용 프로그램과 독립하여 사용
      • 응용 프로그램 언어와 다른 언어로 사용
      • 응용 프로그램의 동작을 사용자의 요구에 맞게 수행할 수 있도록 한다
  • JavaScript와 TypeScript
    • JavaScript
      • 스크립트 언어
      • 웹을 구성하는 요소 중 하나
      • 클라이언트 단에서 웹 페이지가 동작하는 것을 담당(동력부)
      • HTML과 CSS로 만들어진 웹페이지를 동적으로 변경해주는 언어
      • 변수형이 존재하지 않음(var)
    • TypeScript
      • JavaScript의 Superset 프로그래밍 언어
      • JavaScript와 달리, 정적 타입 명시 가능
      • 컴파일 시, 잘못 사용된 코드를 잡아낼 수 있다
      • 객체 지향 프로그래밍 가능(클래스 기반 객체 생성, 상속, 캡슐화, 생성자...)
// JavaScript
var x = 123;
var y = "123";

// TypeScript
let x = '123';
let y : string = '123';

코드 분석

import * as vscode from 'vscode';
import * as fs from 'fs';
import * as path from 'path';
  • 모듈
    • 자주 사용하고 반복되고 중요한 요소들을 미리 선언한 후 export하여 사용
    • 라이브러리와 유사한 개념
  • fs
    • 파일 시스템 모듈
  • path
    • 경로 작업을 위한 유틸리티를 제공하는 모듈
export class NodeDependenciesProvider implements vscode.TreeDataProvider<Dependency> {
  • export
    • 모듈의 변수, 함수, 타입 등을 외부 모듈이 사용할 수 있도록 표시한 키워드
  • implements
    • 반드시 부모의 메소드나 변수를 오버라이드해서 사용하도록 하는 예약어
    • 인터페이스에 있는 프로퍼티 및 메서드를 전부 가지고 있거나 구현해야 한다
    • 다중 상속 지원
  constructor(private workspaceRoot: string) {}
  • constructor
    • 모든 class가 가지는 메서드
    • class로부터 객체를 생성할 때 호출 된다
    • 객체의 초기화 담당
    • constructor(접근제한자 변수명: 타입)
  getTreeItem(element: Dependency): vscode.TreeItem {
    return element;
  }

  getChildren(element?: Dependency): Thenable<Dependency[]> {
    if (!this.workspaceRoot) {
      vscode.window.showInformationMessage('No dependency in empty workspace');
      return Promise.resolve([]);
    }
  • TreeDataProvider 인터페이스 구현
    • 어떤 item을 전시할 것인가를 설정한다
    • getTreeItem
      • 주어진 element나 root를 위한 자식(children)을 반환
    • getChildren
      • view 내부에 구현될 element의 UI(TreeItem)를 반환
  private getDepsInPackageJson(packageJsonPath: string): Dependency[] {
  • 함수 선언
    • 접근제한자 함수명(인자명: 타입): 리턴 타입
      const deps = packageJson.dependencies
        ? Object.keys(packageJson.dependencies).map(dep =>
            toDep(dep, packageJson.dependencies[dep])
          )
        : [];
  • ?
    • 선택적 프로퍼티
    • 객체 프로퍼티 타입을 정의하고 값을 할당하지 않는 경우 에러 발생
    • 선택적 프로퍼티로 구현된 프로퍼티는 값을 할당하지 않아도 문제가 없다
    • optional chaining(프로퍼티가 null 또는 undefined)에서도 사용 가능(undefined 반환)
  • 전체 코드
    • Tree View를 열면, getChilderen 메서드가 element를 제외하고 호출된다
    • TreeDataProvider는 상위 레벨의 tree item을 반환한다
    • 예제 코드
      • 상위 레벨의 tree item의 collapsibleStateTreeItemCollapsibleState.Collapse이다
      • 상위 레벨 tree item이 collapsed로 설정된다
      • .None은 tree item이 children을 가지고 있지 않다는 것을 의미한다
import * as vscode from 'vscode';
import * as fs from 'fs';
import * as path from 'path';

export class NodeDependenciesProvider implements vscode.TreeDataProvider<Dependency> {
  constructor(private workspaceRoot: string) {}

  getTreeItem(element: Dependency): vscode.TreeItem {
    return element;
  }

  getChildren(element?: Dependency): Thenable<Dependency[]> {
    if (!this.workspaceRoot) {
      vscode.window.showInformationMessage('No dependency in empty workspace');
      return Promise.resolve([]);
    }

    if (element) {
      return Promise.resolve(
        this.getDepsInPackageJson(
          path.join(this.workspaceRoot, 'node_modules', element.label, 'package.json')
        )
      );
    } else {
      const packageJsonPath = path.join(this.workspaceRoot, 'package.json');
      if (this.pathExists(packageJsonPath)) {
        return Promise.resolve(this.getDepsInPackageJson(packageJsonPath));
      } else {
        vscode.window.showInformationMessage('Workspace has no package.json');
        return Promise.resolve([]);
      }
    }
  }

  /**
   * Given the path to package.json, read all its dependencies and devDependencies.
   */
  private getDepsInPackageJson(packageJsonPath: string): Dependency[] {
    if (this.pathExists(packageJsonPath)) {
      const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));

      const toDep = (moduleName: string, version: string): Dependency => {
        if (this.pathExists(path.join(this.workspaceRoot, 'node_modules', moduleName))) {
          return new Dependency(
            moduleName,
            version,
            vscode.TreeItemCollapsibleState.Collapsed
          );
        } else {
          return new Dependency(moduleName, version, vscode.TreeItemCollapsibleState.None);
        }
      };

      const deps = packageJson.dependencies
        ? Object.keys(packageJson.dependencies).map(dep =>
            toDep(dep, packageJson.dependencies[dep])
          )
        : [];
      const devDeps = packageJson.devDependencies
        ? Object.keys(packageJson.devDependencies).map(dep =>
            toDep(dep, packageJson.devDependencies[dep])
          )
        : [];
      return deps.concat(devDeps);
    } else {
      return [];
    }
  }

  private pathExists(p: string): boolean {
    try {
      fs.accessSync(p);
    } catch (err) {
      return false;
    }
    return true;
  }
}

class Dependency extends vscode.TreeItem {
  constructor(
    public readonly label: string,
    private version: string,
    public readonly collapsibleState: vscode.TreeItemCollapsibleState
  ) {
    super(label, collapsibleState);
    this.tooltip = `${this.label}-${this.version}`;
    this.description = this.version;
  }

  iconPath = {
    light: path.join(__filename, '..', '..', 'resources', 'light', 'dependency.svg'),
    dark: path.join(__filename, '..', '..', 'resources', 'dark', 'dependency.svg')
  };
}
profile
There's Only One Thing To Do: Learn All We Can

0개의 댓글