jogelin / huge-nx

30 stars 0 forks source link

Discussion: Files modification stored in config `*.conventions.ts`, files generation and CLI multiple choices #1

Open Thisisjuke opened 4 months ago

Thisisjuke commented 4 months ago

I heard about the project from a friend. Currently, I'm trying to generate NX applications and libraries from a CLI. My goal is to offer several possible choices for applications and libraries. Overall, the user is allowed to choose from:

Applications:

Libraries:

At the moment, I'm mostly focused on cleanly auto-generating the libraries and linking them in "global" files.

For example: the different configurations available and exported in the eslint library are recommended & default. These are the 2 configurations that I usually use in my projects: a complex configuration with many custom rules, or a light configuration that will be expanded upon throughout the project. This library mainly requires an update in 2 files of the NX Workspace:

/* const defaultConfig = require('./libs/eslint/src/default') */
const recommendedConfig = require('./libs/eslint/src/recommended')

module.exports = recommendedConfig

So there are several ways to do this, and currently these modifications are made in a custom Inquirer script that will itself copy/paste files or modify things in an approximate way by reading files.

So I looked into NX generators which seem to be the right solution for my use case: modifying files in my workspace while being aware of certain useful things related to the NX workspace context.

So currently, if I want to generate my workspace from huge-nx, and then make modifications to it, I have to call the huge-nx CLI from my CLI: so I don't fully leverage the potential of the *.conventions.ts config.

Hence my following questions after reading the [TODO] in the Readme:

All of this is the beginning of a reflection on automated library customization and not on automated monorepo generation, but my current issues seem to be shared with those of huge-nx.

I can provide details on my current workflow and I look forward to hearing your thoughts on this! Thank you in advance :v:

(Perhaps this issue should have been a discussion but I don't think those have been enabled for this repo)

jogelin commented 4 months ago

Hey,

Thanks for your interest in huge-nx!

I haven't implemented yet a way to integrate customizations when generating a workspace. But this is of course something I would like to integrate. Your use case could be the first one that could guide me to it ;)

I don't want to complexity too much the *.conventions.ts. I prefer to open doors and keep customization outside of the list of properties.

Concerning the customizations:

1. Allow running custom generators at Workspace level:

export default {

  workspace: {
    // --> List of scripts or generators at the Workspace level
    global: ['@my-org/my-plugin:my-workspace-generator']
    apps: {...},
  },
};

So after the generation of the apps/libs, I could execute global scripts. However, for local generators, it will be important to ensure that all imports/libraries are installed.

2. Allow running custom generators at ProjectType level:

export default {
  projectTypes: {
    'global:angular:application': {
      projectPattern: '*-app',
      // --> Usage of a custom generator
      generators: [{ generator: '@my-org/my-plugin:my-angular-generator' }],
    },
  },
  workspace: {
    apps: {
      'my-app': 'global:angular:application',
    },
  },
};

However, for local generators, it will be important to ensure that all imports/libraries are installed.

Concerning the "intermediate" questions:

For the moment, I am just skipping them by using the option --no-interactive for each execution.

When you generate a huge workspace, it is not fun to have all the questions for each generator.

But I think it would make sense to be able to enable/disable that option for each execution or globally like:

export default {
  projectTypes: {
    'global:angular:application': {
      projectPattern: '*-app',
      generators: [{ 
           generator: '@my-org/my-plugin:my-angular-generator',
           options: {
               interactive: true // <-- HERE
           }
      }],
    },
  },
  workspace: {
    global: {
        generators: ['@my-org/my-plugin:my-workspace-generator'],
        interactive: true // <-- HERE
    },
    apps: {
      'my-app': 'global:angular:application',
    },
  },
};

By default, it will be false.

Then if your custom generators supports prompts, the user will be able to customize it and it is the responsibility of your generator to switch.

Concerning using it to automate custom libs and not the entire workspace

There is no need to create and maintain multiple custom generators. You can create one custom generator that will read your ProjectTypes from your files and generate a project from it by using the configurations described.

It is something I want to implement too.

I think this should cover your needs right? Please do not hesitate to contact me if you have other ideas ;)

Thisisjuke commented 4 months ago

Hey, thanks for your thorough response!

I'll do my best to provide my insights, and if Huge-nx appears to be the solution, I'll dedicate some personal time and may also allocate some professional time to delve into matters related to this repository.

Perhaps I'm feeling a bit overwhelmed by the complexity of this ecosystem, but I'll discuss this further at the end.

1. Generator Handling

So, if I understand correctly, if I want to use Huge-nx to:

The goal will be to create one big generator, with different "params" ? So that, in the end, I will have 7 generators:

This way, I can handle file modifications/file creations by "app"/"lib". One generator will be created with all its necessary dependencies added in package.json?

Then, how can I ensure the proper behavior and integrity of the modifications on "global" files like the root /eslint.config.js or the root /tsconfig.base.json ?

2. Integration with my Own CLI (Inquirer)

In the end, will my CLI only be used to generate the appropriate *.conventions.ts ?

A CLI that aims to generate an incomplete (choice-based) Huge-nx workspace will only:

3. About Prompts and Interactivity

Both of the two solutions seem promising, as every user choice, regardless of its relevance to the generated NX workspace, will be predetermined ans stored beforehand. Additionally, everything related to the generator will be displayed due to interactive: true. If everything aligns smoothly (both in my mind and in my CLI), and if I want to pass parameters but remain silent (interactive: false), I will just need to pass stored user inputs as generator parameters, right? So, how can I specify to Huge-nx to pass down perhaps 10 or 20 parameters to the listed generator in the config file?

4. Things needed on my side to continue / help.

On my end, I utilize NX workspace for all of my personal JS/web projects, and I've also employed NX in three professional projects that are currently in production. Interestingly, none of them have utilized generators before; this is my first attempt at incorporating them.

To kick things off, I delved into your articles on your GitHub profile and watched some official videos about NX Crystal. While I found the concepts in the official NX documentation to be well explained, particularly regarding prompts and configuration file modification, I found the information on creating generators or the "Getting Started" examples to be somewhat lacking.

Used resources:

Additionally, the various code snippets found on the internet are either from before the Crystal redesign or contain a lot of code related to applyTransform from jscodeshift/src/testUtils or a bunch of functions form @nx/devkit without real explanation.

Typically, when discussing code generation or modification, we usually use tools like "Plop" or "Hygen". NX's philosophy around file modification confuses me, and I'm not sure where to start to even modify:

If you have good resources to create generators, I will start to prepare some of my simplest custom generators to test them with huge-nx as soon as this feature will be released!

If communicating through GitHub issues ever becomes too tedious or clutters the repository too much, what's your preferred method of contact? Don't want to bother you too much :vulcan_salute:

stephenwade commented 3 months ago

I'm also interested in using this tool if I can integrate local generators. I would love a way to ensure that my entire workspace uses the local generators consistently and rectify any configuration drift.