이 가이드는 다음과 같은 목표를 가집니다:
> ✅ 개발자가 로컬에서 Playwright 기반 스크립트 실행 엔진을 구축하고,
> ✅ 웹에서 저장된 JavaScript 코드를 동적으로 실행할 수 있도록 준비
---
# 🚀 Playwright 실행 엔진
## 개발자 환경 설치 및 개발 가이드
---
## 📋 목차
1. [필요한 도구 설치](#1-필수-도구-설치)
2. [프로젝트 생성](#2-프로젝트-생성)
3. [Playwright 설치 및 설정](#3-playwright-설치-및-설정)
4. [기본 스크립트 실행기 개발](#4-기본-스크립트-실행기-개발)
5. [보안 강화: 샌드박스 적용 (vm2)](#5-보안-강화-샌드박스-적용-vm2)
6. [실행 예제 및 테스트](#6-실행-예제-및-테스트)
7. [다음 단계: API 서버 연동](#7-다음-단계-api-서버-연동)
---
## 1. ✅ 필수 도구 설치
### 1.1 Node.js 설치 (v16 이상 권장)
- 다운로드: [https://nodejs.org](https://nodejs.org)
- 확인:
```bash
node --version # v16.x 이상
npm --version # 8.x 이상
```
### 1.2 텍스트 에디터 (VS Code 추천)
- 다운로드: [https://code.visualstudio.com](https://code.visualstudio.com)
- 추천 확장:
- **ESLint**
- **Prettier**
- **Playwright Test for VS Code**
---
## 2. 📂 프로젝트 생성
```bash
mkdir playwright-runner
cd playwright-runner
npm init -y
```
---
## 3. 🧰 Playwright 설치 및 설정
### 3.1 Playwright 설치
```bash
npm install @playwright/test
```
### 3.2 브라우저 설치
```bash
npx playwright install
```
> ✅ Chromium, Firefox, WebKit 설치됨
(선택) Linux 사용자라면 의존성도 설치:
```bash
npx playwright install-deps
```
---
## 4. 🧪 기본 스크립트 실행기 개발
### 4.1 파일 생성: `runner.js`
```javascript
// runner.js
const { chromium } = require('playwright');
// 브라우저 재사용 (성능 향상)
let browser = null;
async function getBrowser() {
if (!browser) {
browser = await chromium.launch({ headless: true }); // false로 하면 창 보임
}
return browser;
}
/**
* 외부 JS 코드를 실행
* @param {string} code - 사용자 정의 Playwright 코드 (문자열)
* @returns {Promise<Object>} 실행 결과 또는 에러
*/
async function runUserScript(code) {
const browser = await getBrowser();
const context = await browser.newContext();
const page = await context.newPage();
try {
// 주의: new Function은 보안 위험 있음 (나중에 샌드박스 처리)
const scriptFunction = new Function('page', code);
await scriptFunction(page);
await context.close();
return { success: true, message: '스크립트 성공적으로 실행됨' };
} catch (error) {
await context.close();
return { success: false, error: error.message };
}
}
module.exports = { runUserScript, getBrowser };
```
---
## 5. 🔐 보안 강화: 샌드박스 적용 (vm2)
> ⚠️ `new Function()`은 코드 주입 위험이 큼 → `vm2`로 샌드박스
### 5.1 vm2 설치
```bash
npm install vm2
```
### 5.2 보안 실행기: `secure-runner.js`
```javascript
// secure-runner.js
const { chromium } = require('playwright');
const { NodeVM } = require('vm2');
let browser = null;
async function getBrowser() {
if (!browser) {
browser = await chromium.launch({ headless: true });
}
return browser;
}
/**
* 샌드박스 환경에서 코드 실행
* @param {string} code - 사용자 코드
* @returns {Promise<Object>}
*/
async function runUserScriptSecure(code) {
const browser = await getBrowser();
const context = await browser.newContext();
const page = await context.newPage();
const vm = new NodeVM({
sandbox: { page }, // page 객체만 허용
require: {
external: false, // 외부 모듈 차단
builtin: [] // 허용된 내장 모듈 없음
}
});
try {
// 비동기 코드를 즉시 실행하는 IIFE로 감쌈
const wrappedCode = `(async () => { ${code} })();`;
await vm.run(wrappedCode, __filename);
await context.close();
return { success: true, message: '성공' };
} catch (error) {
await context.close();
return { success: false, error: error.message };
}
}
module.exports = { runUserScriptSecure, getBrowser };
```
---
## 6. 🧪 실행 예제 및 테스트
### 6.1 테스트 스크립트: `test.js`
```javascript
// test.js
const { runUserScriptSecure } = require('./secure-runner');
const testScript = `
await page.goto('https://example.com');
console.log('페이지 제목:', await page.title());
await page.screenshot({ path: 'example.png' });
await page.waitForTimeout(1000);
`;
(async () => {
console.log('🟢 스크립트 실행 시작...');
const result = await runUserScriptSecure(testScript);
if (result.success) {
console.log('✅ 성공:', result.message);
} else {
console.error('❌ 실패:', result.error);
}
})();
```
### 6.2 실행
```bash
node test.js
```
> ✅ 성공 시: `example.png` 파일 생성 및 로그 출력
---
## 7. 🔄 다음 단계: API 서버 연동 (Express 기반)
### 7.1 Express 설치
```bash
npm install express
```
### 7.2 `server.js` 생성
```javascript
// server.js
const express = require('express');
const { runUserScriptSecure } = require('./secure-runner');
const app = express();
app.use(express.json());
// 스크립트 실행 엔드포인트
app.post('/run', async (req, res) => {
const { code } = req.body;
if (!code) {
return res.status(400).json({ error: '코드가 필요합니다.' });
}
console.log('실행 요청 수신');
const result = await runUserScriptSecure(code);
res.json(result);
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`🚀 서버 실행 중: http://localhost:${PORT}`);
});
```
### 7.3 서버 실행
```bash
node server.js
```
### 7.4 테스트 요청 (예: curl)
```bash
curl -X POST http://localhost:3000/run \
-H "Content-Type: application/json" \
-d '{
"code": "await page.goto(\"https://example.com\"); await page.screenshot({ path: \"test.png\" });"
}'
```
---
## 🧰 개발 환경 정리
| 항목 | 버전/설정 |
|------|----------|
| Node.js | v16 이상 |
| npm | v8 이상 |
| Playwright | 최신 버전 |
| 브라우저 | Chromium, Firefox, WebKit |
| 보안 | vm2 사용 (샌드박스) |
| 실행 모드 | headless: true (배포용), false (디버깅용) |
---
## 🛠️ 개발 팁
| 팁 | 설명 |
|----|------|
| 🐞 디버깅 | `headless: false`로 설정하면 브라우저 창이 보임 |
| 📦 의존성 관리 | `package.json`에 스크립트 추가: `"dev": "node test.js"` |
| 🧹 정리 | 브라우저 종료: `await browser.close()` (개발 중에는 생략 가능) |
| ⏳ 타임아웃 | `page.setDefaultTimeout(10000)` 설정 가능 |
| 🖼️ 스크린샷 | 경로를 동적으로 설정: `screenshot-${Date.now()}.png` |
---
## 📚 참고 문서
- Playwright 공식 문서: [https://playwright.dev](https://playwright.dev)
- vm2 GitHub: [https://github.com/patriksimek/vm2](https://github.com/patriksimek/vm2)
- Express.js: [https://expressjs.com](https://expressjs.com)
---
## 🎁 최종 폴더 구조
```
playwright-runner/
├── node_modules/
├── runner.js # 기본 실행기
├── secure-runner.js # 보안 실행기 (vm2)
├── test.js # 테스트 코드
├── server.js # Express API 서버
├── example.png # 출력 파일
├── package.json
└── package-lock.json
'AI' 카테고리의 다른 글
Windows 11에서 Playwright 실행 엔진 개발하기 (0) | 2025.08.25 |
---|---|
웹페이지에 JavaScript/TypeScript 스크립트를 저장하고, 이를 Playwright로 동적으로 실행하는 아키텍처와 개발 방법 (0) | 2025.08.25 |
playwright (1) | 2025.08.25 |
2025년 8월 유용한 AI 관련 소식 (1) | 2025.08.21 |
개발자들이 AI를 효과적으로 활용하기 위한 50가지 팁 (0) | 2025.08.21 |