vscode extension Webview에 react 적용하기 (1)
vscode에 있는 Webview를 더욱 더 활용하기 위해 react를 적용하는 방법에 대해서 외국사이트에서 튜토리얼이 있길래 가져와 본다. (라이센스도 MIT 라이센스임 )
Reactception : extending VS Code extension with webviews and React
VS code has become quite popular among coders these days. Being very open to modifications using “extension” really helped to expand the…
medium.com
위의 링크에 영어로 쏼라쏼라 알려주는데 영어 다 읽고 해석하기 귀찮아서 가져와 본다.
튜토리얼과 관련된 github도 제공된다 ( 성질급하신 분들은 코드 직접 가서 보셈 )
https://github.com/Ciaanh/reactception
GitHub - Ciaanh/reactception
Contribute to Ciaanh/reactception development by creating an account on GitHub.
github.com
완성화면
CTRL+SHIFT+P 누르고 뜨는 화면에서 Webview React 뭐시기 버튼 나옴, 클릭 후 자바스크립트 파일 아무거나 클릭
1. vscode extension 개발 시작하기.
- nodejs 설치 ( https://nodejs.org/ko/download/ 여기가서 다운로드하기, nodejs 환경변수 맞춰줘야 cmd창에서 씀 )
- vscode 설치 ( https://code.visualstudio.com/download 여기가서 다운로드하기 )
- npm으로 yo랑 generator-code 깔기, -g 옵션은 global임 시스템에 설치( npm install -g yo generator-code )
- create the extension project with : yo code
2. yo code 했을 때 시스템에서 묻는 질문들 답변
? What type of extension do you want to create? New Extension (TypeScript)
? What’s the name of your extension? vscode-react
? What’s the identifier of your extension? vscode-react
? What’s the description of your extension? Inception
? Initialize a git repository? Yes
? Which package manager to use? npm
이렇게 하라고 한다.
이렇게 만들어지면 vscode로 해당 생성된 프로젝트 접근하여, 수행하면 hello world 동작
3. language support 를 extension 프로젝트에 추가하기
(1) packages.json 파일에 contributes 항목으로 language 내용 추가하기
(2) commands rename 하기
(3) activationEvents rename 하기
{
"name": "vscode-react",
"displayName": "vscode-react",
"description": "Inception",
"version": "0.0.1",
"engines": {
"vscode": "^1.29.0"
},
"categories": [
"Other"
],
"activationEvents": [
"onCommand:extension.viewconfig" <<<(3)
],
"main": "./out/extension.js",
"contributes": { <<<< (1)
"languages": [
{
"id": "dummyconfig",
"aliases": [
"DummyConfig",
"dc"
],
"extensions": [
".json"
]
}
], <<< (1)
"commands": [
{ <<< (2)
"command": "extension.viewconfig",
"title": "Display config JSON.",
"category": "Webview React"
} <<< (2)
]
},
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./",
"postinstall": "node ./node_modules/vscode/bin/install",
"test": "npm run compile && node ./node_modules/vscode/bin/test"
},
"devDependencies": {
"typescript": "^3.3.1",
"vscode": "^1.1.28",
"tslint": "^5.12.1",
"@types/node": "^10.12.21",
"@types/mocha": "^2.2.42"
}
}
4. 기본 Webview 띄우기
extension.ts 는 메인인데 여기서 activate 함수 안에 webview를 띄울 수 있게 아래와 같이 코드를 세팅한다. 이 코드는 전체코드를 나타낸 것이 아니라 딱 그 부분만 가져온 거니까 전체코드 궁금하면 github 링크 ㄱㄱ ( step 2 임)
let openDialogOptions: vscode.OpenDialogOptions = {
canSelectFiles: true,
canSelectFolders: false,
canSelectMany: false,
filters: {
Json: ["json"]
}
};
vscode.window
.showOpenDialog(openDialogOptions)
.then(async (uri: vscode.Uri[] | undefined) => {
if (uri && uri.length > 0) {
//vscode.window.showInformationMessage(uri[0].fsPath); // << before 이게 그냥 지금은 메시지 띄우는건데 여기 웹뷰 띄우게 수정할거임
const view = new ViewLoader(uri[0]); // << after Webview 띄우기
} else {
vscode.window.showErrorMessage("No valid file selected!");
return;
}
});
}
webview 파일 ( 지금은 react 아니고 그냥 webview )
ViewLoader.ts 코딩 ( 그냥 webview 띄우기 )
import * as vscode from "vscode";
export default class ViewLoader {
private readonly _panel: vscode.WebviewPanel | undefined;
constructor(fileUri: vscode.Uri) {
this._panel = vscode.window.createWebviewPanel(
"configView",
"Config View",
vscode.ViewColumn.One,
{}
);
this._panel.webview.html = this.getWebviewContent(fileUri.fsPath);
}
private getWebviewContent(filepath: string): string {
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Config View</title>
</head>
<body>
<img src="https://media.giphy.com/media/uoAn5ik8zAuqI/giphy.gif" width="300" /><br/>
<code>${filepath}</code>
</body>
</html>`;
}
}
5. react app을 설치하기
설치할거 밑에 있음
npm install react react-dom
npm install --save-dev @types/react @types/react-dom
npm install — save-dev webpack webpack-cli
npm install --save-dev ts-loader style-loader css-loader npm-run-all
그 외 ts-loader css-loader 등등 설치할거 나중에 공지
6. react app 기본 세팅
(1) 파일 구조 세팅 : 그림과 같이 세팅하기 ( 빈파일들 만들기 )
(2) tsconfig.json 파일에는 내가 react app을 사용하고 configViewer이라는 폴더에 출력 디렉토리로 사용하겠다고 선언한다는 내용을 작성함. 이 폴더는 나중에 react app이랑 extension을 바인딩할 때 유용하게 사용됨.
아래는 tsconfig.json 파일 내용인데 대충 react app을 확장 프로젝트 루트에서 configViewer 폴더를 출력 디렉토리로 하겠다고 선언하고, react 쓰겠다고 하고, 이런 저런 설정들 넣는거임.
{
"compilerOptions": {
"module": "esnext",
"moduleResolution": "node",
"target": "es6",
"outDir": "configViewer",
"lib": [
"es6",
"dom"
],
"jsx": "react",
"sourceMap": true,
"rootDir": "..",
"noUnusedLocals": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"experimentalDecorators": true
},
"exclude": [
"node_modules"
]
}
(3) package.json 세팅하기 ( package.json )
react 쓰기 위해서 webpack build 설정을 추가해야한다. 아래와 같이 바꿔주기
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "npm-run-all compile:*",
"watch": "npm-run-all -p watch:*",
"compile:extension": "tsc -p ./",
"compile:views": "webpack --mode development",
"watch:extension": "tsc -watch -p ./",
"watch:views": "webpack --watch --mode development",
"postinstall": "node ./node_modules/vscode/bin/install",
"test": "npm run compile && node ./node_modules/vscode/bin/test"
},
(4) webpack.config.js 세팅하기
다른 loader 사용법을 선언하고 react 진입점을 정의한 뒤 react app 출력 폴더를 configViewer 폴더로 다시 설정하도록 하는 파일. (webpack 설정파일)
const path = require("path");
module.exports = {
entry: {
configViewer: "./src/view/app/index.tsx"
},
output: {
path: path.resolve(__dirname, "configViewer"),
filename: "[name].js"
},
devtool: "eval-source-map",
resolve: {
extensions: [".js", ".ts", ".tsx", ".json"]
},
module: {
rules: [
{
test: /\.(ts|tsx)$/,
loader: "ts-loader",
options: {}
},
{
test: /\.css$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader"
}
]
}
]
},
performance: {
hints: false
}
};
(5) root 디렉토리의 "tsconfig.json"을 편집 , ( react app을 범위에서 제외하도록 설정 )
"exclude": [
"node_modules",
".vscode-test",
"**/view/app/**"
]
(6) .gitignore 편집하여 "configViewer/configViewer.js" 에 대한 항목들이 git에 안올라가도록 한다. (저 파일은 빌드하면 컴터가 만드는 파일 )
(7) index.tsx 에 렌더링하는 내용을 추가한다.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import './index.css';
ReactDOM.render(
<h1>Hello</h1>,
document.getElementById('root')
);
여기까지가 내가 생각하는 스텝 1의 절차이고 스텝 2는 다음 포스트에서 추가적으로 올릴 예정
정리하면,
기본적으로 내가 생각하는 이 구조는
extension이 시작되면 extension.ts 에서 webview를 호출하는 데 ViewLoader.ts 코드가 react app을 호출하는 데 사용이 되고, ViewLoader.ts 에 getWebviewContent에선 react app을 부르기 위한 기본 밑작업 및 react app 호출을 담당하고 있고, 거기서 react 코드로 build시 생성된 configViewer.js를 호출한다. ( webpack.config.js 파일 보면 내용이 index.tsx 파일로 configViewer를 만든다고 되어있다. )
그래서 내가 생각할 땐 view/app 안에 있는 app들의 결과물은 결국 configViewer.js (빌드하면 만들어짐, 만들라고 위에서 세팅함) 이고 핵심은 react app문법들을 공부 및 공부해서 configViewer.js 같은 걸 rendering 잘 할수 있으면 되는 거 같다.
이게 왜 필요하냐면 vscode extension 개발할 때 react 를 사용하여 기존 webview에는 없던 react의 장점들을 활용할 수 있으니 알아두면 좋을거라 판단됨
to be continue..