Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Templates vs Project Classes #18

Closed
andrestone opened this issue Jul 15, 2020 · 4 comments
Closed

Templates vs Project Classes #18

andrestone opened this issue Jul 15, 2020 · 4 comments

Comments

@andrestone
Copy link
Contributor

Hey there!

With the latest commits, we now have 1:1 relation between classes and initialization options. But, in fact, one class could have many templates to serve many different purposes.

So, the question is: should we have a templating system or just go creating project classes to support common use cases? None of those and stick with current state (single template per project type) ?

@eladb
Copy link
Contributor

eladb commented Jul 16, 2020

projen is all about avoiding templates. "Templates are evil" is our moto.

The main principle is that project types offer a surface area for users to define their project and we can easily implement a hierarchy of project types if there are use cases for more specific configuration.

For example, JsiiProject is derived from TypeScriptProject and specializes it for jsii use cases.

Let's take a use case you have in mind and I'll show you how we can add a project type for it.

#templatesareevil

@andrestone
Copy link
Contributor Author

andrestone commented Jul 16, 2020

I'm not necessarily advocating for templates, I just wanted to clarify what is the better path for extending projen to support more specific use cases, as I thought we were working towards allowing templates since this.

There's a multitude of project "types" that support various use cases and I think it's important to make clear to which degree these use cases would be supported out-of-the-box. IMO, the downside of using "types" instead of templates is that the codebase might get pretty bloated and hard to maintain (if we're willing to support many), while templates live outside of the core APIs and therefore introduce less friction. I also see it as an easier path to adoption, since more flexibly supporting different use cases is more welcoming (if I have a cdk-jsii-construct template (or type), there's very little to customize in comparison with starting with the jsii type).

For example, here is what's currently working on my fork (API defo needs a better interface, but you get the idea):

Adding new project from template and customizing

.projenrc.js

const webFrontEnd = NodeProject.fromTemplate({
  templateName: 'typescript',
  copyFiles: true,
  modifier: (proj) => {
    proj.addFields({
      name: 'my-project',
      keywords: ['hello', 'from', 'async']
    });
  }
});
webFrontEnd.then(proj => proj.synth());

In the example above I'm using a template (which consists of a .projenrc.js file and sample code files) to instantiate a new projen project with changes. Since I'm using actual templates, changing template files is more flexible and straight forward.

I'm also using templates to manage monorepo packages like this:

Creating a monorepo project and adding a custom package based on template:

.projenrc.js

const myMonorepoProject = new LernaProject({
  name: 'root',
  lernaVersioning: true,
  ...common,
});

myMonorepoProject.addPackageFromTemplate({
  template: 'typescript',
  modifier: (proj) => {
    proj.addFields({
      name: 'dynageo',
      keywords: ['hello', 'from', 'async']
    });
  }
});
myMonorepoProject.synth();

Using classes instead of templates just makes the above easier to implement. But how many types are we willing to support? Maybe open for extensibility with a projen+ kind of package? What about non-text files that might exist in templates, such as sample images?

@eladb
Copy link
Contributor

eladb commented Jul 16, 2020

I'd like to start by using project types as the main vehicle for offering abstraction and not templates. Yes, they require thinking about APIs and surface area, but that's that whole point. Templates are evil exactly for that reason - they "seem easy" at first but very quickly they become completely unmaintainable and impossible to update.

When we reach 300 project types, we'll see how we can decentralize the ecosystem (it is always possible to import a project type from a library). At the moment, I think there is some value in keeping things simple and centralized. I added an Ecosystem section to readme with some info.

@andrestone
Copy link
Contributor Author

Awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants