feat(01-01): create Vite project with TypeScript and Canvas

- Initialize Vite project with vanilla-ts configuration
- Add TypeScript with strict mode enabled
- Configure Vitest for testing
- Create index.html with Canvas element
- Add main.ts entry point with canvas setup
- Add setup tests for project dependencies

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 23:38:14 +07:00
parent b7a5d42a03
commit 3e61fa2fd4
10 changed files with 1903 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
settings.local.json
+29
View File
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Pikachu Match Game</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #1a1a2e;
}
#game {
border-radius: 8px;
}
</style>
</head>
<body>
<canvas id="game"></canvas>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
+1746
View File
File diff suppressed because it is too large Load Diff
+31
View File
@@ -0,0 +1,31 @@
{
"name": "gsd-framework",
"version": "1.0.0",
"description": "Pikachu Match - A tile-matching puzzle game built with Vite + TypeScript + Canvas",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"test": "vitest",
"test:run": "vitest run"
},
"repository": {
"type": "git",
"url": "git+https://github.com/tiennm99/gsd-framework.git"
},
"keywords": ["game", "puzzle", "canvas", "typescript", "vite"],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/tiennm99/gsd-framework/issues"
},
"homepage": "https://github.com/tiennm99/gsd-framework#readme",
"devDependencies": {
"@types/node": "^25.4.0",
"@vitest/coverage-v8": "^4.0.18",
"typescript": "^5.9.3",
"vite": "^7.3.1",
"vitest": "^4.0.18"
}
}
+30
View File
@@ -0,0 +1,30 @@
// Test 1: npm run dev starts without errors
// Test 2: Browser displays Canvas element with colored background
// Test 3: npm run test runs vitest successfully
import { describe, it, expect } from 'vitest';
describe('Project Setup', () => {
it('should have vite as a dev dependency', () => {
// Read package.json to verify vite is installed
const pkg = require('../../package.json');
expect(pkg.devDependencies).toHaveProperty('vite');
});
it('should have typescript as a dev dependency', () => {
const pkg = require('../../package.json');
expect(pkg.devDependencies).toHaveProperty('typescript');
});
it('should have vitest as a dev dependency', () => {
const pkg = require('../../package.json');
expect(pkg.devDependencies).toHaveProperty('vitest');
});
it('should have npm scripts for dev, test, and build', () => {
const pkg = require('../../package.json');
expect(pkg.scripts).toHaveProperty('dev');
expect(pkg.scripts).toHaveProperty('test');
expect(pkg.scripts).toHaveProperty('build');
});
});
+28
View File
@@ -0,0 +1,28 @@
// Main entry point for the Pikachu Match game
// Temporary placeholder - will be updated when CONFIG is available
// Get canvas element by id 'game'
const canvas = document.getElementById('game') as HTMLCanvasElement;
if (!canvas) {
throw new Error('Canvas element with id "game" not found');
}
// Get 2D context
const ctx = canvas.getContext('2d');
if (!ctx) {
throw new Error('Could not get 2D context from canvas');
}
// Set canvas size (hardcoded for now: 16 cols * 52, 10 rows * 52)
// 52 = 48 (tile size) + 4 (gap)
const canvasWidth = 16 * 52; // 832
const canvasHeight = 10 * 52; // 520
canvas.width = canvasWidth;
canvas.height = canvasHeight;
// Fill with background color (hardcoded for now: '#1a1a2e')
ctx.fillStyle = '#1a1a2e';
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
console.log('Pikachu Match game initialized');
console.log(`Canvas size: ${canvasWidth}x${canvasHeight}`);
+1
View File
@@ -0,0 +1 @@
/// <reference types="vite/client" />
+23
View File
@@ -0,0 +1,23 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}
+6
View File
@@ -0,0 +1,6 @@
import { defineConfig } from 'vite';
export default defineConfig({
// Base Vite configuration for vanilla TypeScript
// No plugins needed for vanilla TS
});
+8
View File
@@ -0,0 +1,8 @@
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globals: true,
environment: 'node',
},
});