Skip to content

feat: migrate from Yeoman to Plop for modern scaffolding #5

@prometheas

Description

@prometheas

Summary

Migrate the project from Yeoman Generator to Plop for a more modern, performant, and maintainable scaffolding solution.

Background

The project currently uses Yeoman Generator (yeoman-generator@5.10.0) which, while functional, has several limitations:

  • Complex class-based architecture making testing difficult
  • Heavy dependency footprint
  • Slower performance due to filesystem ceremony
  • Testing challenges (complex mocking, temp directories, slow execution)
  • Aging ecosystem with less active development

Proposed Solution: Migrate to Plop

Plop is a modern micro-generator framework that's perfect for our use case:

Benefits

  • Modern Architecture: Simple function-based generators vs complex classes
  • Better Performance: Lightweight with minimal dependencies
  • Improved Testing: Easy to unit test, supports in-memory operations
  • TypeScript Support: Built-in TypeScript support with proper types
  • Active Maintenance: Modern, well-maintained project
  • Simpler API: More intuitive than Yeoman's class hierarchy

Migration Scope

Phase 1: Core Migration

  • Add Plop as dependency, remove Yeoman Generator
  • Convert main generator (app/index.js) to Plop format (plopfile.js)
  • Migrate prompts (should be nearly 1:1)
  • Convert file copy/template operations to Plop actions
  • Update CLI interface and package.json scripts

Phase 2: Templates & Testing

  • Ensure all template stacks work correctly (js-vitest, php-phpspec, php-phpunit)
  • Migrate test suite to use node-plop for programmatic testing
  • Implement faster, more reliable testing with in-memory operations
  • Update documentation and README

Phase 3: Enhancements (Optional)

  • Add TypeScript for better developer experience
  • Implement additional Handlebars helpers for template flexibility
  • Add custom actions for advanced file operations if needed

Technical Comparison

Current Yeoman Structure:

module.exports = class extends Generator {
  async prompting() {
    const prompts = [/* prompts array */];
    const props = await this.prompt(prompts);
    // set properties
  }
  
  writing() {
    this.fs.copyTpl(/* template operations */);
  }
};

Proposed Plop Structure:

export default function (plop) {
  plop.setGenerator('tdd-kata', {
    description: 'Generate TDD kata scaffolds',
    prompts: [/* same prompts array */],
    actions: [
      {
        type: 'add',
        path: 'README.md', 
        templateFile: 'templates/katas/{{kata}}.md'
      },
      // dynamic actions based on stack choice
    ]
  });
}

Testing Improvements

One of the major benefits will be drastically improved testing:

Current (Yeoman):

  • Complex yeoman-test setup with temp directories
  • Slow filesystem operations
  • Difficult to mock and isolate
  • Shell execution required for integration tests

Proposed (Plop):

  • Simple programmatic testing with node-plop
  • In-memory operations possible
  • Easy mocking and isolation
  • Much faster test execution

Breaking Changes

  • CLI interface will change from yo generator-multistack-tdd-kata to plop (or custom CLI name)
  • Generated project structure remains identical (no user impact)
  • Development/contribution workflow changes

Success Criteria

  • All existing functionality preserved
  • Generated projects identical to current output
  • Test suite runs faster (target: 50%+ improvement)
  • Simpler codebase with better maintainability
  • Documentation updated
  • CLI remains user-friendly

Implementation Notes

  • Consider keeping Yeoman temporarily during migration for comparison
  • Ensure template compatibility (currently using basic templating, should work with Handlebars)
  • May need custom actions for complex file operations currently done in writeProjectFiles()
  • Test the migration thoroughly with all stack combinations

Related Issues

This addresses testing performance issues and modernizes the codebase for better maintainability.


Priority: Medium (good improvement but not urgent)
Estimated Effort: 1-2 days for core migration + testing

Metadata

Metadata

Assignees

No one assigned

    Labels

    dxDeveloper experience taskenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions