实现小游戏与小程序项目创建发布
This commit is contained in:
139
electron/opencode/project-template.ts
Normal file
139
electron/opencode/project-template.ts
Normal file
@@ -0,0 +1,139 @@
|
||||
import { dirname, join } from 'node:path';
|
||||
import { mkdir, writeFile } from 'node:fs/promises';
|
||||
import type { ProjectType } from '../../shared/project-config';
|
||||
import vitePackageJson from './project-templates/vite/package.json';
|
||||
import vitePackageLock from './project-templates/vite/package-lock.json';
|
||||
|
||||
const VITE_CONFIG = `import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
base: './',
|
||||
});
|
||||
`;
|
||||
|
||||
const MINI_GAME_FILES: Record<string, string> = {
|
||||
'index.html': `<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<title>Makelore 小游戏</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
html, body { width: 100%; height: 100%; margin: 0; overflow: hidden; background: #10233d; }
|
||||
body { display: grid; place-items: center; font-family: system-ui, sans-serif; }
|
||||
#game { width: 100%; height: 100%; touch-action: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="game" aria-label="Makelore 小游戏画布"></canvas>
|
||||
<script type="module" src="/game.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
`,
|
||||
'game.json': `${JSON.stringify({ deviceOrientation: 'portrait', showStatusBar: false }, null, 2)}\n`,
|
||||
'game.js': `const canvas = document.querySelector('#game');
|
||||
const context = canvas.getContext('2d');
|
||||
|
||||
function render() {
|
||||
const ratio = window.devicePixelRatio || 1;
|
||||
const width = window.innerWidth;
|
||||
const height = window.innerHeight;
|
||||
canvas.width = Math.round(width * ratio);
|
||||
canvas.height = Math.round(height * ratio);
|
||||
context.setTransform(ratio, 0, 0, ratio, 0, 0);
|
||||
|
||||
const gradient = context.createLinearGradient(0, 0, 0, height);
|
||||
gradient.addColorStop(0, '#10233d');
|
||||
gradient.addColorStop(1, '#3a5578');
|
||||
context.fillStyle = gradient;
|
||||
context.fillRect(0, 0, width, height);
|
||||
|
||||
context.textAlign = 'center';
|
||||
context.fillStyle = '#ffffff';
|
||||
context.font = '700 28px system-ui, sans-serif';
|
||||
context.fillText('Makelore 小游戏', width / 2, height / 2 - 10);
|
||||
context.fillStyle = '#f6b45f';
|
||||
context.font = '16px system-ui, sans-serif';
|
||||
context.fillText('点击画布,开始创造', width / 2, height / 2 + 26);
|
||||
}
|
||||
|
||||
canvas.addEventListener('pointerdown', (event) => {
|
||||
context.beginPath();
|
||||
context.fillStyle = '#f26a3d';
|
||||
context.arc(event.clientX, event.clientY, 18, 0, Math.PI * 2);
|
||||
context.fill();
|
||||
});
|
||||
window.addEventListener('resize', render);
|
||||
render();
|
||||
`,
|
||||
};
|
||||
|
||||
const MINI_PROGRAM_FILES: Record<string, string> = {
|
||||
'index.html': `<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Makelore 小程序</title>
|
||||
</head>
|
||||
<body>
|
||||
<main id="app"></main>
|
||||
<script type="module" src="/pages/index/index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
`,
|
||||
'app.json': `${JSON.stringify({ pages: ['pages/index/index'], window: { navigationBarTitleText: 'Makelore 小程序' } }, null, 2)}\n`,
|
||||
'app.js': `export const app = {
|
||||
globalData: {
|
||||
platform: 'makelore',
|
||||
},
|
||||
};
|
||||
`,
|
||||
'pages/index/index.json': `${JSON.stringify({ navigationBarTitleText: '首页' }, null, 2)}\n`,
|
||||
'pages/index/index.css': `:root {
|
||||
color: #24364b;
|
||||
background: #f4f7fb;
|
||||
font-family: system-ui, sans-serif;
|
||||
}
|
||||
|
||||
body { margin: 0; }
|
||||
.page { min-height: 100vh; display: grid; place-items: center; padding: 24px; }
|
||||
.card { width: min(420px, 100%); border: 1px solid #d8e1ec; border-radius: 20px; background: #fff; padding: 28px; text-align: center; box-shadow: 0 16px 48px rgb(36 54 75 / 10%); }
|
||||
button { border: 0; border-radius: 12px; background: #3a5578; color: #fff; padding: 12px 18px; font: inherit; font-weight: 700; cursor: pointer; }
|
||||
`,
|
||||
'pages/index/index.js': `import { app } from '../../app.js';
|
||||
import './index.css';
|
||||
|
||||
const root = document.querySelector('#app');
|
||||
let count = 0;
|
||||
root.innerHTML = \`<section class="page"><div class="card"><p>运行于 \${app.globalData.platform}</p><h1>Makelore 小程序</h1><p id="count">已点击 0 次</p><button type="button">点我试试</button></div></section>\`;
|
||||
root.querySelector('button').addEventListener('click', () => {
|
||||
count += 1;
|
||||
root.querySelector('#count').textContent = \`已点击 \${count} 次\`;
|
||||
});
|
||||
`,
|
||||
};
|
||||
|
||||
function serializeJson(value: unknown): string {
|
||||
return `${JSON.stringify(value, null, 2)}\n`;
|
||||
}
|
||||
|
||||
export async function createPublishableProjectTemplate(
|
||||
projectPath: string,
|
||||
projectType: Exclude<ProjectType, 'custom'>,
|
||||
): Promise<void> {
|
||||
const files = projectType === 'mini_game' ? MINI_GAME_FILES : MINI_PROGRAM_FILES;
|
||||
const templateFiles: Record<string, string> = {
|
||||
'package.json': serializeJson(vitePackageJson),
|
||||
'package-lock.json': serializeJson(vitePackageLock),
|
||||
'vite.config.js': VITE_CONFIG,
|
||||
...files,
|
||||
};
|
||||
|
||||
for (const [relativePath, content] of Object.entries(templateFiles)) {
|
||||
const filePath = join(projectPath, relativePath);
|
||||
await mkdir(dirname(filePath), { recursive: true });
|
||||
await writeFile(filePath, content, { encoding: 'utf8', flag: 'wx' });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user