create-slotkit-app 0.1.4 → 0.1.7
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/README.md +13 -16
- package/dist/index.js +115 -51
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
- **Quick Setup**: Create a new SlotKit project in seconds
|
|
16
16
|
- **Vite Integration**: Uses Vite for fast development and building
|
|
17
17
|
- **TypeScript Support**: Full TypeScript configuration included
|
|
18
|
-
- **Plugin System Ready**: Pre-configured plugin directory structure
|
|
18
|
+
- **Plugin System Ready**: Pre-configured plugin directory structure with a default helloworld plugin
|
|
19
|
+
- **Auto Import Generation**: `slotkit generate-imports` runs automatically before `pnpm dev` and `pnpm build`
|
|
19
20
|
- **Zero Configuration**: Works out of the box with sensible defaults
|
|
20
21
|
|
|
21
22
|
### Installation
|
|
@@ -59,14 +60,8 @@ cd my-slotkit-app
|
|
|
59
60
|
# Install dependencies
|
|
60
61
|
pnpm install
|
|
61
62
|
|
|
62
|
-
#
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
# Generate plugin import mappings
|
|
66
|
-
slotkit generate-imports
|
|
67
|
-
|
|
68
|
-
# Start development server
|
|
69
|
-
slotkit dev
|
|
63
|
+
# Start development server (generate-imports runs automatically)
|
|
64
|
+
pnpm dev
|
|
70
65
|
```
|
|
71
66
|
|
|
72
67
|
### What Gets Created
|
|
@@ -81,7 +76,8 @@ my-slotkit-app/
|
|
|
81
76
|
│ │ ├── AppLayout.tsx # Layout with Slot components
|
|
82
77
|
│ │ └── AppLayout.css # Layout styles
|
|
83
78
|
│ └── main.tsx # Entry point
|
|
84
|
-
├── plugins/
|
|
79
|
+
├── plugins/
|
|
80
|
+
│ └── helloworld/ # Default sample plugin
|
|
85
81
|
├── slotkit.config.ts # SlotKit configuration
|
|
86
82
|
├── vite.config.ts # Vite configuration
|
|
87
83
|
├── package.json # Project dependencies
|
|
@@ -98,8 +94,9 @@ The generated project includes:
|
|
|
98
94
|
- `sidebar` slot
|
|
99
95
|
- `content` slot
|
|
100
96
|
- `footer` slot
|
|
101
|
-
3. **slotkit.config.ts**: Basic configuration pointing to `./plugins`
|
|
102
|
-
4. **
|
|
97
|
+
3. **slotkit.config.ts**: Basic configuration pointing to `./plugins`
|
|
98
|
+
4. **helloworld plugin**: Located at `plugins/helloworld/` as a ready-to-run example
|
|
99
|
+
5. **vite.config.ts**: Vite configuration with plugin directory access
|
|
103
100
|
|
|
104
101
|
### Creating Plugins
|
|
105
102
|
|
|
@@ -122,10 +119,10 @@ slotkit disable my-plugin
|
|
|
122
119
|
|
|
123
120
|
### Next Steps
|
|
124
121
|
|
|
125
|
-
1.
|
|
126
|
-
2.
|
|
127
|
-
3.
|
|
128
|
-
4.
|
|
122
|
+
1. Install dependencies: `pnpm install`
|
|
123
|
+
2. Start the dev server: `pnpm dev` (runs `slotkit generate-imports` automatically)
|
|
124
|
+
3. Create additional plugins: `slotkit create-plugin my-plugin --slots content`
|
|
125
|
+
4. Whenever you create/modify plugins outside the dev flow, run `pnpm slotkit generate-imports`
|
|
129
126
|
|
|
130
127
|
### Configuration
|
|
131
128
|
|
package/dist/index.js
CHANGED
|
@@ -62,35 +62,31 @@ import { pluginRegistry, pluginLoader, setPluginImportFunctions } from '@slotkit
|
|
|
62
62
|
// This file is generated by 'slotkit generate-imports'
|
|
63
63
|
import * as pluginImports from './core/plugin/loader/plugin-imports.generated'
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
* Initialize plugin import mappings
|
|
67
|
-
*/
|
|
65
|
+
// Initialize plugin import mappings
|
|
68
66
|
if (pluginImports.getPluginImport && pluginImports.getAvailablePluginIds) {
|
|
69
67
|
setPluginImportFunctions({
|
|
70
|
-
getPluginImport:
|
|
71
|
-
|
|
68
|
+
getPluginImport: (pluginId: string) => {
|
|
69
|
+
const importFn = pluginImports.getPluginImport(pluginId)
|
|
70
|
+
if (!importFn) return undefined
|
|
71
|
+
return () => Promise.resolve(importFn())
|
|
72
|
+
},
|
|
73
|
+
getAvailablePluginIds: pluginImports.getAvailablePluginIds,
|
|
74
|
+
getAllPluginManifests: pluginImports.getAllPluginManifests,
|
|
75
|
+
getPluginManifest: pluginImports.getPluginManifest
|
|
72
76
|
})
|
|
77
|
+
} else {
|
|
78
|
+
console.warn('[WARN] Plugin import functions not found in generated file')
|
|
73
79
|
}
|
|
74
80
|
|
|
75
|
-
|
|
76
|
-
* Load all plugins
|
|
77
|
-
*/
|
|
81
|
+
// Load all plugins
|
|
78
82
|
const loadPlugins = async () => {
|
|
79
83
|
try {
|
|
80
|
-
console.log('[INFO] Starting to load plugins...')
|
|
81
|
-
|
|
82
|
-
// Load all plugins using plugin loader
|
|
83
84
|
const plugins = await pluginLoader.loadAllPlugins()
|
|
84
|
-
|
|
85
|
-
// Register all plugins to registry
|
|
85
|
+
|
|
86
86
|
plugins.forEach(plugin => {
|
|
87
87
|
pluginRegistry.register(plugin)
|
|
88
|
-
console.log(\`[INFO] Plugin "\${plugin.name}" registered to slots:\`, plugin.slots)
|
|
89
88
|
})
|
|
90
|
-
|
|
91
|
-
console.log('[OK] Plugin loading completed!')
|
|
92
|
-
console.log(\`[INFO] Total \${plugins.length} plugins loaded\`)
|
|
93
|
-
|
|
89
|
+
|
|
94
90
|
return plugins
|
|
95
91
|
} catch (error) {
|
|
96
92
|
console.error('[ERROR] Failed to load plugins:', error)
|
|
@@ -103,41 +99,43 @@ const App: React.FC = () => {
|
|
|
103
99
|
const [loadedPlugins, setLoadedPlugins] = useState<any[]>([])
|
|
104
100
|
|
|
105
101
|
useEffect(() => {
|
|
106
|
-
loadPlugins()
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
102
|
+
loadPlugins()
|
|
103
|
+
.then((plugins) => {
|
|
104
|
+
setPluginsLoaded(true)
|
|
105
|
+
setLoadedPlugins(plugins)
|
|
106
|
+
})
|
|
107
|
+
.catch((error) => {
|
|
108
|
+
console.error('[ERROR] Failed to load plugins:', error)
|
|
109
|
+
})
|
|
112
110
|
}, [])
|
|
113
111
|
|
|
114
112
|
return (
|
|
115
113
|
<div className="app">
|
|
116
114
|
<AppLayout />
|
|
117
|
-
|
|
115
|
+
|
|
118
116
|
{/* Plugin loading status indicator */}
|
|
119
|
-
<div style={{
|
|
120
|
-
position: 'fixed',
|
|
121
|
-
top: '10px',
|
|
122
|
-
right: '10px',
|
|
123
|
-
background: pluginsLoaded ? '#e8f5e8' : '#fff3cd',
|
|
124
|
-
padding: '10px',
|
|
117
|
+
<div style={{
|
|
118
|
+
position: 'fixed',
|
|
119
|
+
top: '10px',
|
|
120
|
+
right: '10px',
|
|
121
|
+
background: pluginsLoaded ? '#e8f5e8' : '#fff3cd',
|
|
122
|
+
padding: '10px',
|
|
125
123
|
borderRadius: '4px',
|
|
126
124
|
fontSize: '12px',
|
|
127
|
-
border:
|
|
125
|
+
border: pluginsLoaded ? '1px solid #4caf50' : '1px solid #ffc107',
|
|
128
126
|
zIndex: 1000
|
|
129
127
|
}}>
|
|
130
128
|
{pluginsLoaded ? '[OK] Plugins loaded' : '[INFO] Loading plugins...'}
|
|
131
129
|
</div>
|
|
132
|
-
|
|
130
|
+
|
|
133
131
|
{/* Loaded plugins list */}
|
|
134
132
|
{loadedPlugins.length > 0 && (
|
|
135
|
-
<div style={{
|
|
136
|
-
position: 'fixed',
|
|
137
|
-
top: '50px',
|
|
138
|
-
right: '10px',
|
|
139
|
-
background: '#f3e5f5',
|
|
140
|
-
padding: '10px',
|
|
133
|
+
<div style={{
|
|
134
|
+
position: 'fixed',
|
|
135
|
+
top: '50px',
|
|
136
|
+
right: '10px',
|
|
137
|
+
background: '#f3e5f5',
|
|
138
|
+
padding: '10px',
|
|
141
139
|
borderRadius: '4px',
|
|
142
140
|
fontSize: '11px',
|
|
143
141
|
border: '1px solid #9c27b0',
|
|
@@ -270,8 +268,73 @@ export default defineConfig({
|
|
|
270
268
|
})
|
|
271
269
|
`;
|
|
272
270
|
writeFileSync(join(projectDir, 'slotkit.config.ts'), slotkitConfig, 'utf-8');
|
|
273
|
-
// Create plugins directory
|
|
274
|
-
|
|
271
|
+
// Create plugins directory and default hello-world plugin
|
|
272
|
+
const pluginsDir = join(projectDir, 'plugins');
|
|
273
|
+
mkdirSync(pluginsDir, { recursive: true });
|
|
274
|
+
const helloWorldDir = join(pluginsDir, 'helloworld');
|
|
275
|
+
const helloWorldSrcDir = join(helloWorldDir, 'src');
|
|
276
|
+
mkdirSync(helloWorldSrcDir, { recursive: true });
|
|
277
|
+
const helloWorldManifest = `{
|
|
278
|
+
"id": "helloworld",
|
|
279
|
+
"name": "Hello-world Plugin",
|
|
280
|
+
"version": "1.0.0",
|
|
281
|
+
"description": "A built-in hello-world plugin",
|
|
282
|
+
"author": "SlotKit Team",
|
|
283
|
+
"entry": "./src/index.tsx",
|
|
284
|
+
"slots": [
|
|
285
|
+
"content"
|
|
286
|
+
],
|
|
287
|
+
"enabled": true
|
|
288
|
+
}`;
|
|
289
|
+
writeFileSync(join(helloWorldDir, 'manifest.json'), helloWorldManifest + '\n', 'utf-8');
|
|
290
|
+
const helloWorldPackageJson = `{
|
|
291
|
+
"name": "plugin-helloworld",
|
|
292
|
+
"version": "1.0.0",
|
|
293
|
+
"main": "src/index.tsx",
|
|
294
|
+
"private": true
|
|
295
|
+
}`;
|
|
296
|
+
writeFileSync(join(helloWorldDir, 'package.json'), helloWorldPackageJson + '\n', 'utf-8');
|
|
297
|
+
const helloWorldTsconfig = `{
|
|
298
|
+
"extends": "../../tsconfig.json",
|
|
299
|
+
"compilerOptions": {
|
|
300
|
+
"jsx": "react-jsx"
|
|
301
|
+
},
|
|
302
|
+
"include": [
|
|
303
|
+
"src/**/*"
|
|
304
|
+
]
|
|
305
|
+
}`;
|
|
306
|
+
writeFileSync(join(helloWorldDir, 'tsconfig.json'), helloWorldTsconfig + '\n', 'utf-8');
|
|
307
|
+
const helloWorldIndexTsx = `import React from 'react'
|
|
308
|
+
|
|
309
|
+
const HelloWorldComponent: React.FC = () => {
|
|
310
|
+
return (
|
|
311
|
+
<div
|
|
312
|
+
style={{
|
|
313
|
+
padding: '1rem',
|
|
314
|
+
background: '#f5f5f5',
|
|
315
|
+
border: '1px solid #ddd',
|
|
316
|
+
borderRadius: '8px',
|
|
317
|
+
margin: '0.5rem 0'
|
|
318
|
+
}}
|
|
319
|
+
>
|
|
320
|
+
<h3>Hello-world Plugin</h3>
|
|
321
|
+
<p>This is the default hello-world plugin generated by create-slotkit-app.</p>
|
|
322
|
+
</div>
|
|
323
|
+
)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const helloworldPlugin = {
|
|
327
|
+
id: 'helloworld',
|
|
328
|
+
name: 'Hello-world Plugin',
|
|
329
|
+
version: '1.0.0',
|
|
330
|
+
component: HelloWorldComponent,
|
|
331
|
+
slots: ['content']
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
export { helloworldPlugin }
|
|
335
|
+
export default helloworldPlugin
|
|
336
|
+
`;
|
|
337
|
+
writeFileSync(join(helloWorldSrcDir, 'index.tsx'), helloWorldIndexTsx, 'utf-8');
|
|
275
338
|
// Create or update vite.config.ts with SlotKit-specific configuration
|
|
276
339
|
const viteConfigPath = join(projectDir, 'vite.config.ts');
|
|
277
340
|
const viteConfigJsPath = join(projectDir, 'vite.config.js');
|
|
@@ -393,13 +456,14 @@ program
|
|
|
393
456
|
// Ensure @vitejs/plugin-react is in devDependencies
|
|
394
457
|
packageJson.devDependencies['@vitejs/plugin-react'] = packageJson.devDependencies['@vitejs/plugin-react'] || '^5.0.4';
|
|
395
458
|
}
|
|
396
|
-
//
|
|
397
|
-
packageJson.scripts
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
459
|
+
// Ensure scripts object exists
|
|
460
|
+
if (!packageJson.scripts) {
|
|
461
|
+
packageJson.scripts = {};
|
|
462
|
+
}
|
|
463
|
+
packageJson.scripts.dev = 'slotkit generate-imports && slotkit dev';
|
|
464
|
+
packageJson.scripts.build = 'slotkit generate-imports && slotkit build';
|
|
465
|
+
packageJson.scripts.preview = packageJson.scripts.preview || 'slotkit preview';
|
|
466
|
+
packageJson.scripts['generate-imports'] = packageJson.scripts['generate-imports'] || 'slotkit generate-imports';
|
|
403
467
|
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf-8');
|
|
404
468
|
}
|
|
405
469
|
// Step 3: Create SlotKit-specific files
|
|
@@ -418,9 +482,9 @@ program
|
|
|
418
482
|
console.log('\n[INFO] Next steps:');
|
|
419
483
|
console.log(` cd ${projectName}`);
|
|
420
484
|
console.log(' pnpm install');
|
|
421
|
-
console.log('
|
|
422
|
-
console.log(' slotkit
|
|
423
|
-
console.log(' slotkit
|
|
485
|
+
console.log(' pnpm dev');
|
|
486
|
+
console.log(' # Optional: pnpm slotkit create-plugin <name> --slots <slots>');
|
|
487
|
+
console.log(' # predev/prebuild will automatically run slotkit generate-imports');
|
|
424
488
|
}
|
|
425
489
|
catch (error) {
|
|
426
490
|
console.error('[ERROR] Failed to create project:', error.message);
|