@mrbryan1502/create-symfony-vue 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/index.js +142 -0
- package/package.json +30 -0
- package/template/.editorconfig +25 -0
- package/template/.env +48 -0
- package/template/.env.dev +4 -0
- package/template/.env.test +3 -0
- package/template/.gitattributes +9 -0
- package/template/.prettierignore +46 -0
- package/template/.prettierrc +9 -0
- package/template/.vscode/extensions.json +17 -0
- package/template/.vscode/settings.json +19 -0
- package/template/README.md +172 -0
- package/template/assets/app.css +3 -0
- package/template/assets/main.ts +11 -0
- package/template/assets/router/index.ts +13 -0
- package/template/assets/src/App.vue +571 -0
- package/template/assets/styles/app.css +3 -0
- package/template/bin/console +21 -0
- package/template/bin/phpunit +4 -0
- package/template/compose.override.yaml +18 -0
- package/template/compose.yaml +25 -0
- package/template/composer.json +122 -0
- package/template/composer.lock +10332 -0
- package/template/config/bundles.php +16 -0
- package/template/config/preload.php +5 -0
- package/template/config/reference.php +1696 -0
- package/template/config/routes/framework.yaml +4 -0
- package/template/config/routes/pentatrion_vite.yaml +9 -0
- package/template/config/routes/security.yaml +3 -0
- package/template/config/routes/web_profiler.yaml +8 -0
- package/template/config/routes.yaml +11 -0
- package/template/config/services.yaml +23 -0
- package/template/importmap.php +22 -0
- package/template/package.json +47 -0
- package/template/phpunit.dist.xml +44 -0
- package/template/pnpm-lock.yaml +2715 -0
- package/template/public/index.php +9 -0
- package/template/src/Controller/AppController.php +16 -0
- package/template/src/Kernel.php +11 -0
- package/template/symfony.lock +319 -0
- package/template/templates/app.html.twig +13 -0
- package/template/templates/base.html.twig +26 -0
- package/template/tests/bootstrap.php +13 -0
- package/template/tsconfig.json +17 -0
- package/template/vite.config.js +29 -0
package/bin/index.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { existsSync, mkdirSync, readdirSync, copyFileSync, readFileSync, writeFileSync, rmSync } from 'fs';
|
|
4
|
+
import { join, resolve, dirname, basename } from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { execSync } from 'child_process';
|
|
7
|
+
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const TEMPLATE_DIR = resolve(__dirname, '..', 'template');
|
|
10
|
+
const IGNORE = new Set([
|
|
11
|
+
'.git',
|
|
12
|
+
'node_modules',
|
|
13
|
+
'vendor',
|
|
14
|
+
'var',
|
|
15
|
+
'packages',
|
|
16
|
+
'.env.local',
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
function copyRecursive(src, dest) {
|
|
20
|
+
if (!existsSync(src)) return;
|
|
21
|
+
const entries = readdirSync(src, { withFileTypes: true });
|
|
22
|
+
mkdirSync(dest, { recursive: true });
|
|
23
|
+
|
|
24
|
+
for (const entry of entries) {
|
|
25
|
+
if (IGNORE.has(entry.name)) continue;
|
|
26
|
+
const srcPath = join(src, entry.name);
|
|
27
|
+
const destPath = join(dest, entry.name);
|
|
28
|
+
|
|
29
|
+
if (entry.isDirectory()) {
|
|
30
|
+
copyRecursive(srcPath, destPath);
|
|
31
|
+
} else {
|
|
32
|
+
copyFileSync(srcPath, destPath);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function hasTool(cmd) {
|
|
38
|
+
try { execSync(`${cmd} --version`, { stdio: 'ignore' }); return true; }
|
|
39
|
+
catch { return false; }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function detectPackageManager() {
|
|
43
|
+
if (hasTool('pnpm')) return 'pnpm';
|
|
44
|
+
if (hasTool('yarn')) return 'yarn';
|
|
45
|
+
if (hasTool('bun')) return 'bun';
|
|
46
|
+
return 'npm';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function sanitizeName(name) {
|
|
50
|
+
return basename(name).toLowerCase().replace(/[^a-z0-9_-]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function printBanner(name) {
|
|
54
|
+
console.log('');
|
|
55
|
+
console.log(' \x1b[38;2;74;144;226m\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510');
|
|
56
|
+
console.log(` \x1b[38;2;74;144;226m\u2502 \x1b[0m\x1b[1mSymfony\x1b[0m \x1b[38;2;74;144;226m+\x1b[0m \x1b[1m\x1b[38;2;66;184;131mVue 3\x1b[0m \x1b[38;2;74;144;226m\xB7 Plantilla moderna\x1b[38;2;74;144;226m \u2502`);
|
|
57
|
+
console.log(` \x1b[38;2;74;144;226m\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\x1b[0m`);
|
|
58
|
+
console.log('');
|
|
59
|
+
console.log(` \u2728 Proyecto creado: \x1b[1m${name}\x1b[0m`);
|
|
60
|
+
console.log('');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function printDone(dir, pm) {
|
|
64
|
+
console.log('');
|
|
65
|
+
console.log(' \x1b[32m\u2714\x1b[0m Dependencias instaladas correctamente');
|
|
66
|
+
console.log('');
|
|
67
|
+
console.log(' \x1b[1mPr\xf3ximos pasos:\x1b[0m');
|
|
68
|
+
console.log('');
|
|
69
|
+
console.log(` $ \x1b[36mcd ${dir}\x1b[0m`);
|
|
70
|
+
console.log(` $ \x1b[36m${pm} dev\x1b[0m`);
|
|
71
|
+
console.log('');
|
|
72
|
+
console.log(' \x1b[90m\xa1Disfruta codificando!\x1b[0m');
|
|
73
|
+
console.log('');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// --- Main ---
|
|
77
|
+
|
|
78
|
+
const projectName = process.argv[2];
|
|
79
|
+
|
|
80
|
+
if (!projectName) {
|
|
81
|
+
console.error('\n \x1b[31mError:\x1b[0m Debes especificar un nombre para el proyecto');
|
|
82
|
+
console.error('');
|
|
83
|
+
console.error(' \x1b[1mUso:\x1b[0m');
|
|
84
|
+
console.error(` $ npx @mrbryan1502/create-symfony-vue \x1b[33m<project-name>\x1b[0m`);
|
|
85
|
+
console.error(` $ pnpm dlx @mrbryan1502/create-symfony-vue \x1b[33m<project-name>\x1b[0m`);
|
|
86
|
+
console.error('');
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const projectDir = resolve(process.cwd(), projectName);
|
|
91
|
+
|
|
92
|
+
if (existsSync(projectDir)) {
|
|
93
|
+
const entries = readdirSync(projectDir);
|
|
94
|
+
if (entries.length > 0) {
|
|
95
|
+
console.error(`\n \x1b[31mError:\x1b[0m El directorio "${projectName}" ya existe y no est\xe1 vac\xedo\n`);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
console.log(`\n \x1b[90mCreando proyecto\x1b[0m ${projectName} \x1b[90m...\x1b[0m\n`);
|
|
101
|
+
|
|
102
|
+
copyRecursive(TEMPLATE_DIR, projectDir);
|
|
103
|
+
|
|
104
|
+
// Update composer.json name
|
|
105
|
+
const composerJsonPath = join(projectDir, 'composer.json');
|
|
106
|
+
try {
|
|
107
|
+
const content = readFileSync(composerJsonPath, 'utf-8');
|
|
108
|
+
const json = JSON.parse(content);
|
|
109
|
+
json.name = sanitizeName(projectName);
|
|
110
|
+
writeFileSync(composerJsonPath, JSON.stringify(json, null, 4) + '\n');
|
|
111
|
+
} catch {}
|
|
112
|
+
|
|
113
|
+
printBanner(projectName);
|
|
114
|
+
|
|
115
|
+
// Install Composer dependencies
|
|
116
|
+
const hasComposer = hasTool('composer');
|
|
117
|
+
if (hasComposer) {
|
|
118
|
+
console.log(' \x1b[90mInstalando dependencias PHP (composer install) ...\x1b[0m');
|
|
119
|
+
execSync('composer install --no-interaction', { cwd: projectDir, stdio: 'inherit' });
|
|
120
|
+
} else {
|
|
121
|
+
console.log(' \x1b[33m\u26a0\x1b[0m \x1b[90mComposer no est\xe1 instalado. Ejecuta "composer install" manualmente.\x1b[0m');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Install Node dependencies
|
|
125
|
+
const pm = detectPackageManager();
|
|
126
|
+
console.log(` \x1b[90mInstalando dependencias frontend (${pm} install) ...\x1b[0m`);
|
|
127
|
+
execSync(`${pm} install`, { cwd: projectDir, stdio: 'inherit' });
|
|
128
|
+
|
|
129
|
+
// Clean up .git from template if present
|
|
130
|
+
const templateGit = join(projectDir, '.git');
|
|
131
|
+
if (existsSync(templateGit)) {
|
|
132
|
+
rmSync(templateGit, { recursive: true, force: true });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Initialize new git repo
|
|
136
|
+
try {
|
|
137
|
+
execSync('git init', { cwd: projectDir, stdio: 'ignore' });
|
|
138
|
+
execSync('git add .', { cwd: projectDir, stdio: 'ignore' });
|
|
139
|
+
execSync('git commit -m "Initial commit from create-symfony-vue"', { cwd: projectDir, stdio: 'ignore' });
|
|
140
|
+
} catch {}
|
|
141
|
+
|
|
142
|
+
printDone(projectName, pm);
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mrbryan1502/create-symfony-vue",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Scaffold a new Symfony 7 + Vue 3 project",
|
|
5
|
+
"author": "mrbryan1502",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"create-symfony-vue": "bin/index.js"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"bin",
|
|
15
|
+
"template"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=18"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"symfony",
|
|
22
|
+
"vue",
|
|
23
|
+
"vue3",
|
|
24
|
+
"symfony7",
|
|
25
|
+
"vite",
|
|
26
|
+
"scaffold",
|
|
27
|
+
"template"
|
|
28
|
+
],
|
|
29
|
+
"license": "MIT"
|
|
30
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# editorconfig.org
|
|
2
|
+
|
|
3
|
+
root = true
|
|
4
|
+
|
|
5
|
+
[*.{php}]
|
|
6
|
+
charset = utf-8
|
|
7
|
+
end_of_line = lf
|
|
8
|
+
indent_size = 4
|
|
9
|
+
indent_style = space
|
|
10
|
+
insert_final_newline = true
|
|
11
|
+
trim_trailing_whitespace = true
|
|
12
|
+
|
|
13
|
+
[{compose.yaml,compose.*.yaml}]
|
|
14
|
+
indent_size = 2
|
|
15
|
+
|
|
16
|
+
[*.md]
|
|
17
|
+
trim_trailing_whitespace = false
|
|
18
|
+
|
|
19
|
+
[*.{ts,vue,js,jsx,tsx}]
|
|
20
|
+
charset = utf-8
|
|
21
|
+
end_of_line = lf
|
|
22
|
+
indent_size = 2
|
|
23
|
+
indent_style = space
|
|
24
|
+
insert_final_newline = true
|
|
25
|
+
trim_trailing_whitespace = true
|
package/template/.env
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# In all environments, the following files are loaded if they exist,
|
|
2
|
+
# the latter taking precedence over the former:
|
|
3
|
+
#
|
|
4
|
+
# * .env contains default values for the environment variables needed by the app
|
|
5
|
+
# * .env.local uncommitted file with local overrides
|
|
6
|
+
# * .env.$APP_ENV committed environment-specific defaults
|
|
7
|
+
# * .env.$APP_ENV.local uncommitted environment-specific overrides
|
|
8
|
+
#
|
|
9
|
+
# Real environment variables win over .env files.
|
|
10
|
+
#
|
|
11
|
+
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
|
|
12
|
+
# https://symfony.com/doc/current/configuration/secrets.html
|
|
13
|
+
#
|
|
14
|
+
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
|
|
15
|
+
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
|
|
16
|
+
|
|
17
|
+
###> symfony/framework-bundle ###
|
|
18
|
+
APP_ENV=dev
|
|
19
|
+
APP_SECRET=
|
|
20
|
+
APP_SHARE_DIR=var/share
|
|
21
|
+
###< symfony/framework-bundle ###
|
|
22
|
+
|
|
23
|
+
###> symfony/routing ###
|
|
24
|
+
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
|
|
25
|
+
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
|
|
26
|
+
DEFAULT_URI=http://localhost
|
|
27
|
+
###< symfony/routing ###
|
|
28
|
+
|
|
29
|
+
###> doctrine/doctrine-bundle ###
|
|
30
|
+
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
|
|
31
|
+
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
|
|
32
|
+
#
|
|
33
|
+
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data_%kernel.environment%.db"
|
|
34
|
+
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4"
|
|
35
|
+
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4"
|
|
36
|
+
DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8"
|
|
37
|
+
###< doctrine/doctrine-bundle ###
|
|
38
|
+
|
|
39
|
+
###> symfony/messenger ###
|
|
40
|
+
# Choose one of the transports below
|
|
41
|
+
# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
|
|
42
|
+
# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
|
|
43
|
+
MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
|
|
44
|
+
###< symfony/messenger ###
|
|
45
|
+
|
|
46
|
+
###> symfony/mailer ###
|
|
47
|
+
MAILER_DSN=null://null
|
|
48
|
+
###< symfony/mailer ###
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
|
|
2
|
+
###> Symfony ###
|
|
3
|
+
/src/
|
|
4
|
+
/templates/
|
|
5
|
+
/tests/
|
|
6
|
+
/translations/
|
|
7
|
+
/public/
|
|
8
|
+
/migrations/
|
|
9
|
+
/config/
|
|
10
|
+
/bin/
|
|
11
|
+
###< Symfony ###
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
###> symfony/framework-bundle ###
|
|
15
|
+
/.env.local
|
|
16
|
+
/.env.local.php
|
|
17
|
+
/.env.*.local
|
|
18
|
+
/config/secrets/prod/prod.decrypt.private.php
|
|
19
|
+
/public/bundles/
|
|
20
|
+
/var/
|
|
21
|
+
/vendor/
|
|
22
|
+
###< symfony/framework-bundle ###
|
|
23
|
+
|
|
24
|
+
###> phpunit/phpunit ###
|
|
25
|
+
/phpunit.xml
|
|
26
|
+
/.phpunit.cache/
|
|
27
|
+
###< phpunit/phpunit ###
|
|
28
|
+
|
|
29
|
+
###> symfony/asset-mapper ###
|
|
30
|
+
/public/assets/
|
|
31
|
+
/assets/vendor/
|
|
32
|
+
###< symfony/asset-mapper ###
|
|
33
|
+
|
|
34
|
+
###> node ###
|
|
35
|
+
/node_modules/
|
|
36
|
+
###< node ###
|
|
37
|
+
|
|
38
|
+
###> Configuration ###
|
|
39
|
+
/composer.json
|
|
40
|
+
/composer.lock
|
|
41
|
+
/*.yaml
|
|
42
|
+
/*.yml
|
|
43
|
+
/importmap.php
|
|
44
|
+
/symfony.lock
|
|
45
|
+
/.vscode/
|
|
46
|
+
###< Configuration ###
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"recommendations": [
|
|
3
|
+
"esbenp.prettier-vscode",
|
|
4
|
+
"dbaeumer.vscode-eslint",
|
|
5
|
+
"EditorConfig.EditorConfig",
|
|
6
|
+
"usernamehw.errorlens",
|
|
7
|
+
"DEVSENSE.phptools-vscode",
|
|
8
|
+
"bmewburn.vscode-intelephense-client",
|
|
9
|
+
"bajdzis.vscode-twig-pack",
|
|
10
|
+
"Vue.volar",
|
|
11
|
+
"DEVSENSE.intelli-php-vscode",
|
|
12
|
+
"DEVSENSE.composer-php-vscode",
|
|
13
|
+
"xdebug.php-pack",
|
|
14
|
+
"xdebug.php-debug",
|
|
15
|
+
"zobo.php-intellisense"
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"[typescript]": {
|
|
3
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
4
|
+
"editor.formatOnSave": true
|
|
5
|
+
},
|
|
6
|
+
"[vue]": {
|
|
7
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
8
|
+
"editor.formatOnSave": true
|
|
9
|
+
},
|
|
10
|
+
"[javascript]": {
|
|
11
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
12
|
+
"editor.formatOnSave": true
|
|
13
|
+
},
|
|
14
|
+
"editor.quickSuggestions": {
|
|
15
|
+
"comments": "on",
|
|
16
|
+
"strings": "on",
|
|
17
|
+
"other": "on"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Symfony + Vue 3 Template
|
|
2
|
+
|
|
3
|
+
Plantilla moderna para aplicaciones web con **Symfony 7** en el backend y **Vue 3** + **TypeScript** en el frontend, integrados mediante Vite.
|
|
4
|
+
|
|
5
|
+
## Stack
|
|
6
|
+
|
|
7
|
+
| Capa | Tecnología |
|
|
8
|
+
| -------- | ------------------------------------------------------------ |
|
|
9
|
+
| Backend | [Symfony 7.4](https://symfony.com) + PHP 8.2+ / Doctrine ORM / PostgreSQL |
|
|
10
|
+
| Frontend | [Vue 3](https://vuejs.org) + TypeScript + Pinia + Vue Router |
|
|
11
|
+
| Build | [Vite](https://vitejs.dev) + `vite-plugin-symfony` + `@vitejs/plugin-vue` |
|
|
12
|
+
| Estilo | CSS moderno con design system oscuro y gradientes |
|
|
13
|
+
|
|
14
|
+
## Instalación
|
|
15
|
+
|
|
16
|
+
Puedes crear un nuevo proyecto de dos formas:
|
|
17
|
+
|
|
18
|
+
### Via Composer (recomendado)
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
composer create-project mrbryan1502/symfony-vue mi-app
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Esto instala automáticamente las dependencias de PHP **y** las de frontend (pnpm).
|
|
25
|
+
|
|
26
|
+
### Via npx / pnpm dlx
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Con npm
|
|
30
|
+
npx @mrbryan1502/create-symfony-vue mi-app
|
|
31
|
+
|
|
32
|
+
# Con pnpm
|
|
33
|
+
pnpm dlx @mrbryan1502/create-symfony-vue mi-app
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Esto crea el proyecto e instala tanto las dependencias PHP (composer) como las de frontend (npm/pnpm/yarn automáticamente detectado).
|
|
37
|
+
|
|
38
|
+
### Manualmente (clonando el repo)
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
git clone https://github.com/mrbryan1502/symfony-vue.git mi-app
|
|
42
|
+
cd mi-app
|
|
43
|
+
|
|
44
|
+
# Las dependencias se instalan automáticamente con cualquiera de estos:
|
|
45
|
+
composer install # instala PHP + dispara pnpm install
|
|
46
|
+
pnpm install # instala frontend + dispara composer install
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Requisitos
|
|
50
|
+
|
|
51
|
+
- PHP >= 8.2
|
|
52
|
+
- [Composer](https://getcomposer.org)
|
|
53
|
+
- [pnpm](https://pnpm.io) >= 11.9 (o npm/yarn/bun)
|
|
54
|
+
- [Symfony CLI](https://symfony.com/download) (recomendado para desarrollo)
|
|
55
|
+
|
|
56
|
+
## Ejecución en desarrollo
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
cd mi-app
|
|
60
|
+
pnpm dev
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Esto lanza simultáneamente:
|
|
64
|
+
|
|
65
|
+
- `symfony serve` — servidor PHP de desarrollo
|
|
66
|
+
- `vite` — servidor de assets con HMR
|
|
67
|
+
|
|
68
|
+
Abrir `https://localhost:8000` en el navegador.
|
|
69
|
+
|
|
70
|
+
### Variables de entorno
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
cp .env .env.local
|
|
74
|
+
# Editar DATABASE_URL y APP_SECRET en .env.local
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Comandos útiles
|
|
78
|
+
|
|
79
|
+
| Comando | Descripción |
|
|
80
|
+
| -------------------- | ----------------------------------- |
|
|
81
|
+
| `pnpm dev` | Desarrollo con hot reload |
|
|
82
|
+
| `pnpm build` | Build de producción para frontend |
|
|
83
|
+
| `pnpm format` | Formatear código con Prettier |
|
|
84
|
+
| `pnpm lint` | Verificar formato |
|
|
85
|
+
| `composer run-script`| Scripts definidos en `composer.json`|
|
|
86
|
+
|
|
87
|
+
## Estructura del proyecto
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
symfony-vue/
|
|
91
|
+
├── assets/ # Frontend (Vue 3 + TypeScript)
|
|
92
|
+
│ ├── main.ts # Punto de entrada
|
|
93
|
+
│ ├── app.css # Estilos globales
|
|
94
|
+
│ ├── router/ # Configuración de Vue Router
|
|
95
|
+
│ ├── src/
|
|
96
|
+
│ │ └── App.vue # Componente raíz (welcome page)
|
|
97
|
+
│ ├── styles/ # Estilos adicionales
|
|
98
|
+
│ └── vendor/ # Assets de vendor
|
|
99
|
+
├── config/ # Configuración de Symfony (YAML)
|
|
100
|
+
├── migrations/ # Migraciones de Doctrine
|
|
101
|
+
├── packages/
|
|
102
|
+
│ └── create-symfony-vue/ # Paquete npm del CLI scaffold
|
|
103
|
+
├── public/ # Document root
|
|
104
|
+
│ └── build/ # Build de Vite (generado)
|
|
105
|
+
├── scripts/ # Utilidades internas
|
|
106
|
+
│ └── sync-template.mjs # Sincroniza template con el CLI
|
|
107
|
+
├── src/ # Código PHP (App\ namespace)
|
|
108
|
+
│ ├── Controller/
|
|
109
|
+
│ ├── Entity/
|
|
110
|
+
│ ├── Repository/
|
|
111
|
+
│ └── ...
|
|
112
|
+
├── templates/ # Twig templates
|
|
113
|
+
│ ├── base.html.twig
|
|
114
|
+
│ └── app.html.twig # Template que monta Vue
|
|
115
|
+
├── tests/ # Tests PHPUnit
|
|
116
|
+
├── translations/ # Traducciones
|
|
117
|
+
├── vite.config.js # Configuración de Vite
|
|
118
|
+
├── tsconfig.json # Configuración de TypeScript
|
|
119
|
+
└── composer.json
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Integración Symfony + Vite
|
|
123
|
+
|
|
124
|
+
La comunicación entre Symfony y Vite se maneja mediante:
|
|
125
|
+
|
|
126
|
+
- [`vite-plugin-symfony`](https://github.com/lhapaipai/vite-plugin-symfony) — plugin de Vite
|
|
127
|
+
- [`pentatrion/vite-bundle`](https://github.com/PentaTraITeam/vite-bundle) — bundle de Symfony
|
|
128
|
+
|
|
129
|
+
Los entry points se definen en `assets/main.ts` y se referencian en Twig mediante:
|
|
130
|
+
|
|
131
|
+
```twig
|
|
132
|
+
{{ vite_entry_link_tags('app') }}
|
|
133
|
+
{{ vite_entry_script_tags('app') }}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Para más información, consulta la [documentación de Symfony con Vite](https://pentatrion.github.io/vite-bundle/).
|
|
137
|
+
|
|
138
|
+
## Producción
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
pnpm build
|
|
142
|
+
composer dump-env prod
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
El servidor Symfony sirve los assets compilados desde `public/build/`.
|
|
146
|
+
|
|
147
|
+
## Desarrollo del CLI
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
# Sincronizar los cambios del template al paquete npm
|
|
151
|
+
node scripts/sync-template.mjs
|
|
152
|
+
|
|
153
|
+
# Probar el CLI localmente
|
|
154
|
+
node packages/create-symfony-vue/bin/index.js mi-app-test
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Publicación
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# Publicar en Packagist (composer)
|
|
161
|
+
# 1. Push a GitHub
|
|
162
|
+
# 2. Crear release en GitHub
|
|
163
|
+
# 3. Packagist detecta automáticamente
|
|
164
|
+
|
|
165
|
+
# Publicar en npm
|
|
166
|
+
cd packages/create-symfony-vue
|
|
167
|
+
npm publish
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Licencia
|
|
171
|
+
|
|
172
|
+
MIT
|