|
| 1 | +# Plugin Devkit Repository - Comprehensive Feature Analysis |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +**plugin-devkit** is a Shopify CLI plugin (v1.0.8) developed by Archetype Themes Limited Partnership. It's a TypeScript-based CLI tool built with oclif that enhances Shopify theme development with a component-driven architecture. The plugin enables developers to build modular, reusable Liquid components for Shopify themes. |
| 6 | + |
| 7 | +## Project Structure |
| 8 | + |
| 9 | +### Technology Stack |
| 10 | +- **Language**: TypeScript (ES2022 target, Node16 modules) |
| 11 | +- **CLI Framework**: oclif (@oclif/core v4) |
| 12 | +- **Build System**: TypeScript compiler |
| 13 | +- **Package Manager**: npm |
| 14 | +- **Node.js Version**: v18.12.0+ |
| 15 | + |
| 16 | +### Key Dependencies |
| 17 | +- `@oclif/core`: CLI framework |
| 18 | +- `chokidar`: File watching |
| 19 | +- `deepmerge`: Object merging |
| 20 | +- `fs-extra`: File system operations |
| 21 | +- `glob`: File pattern matching |
| 22 | +- `jsonc`: JSON with comments support |
| 23 | +- `parse-imports`: JavaScript import parsing |
| 24 | +- `smol-toml`: TOML parsing |
| 25 | + |
| 26 | +### Architecture |
| 27 | +- Commands organized under `src/commands/theme/` |
| 28 | +- Shared utilities in `src/utilities/` |
| 29 | +- Base command class for common functionality |
| 30 | +- Argument and flag definitions centralized |
| 31 | + |
| 32 | +## Core Features |
| 33 | + |
| 34 | +### 1. Component Management System |
| 35 | + |
| 36 | +#### Component Collection Structure |
| 37 | +Components are organized in a collection directory with: |
| 38 | +- `components/` - Contains component folders |
| 39 | +- Each component folder contains: |
| 40 | + - `*.liquid` - Main component file (same name as folder) |
| 41 | + - `snippets/` - Related snippet files |
| 42 | + - `assets/` - Component assets (JS, CSS) |
| 43 | + - `setup/` - Setup files (settings_schema.json, settings_data.json, etc.) |
| 44 | +- `scripts/` - Global JavaScript files |
| 45 | +- `package.json` - Collection metadata |
| 46 | + |
| 47 | +#### Component Node System |
| 48 | +The plugin uses a `LiquidNode` data structure to track: |
| 49 | +- **Type**: `component`, `snippet`, `asset`, `entry`, `setup` |
| 50 | +- **Dependencies**: Snippets referenced via `render`, `include`, `inject` |
| 51 | +- **Assets**: JavaScript files referenced via `asset_url` filter or ES6 imports |
| 52 | +- **Body**: File content for analysis |
| 53 | +- **Theme Folder**: Target location (`assets`, `snippets`, `layout`, `sections`, `templates`, `blocks`) |
| 54 | + |
| 55 | +### 2. Commands |
| 56 | + |
| 57 | +#### Component Commands (`shopify theme component`) |
| 58 | + |
| 59 | +##### `map` - Generate Component Manifest |
| 60 | +- **Purpose**: Creates/updates `component.manifest.json` file |
| 61 | +- **Features**: |
| 62 | + - Maps component files (snippets and assets) to their source collection |
| 63 | + - Tracks component collection version and commit hash |
| 64 | + - Supports component selection (single, comma-separated, or `*` for all) |
| 65 | + - Handles conflicts and overrides with warnings |
| 66 | + - Recursively processes component dependencies |
| 67 | + - Flags: |
| 68 | + - `--ignore-conflicts` (`-f`): Ignore conflicts when mapping |
| 69 | + - `--ignore-overrides` (`-o`): Ignore overrides when mapping |
| 70 | + - `--collection-name` (`-n`): Override collection name |
| 71 | + - `--collection-version` (`-v`): Override collection version |
| 72 | + |
| 73 | +##### `copy` - Copy Component Files |
| 74 | +- **Purpose**: Copies rendered component files into theme directory |
| 75 | +- **Features**: |
| 76 | + - Copies snippets and assets from collection to theme |
| 77 | + - Validates manifest exists and version matches |
| 78 | + - Only copies files belonging to current collection |
| 79 | + - Updates files only if changed |
| 80 | + |
| 81 | +##### `clean` - Remove Unused Files |
| 82 | +- **Purpose**: Removes component files not in manifest |
| 83 | +- **Features**: |
| 84 | + - Scans theme directory for snippets and assets |
| 85 | + - Removes files not listed in `component.manifest.json` |
| 86 | + - Prevents orphaned component files |
| 87 | + - Supports quiet mode (`-q`) |
| 88 | + |
| 89 | +##### `install` - Complete Installation |
| 90 | +- **Purpose**: Runs full component installation workflow |
| 91 | +- **Features**: |
| 92 | + - Executes in sequence: `map` → `copy` → `clean` → `generate import-map` |
| 93 | + - One-command setup for components |
| 94 | + - Supports component selector |
| 95 | + |
| 96 | +##### `dev` - Development Environment |
| 97 | +- **Purpose**: Creates sandboxed development environment |
| 98 | +- **Features**: |
| 99 | + - Removes existing `.dev` directory |
| 100 | + - Clones/fetches theme from GitHub or local directory |
| 101 | + - Copies component files and setup files |
| 102 | + - Integrates with `shopify theme dev` for preview |
| 103 | + - File watching with chokidar for auto-sync |
| 104 | + - Flags: |
| 105 | + - `--theme-dir` (`-t`): Theme directory (default: GitHub Explorer theme) |
| 106 | + - `--setup-files` (`-s`): Copy setup files (default: true) |
| 107 | + - `--watch` (`-w`): Watch for changes (default: true) |
| 108 | + - `--preview` (`-y`): Sync to theme directory (default: true) |
| 109 | + - `--generate-import-map` (`-i`): Generate import map |
| 110 | + - `--generate-template-map` (`-m`): Generate template map |
| 111 | + - Theme dev flags: `--host`, `--port`, `--live-reload`, `--store`, `--theme`, `--password`, `--store-password`, `--environment` |
| 112 | + |
| 113 | +#### Generate Commands (`shopify theme generate`) |
| 114 | + |
| 115 | +##### `import-map` - Generate JavaScript Import Map |
| 116 | +- **Purpose**: Creates `snippets/head.import-map.liquid` for ES6 module imports |
| 117 | +- **Features**: |
| 118 | + - Scans `assets/` directory for `.js` files |
| 119 | + - Creates import map with Shopify `asset_url` filter |
| 120 | + - Supports both `.js` and `.min.js` extensions |
| 121 | + - Generates `<script type="importmap">` snippet |
| 122 | + |
| 123 | +##### `template-map` - Generate Template Route Map |
| 124 | +- **Purpose**: Creates `snippets/template-map.liquid` for component routing |
| 125 | +- **Features**: |
| 126 | + - Scans `templates/` directory recursively |
| 127 | + - Maps component names to Shopify route templates |
| 128 | + - Supports category-based routing (product, collection, page, etc.) |
| 129 | + - Generates JSON template map with Liquid variables |
| 130 | + - Handles special routes (404, cart, customers, search, etc.) |
| 131 | + |
| 132 | +#### Locale Commands (`shopify theme locale`) |
| 133 | + |
| 134 | +##### `sync` - Sync Locale Files |
| 135 | +- **Purpose**: Synchronizes theme locale files with source translations |
| 136 | +- **Features**: |
| 137 | + - Fetches locales from GitHub repository or local directory |
| 138 | + - Scans theme files for translation key usage |
| 139 | + - Three sync modes: |
| 140 | + - `add-missing`: Only add new translations |
| 141 | + - `add-and-override`: Add new and override existing |
| 142 | + - `replace-existing`: Replace existing translations only |
| 143 | + - Supports schema and storefront translations separately |
| 144 | + - Handles dynamic translation keys (prefix patterns) |
| 145 | + - Formats locale files (alphabetical sorting) |
| 146 | + - Flags: |
| 147 | + - `--locales-source` (`-l`): Source directory/URL (default: Archetype locales repo) |
| 148 | + - `--mode` (`-m`): Sync mode (default: `add-missing`) |
| 149 | + - `--target`: Process `all`, `schema`, or `storefront` translations |
| 150 | + - `--format`: Sort keys alphabetically |
| 151 | + - `--clean` (`-c`): Remove unreferenced translations after sync |
| 152 | + |
| 153 | +##### `clean` - Remove Unreferenced Translations |
| 154 | +- **Purpose**: Removes unused translation keys from locale files |
| 155 | +- **Features**: |
| 156 | + - Scans theme files for translation key references |
| 157 | + - Identifies unused keys in locale files |
| 158 | + - Supports prefix-based dynamic keys |
| 159 | + - Formats output files |
| 160 | + - Flags: |
| 161 | + - `--target`: Process `all`, `schema`, or `storefront` translations |
| 162 | + - `--format`: Sort keys alphabetically |
| 163 | + |
| 164 | +### 3. Translation Key Detection |
| 165 | + |
| 166 | +The plugin uses sophisticated regex patterns to detect translation keys: |
| 167 | + |
| 168 | +#### Schema Translations (`t:` pattern) |
| 169 | +- Pattern: `"t:translation.key"` |
| 170 | +- Scanned directories: `config/`, `blocks/`, `sections/` |
| 171 | +- Used in: Schema JSON files |
| 172 | + |
| 173 | +#### Storefront Translations |
| 174 | +- Standard Liquid patterns: |
| 175 | + - `{{ 'key' | t }}` |
| 176 | + - `{% assign var = 'key' | t %}` |
| 177 | + - Dynamic prefixes: `'prefix.' | append: x | t` |
| 178 | +- `render` locale parameter: `render 'snippet' locale: 'key'` |
| 179 | +- `utility.translate` snippet: |
| 180 | + - `key:` parameter |
| 181 | + - `t:` parameter (string or variable) |
| 182 | +- Scanned directories: `blocks/`, `layout/`, `sections/`, `snippets/`, `templates/` |
| 183 | + |
| 184 | +### 4. File Processing Utilities |
| 185 | + |
| 186 | +#### Node Analysis |
| 187 | +- Parses Liquid files to extract: |
| 188 | + - Snippet dependencies (`render`, `include`, `inject`) |
| 189 | + - JavaScript asset references (`asset_url` filter) |
| 190 | + - ES6 import statements in JS files |
| 191 | + - Component structure and relationships |
| 192 | + |
| 193 | +#### Manifest Management |
| 194 | +- `component.manifest.json` structure: |
| 195 | + ```json |
| 196 | + { |
| 197 | + "collections": { |
| 198 | + "collection-name": { |
| 199 | + "commit": "git-commit-hash", |
| 200 | + "version": "1.0.0" |
| 201 | + } |
| 202 | + }, |
| 203 | + "files": { |
| 204 | + "snippets": { |
| 205 | + "snippet-name.liquid": "collection-name" |
| 206 | + }, |
| 207 | + "assets": { |
| 208 | + "asset.js": "collection-name" |
| 209 | + } |
| 210 | + } |
| 211 | + } |
| 212 | + ``` |
| 213 | +- Tracks file ownership |
| 214 | +- Handles conflicts and overrides |
| 215 | +- Supports multiple collections |
| 216 | + |
| 217 | +#### Setup Files Processing |
| 218 | +- Merges `settings_schema.json` from multiple components |
| 219 | +- Deep merges `settings_data.json` from components |
| 220 | +- Copies other setup files to appropriate theme directories |
| 221 | + |
| 222 | +### 5. Git Integration |
| 223 | + |
| 224 | +- Clones theme repositories from GitHub URLs |
| 225 | +- Retrieves commit hash for component collections |
| 226 | +- Used for version tracking in manifests |
| 227 | + |
| 228 | +### 6. File Watching |
| 229 | + |
| 230 | +- Uses `chokidar` for file system watching |
| 231 | +- Watches theme and component directories |
| 232 | +- Auto-rebuilds theme on changes |
| 233 | +- Syncs changes to development directory |
| 234 | + |
| 235 | +## Utility Functions |
| 236 | + |
| 237 | +### File Operations |
| 238 | +- `syncFiles`: Copy entire directory structures |
| 239 | +- `cleanDir`: Remove directory contents |
| 240 | +- `copyFileIfChanged`: Copy only if file changed |
| 241 | +- `writeFileIfChanged`: Write only if content changed |
| 242 | + |
| 243 | +### Object Operations |
| 244 | +- `sortObjectKeys`: Alphabetically sort object keys |
| 245 | +- `flattenObject`: Flatten nested objects |
| 246 | +- `unflattenObject`: Restore nested structure |
| 247 | +- `deepMerge`: Deep merge objects |
| 248 | + |
| 249 | +### Logger |
| 250 | +- Centralized logging with debug, info, warn, error levels |
| 251 | +- Integration with oclif command logging |
| 252 | + |
| 253 | +### Argument & Flag Parsing |
| 254 | +- Centralized argument definitions with validation |
| 255 | +- Component selector validation |
| 256 | +- Theme directory validation |
| 257 | +- Flag definitions with defaults |
| 258 | + |
| 259 | +## Testing |
| 260 | + |
| 261 | +- Test files in `test/` directory mirroring `src/` structure |
| 262 | +- Uses Mocha test framework |
| 263 | +- Test fixtures include: |
| 264 | + - Component collection examples |
| 265 | + - Theme directory structure |
| 266 | + - Locale files |
| 267 | + |
| 268 | +## Development Workflow |
| 269 | + |
| 270 | +### Local Development |
| 271 | +1. Clone repository |
| 272 | +2. Install dependencies: `npm install` |
| 273 | +3. Build: `npm run build` or `npm run watch` |
| 274 | +4. Link plugin: `shopify plugins link` |
| 275 | +5. Test commands locally |
| 276 | + |
| 277 | +### Component Development Workflow |
| 278 | +1. Create component collection structure |
| 279 | +2. Develop components in `components/` directory |
| 280 | +3. Use `shopify theme component dev` for isolated development |
| 281 | +4. Use `shopify theme component install` to integrate into theme |
| 282 | +5. Use `shopify theme component map` to update manifest |
| 283 | + |
| 284 | +## Key Design Patterns |
| 285 | + |
| 286 | +### Command Pattern |
| 287 | +- All commands extend `BaseCommand` |
| 288 | +- Shared initialization logic |
| 289 | +- Consistent argument/flag handling |
| 290 | + |
| 291 | +### Node-Based Architecture |
| 292 | +- Components, snippets, and assets represented as nodes |
| 293 | +- Dependency graph built from nodes |
| 294 | +- Recursive dependency resolution |
| 295 | + |
| 296 | +### Manifest-Driven |
| 297 | +- Single source of truth: `component.manifest.json` |
| 298 | +- Tracks file ownership and versions |
| 299 | +- Enables conflict resolution |
| 300 | + |
| 301 | +### Separation of Concerns |
| 302 | +- Commands: User-facing CLI operations |
| 303 | +- Utilities: Reusable business logic |
| 304 | +- Types: Shared type definitions |
| 305 | + |
| 306 | +## Integration Points |
| 307 | + |
| 308 | +### Shopify CLI |
| 309 | +- Registered as oclif plugin |
| 310 | +- Commands prefixed with `shopify theme` |
| 311 | +- Integrates with `shopify theme dev` command |
| 312 | + |
| 313 | +### Shopify Theme Structure |
| 314 | +- Respects Shopify theme directory structure |
| 315 | +- Works with standard theme folders: |
| 316 | + - `assets/` |
| 317 | + - `config/` |
| 318 | + - `layout/` |
| 319 | + - `sections/` |
| 320 | + - `snippets/` |
| 321 | + - `templates/` |
| 322 | + - `blocks/` |
| 323 | + - `locales/` |
| 324 | + |
| 325 | +## Configuration |
| 326 | + |
| 327 | +### Component Collection |
| 328 | +- Requires `package.json` with name and version |
| 329 | +- Collection name and version used in manifest |
| 330 | +- Can be overridden via flags |
| 331 | + |
| 332 | +### Theme Directory |
| 333 | +- Validates theme directory structure |
| 334 | +- Requires: `layout/`, `templates/`, `config/` directories |
| 335 | +- Supports local paths and GitHub URLs |
| 336 | + |
| 337 | +## Error Handling |
| 338 | + |
| 339 | +- Validates component collection structure |
| 340 | +- Validates theme directory structure |
| 341 | +- Warns on missing components |
| 342 | +- Handles version mismatches |
| 343 | +- Provides clear error messages |
| 344 | + |
| 345 | +## Performance Considerations |
| 346 | + |
| 347 | +- Parallel file processing where possible |
| 348 | +- File change detection to avoid unnecessary writes |
| 349 | +- Efficient glob patterns for file discovery |
| 350 | +- Lazy evaluation of file contents |
| 351 | + |
| 352 | +## Future Extensibility |
| 353 | + |
| 354 | +- Plugin architecture allows adding new commands |
| 355 | +- Utility functions can be extended |
| 356 | +- Node system supports new file types |
| 357 | +- Manifest structure can accommodate new metadata |
| 358 | + |
| 359 | +## Security Considerations |
| 360 | + |
| 361 | +- File system operations validate paths |
| 362 | +- Git operations use standard git commands |
| 363 | +- No arbitrary code execution |
| 364 | +- Input validation on all user inputs |
| 365 | + |
| 366 | +## Documentation |
| 367 | + |
| 368 | +- README with command documentation |
| 369 | +- CONTRIBUTING guide for developers |
| 370 | +- CHANGELOG for version history |
| 371 | +- Code comments explain complex logic |
| 372 | + |
| 373 | +## Limitations |
| 374 | + |
| 375 | +- GitHub-only theme cloning (no other Git providers) |
| 376 | +- Component selector validation requires components directory |
| 377 | +- Manifest must exist before copy operations |
| 378 | +- Version checking requires exact match |
| 379 | + |
| 380 | +## Use Cases |
| 381 | + |
| 382 | +1. **Component Library Development**: Build reusable Shopify components |
| 383 | +2. **Theme Customization**: Add components to existing themes |
| 384 | +3. **Translation Management**: Sync and clean locale files |
| 385 | +4. **Isolated Development**: Develop components separately from theme |
| 386 | +5. **Import Map Generation**: Enable ES6 modules in Shopify themes |
| 387 | +6. **Template Routing**: Map components to theme routes |
0 commit comments