beemojs / beemo

🤖 Centralized configuration layer for dev tools. Beep boop.
https://beemo.dev
MIT License
143 stars 9 forks source link

Add Ability to Rename Generated Config Files #154

Closed ninablanson-p44 closed 2 years ago

ninablanson-p44 commented 2 years ago

Hello!

My team is using beemo for a library that is being converted to ESM. Both Prettier and ESLint suggest using a .cjs file instead of a .js file since they do not yet have ESM support. These libraries also allow .json as a filetype, which is also supported by beemo (as seen with the Typescript driver).

Is it possible to add a way to change the name of the generated config files? I looked into Driver and saw that there is a way to set the filename with the configName property. Could there be a function like getDependencies that overrides the name based on options? Or maybe there is some other, better way to get this behavior? I would be willing to create a PR as well, I just need to know the best recommended route.

Thank you!

milesj commented 2 years ago

@convey-ninablanson For now you can use templates, which is a bit of overhead but will work for the interim: https://beemo.dev/docs/consumer#custom-configs-with-templates

I plan to switch to .cjs in the next major when possible. But I can also look into other alternatives.

ninablanson-p44 commented 2 years ago

Thanks for the tip, @milesj! I was able to create a template and get it working with our ESM library.

For any others who are having similar problems, this is the template I created for Prettier:

import {
  ConfigContext,
  ConfigObject,
  ConfigTemplateOptions,
  ConfigTemplateResult,
  Path,
} from '@beemo/core';
import { Event } from '@boost/event';
import fs from 'node:fs';
import { PrettierArgs } from '@beemo/driver-prettier';

const event = new Event<[ConfigContext, Path, { ignore: string[] }]>('create-ignore-file');

export default function customTemplate(
  configs: ConfigObject[],
  options: ConfigTemplateOptions,
): ConfigTemplateResult {
  const config = configs.reduce((combined, current) => {
    // There may be others that should be merged vs. replaced, but we just care about 'ignore'.
    const { ignore: combinedIgnore = [], ...otherCombined } = combined;
    const { ignore: currentIgnore = [], ...otherCurrent } = current;

    return {
      ...otherCombined,
      ...otherCurrent,
      ignore: [...(combinedIgnore as string[]), ...(currentIgnore as string[])],
    };
  }, {});
  const { ignore, ...partialConfig } = config;
  const formattedConfig = `module.exports = ${JSON.stringify(partialConfig, null, 2)};`;

  // Create the .prettierignore file, if necessary.
  // See: https://github.com/beemojs/beemo/blob/master/packages/driver-prettier/src/PrettierDriver.ts#L29
  if (Array.isArray(ignore)) {
    const ignorePath = options.context.cwd.append('.prettierignore');

    event.emit([options.context as ConfigContext<PrettierArgs>, ignorePath, { ignore }]);

    fs.writeFileSync(ignorePath.path(), ignore.join('\n'));

    options.context.addConfigPath('prettier', ignorePath);
  }

  return {
    config: formattedConfig,
    path: options.context.cwd.append('prettier.config.cjs'),
  };
}

The template I made for ESLint was nearly identical, just changing the names of the types, filenames, ect. Since there is a workaround, I'll close this request. Thanks again!