- 스크립트 언어
- 기존에 존재하는 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
하여 사용
- 라이브러리와 유사한 개념
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의
collapsibleState
는 TreeItemCollapsibleState.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')
};
}