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

feat(astro): add initial support for astro projects #2908

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

vladcos
Copy link
Contributor

@vladcos vladcos commented Sep 4, 2023

This draft PR adds basic support for the emerging https://astro.build (https://github.com/withastro/astro) framework.
Before this is ready I plan to:

  • add more options for configuration
  • add a few bundled deployment strategies (to github hosting and aws s3 + cloudfront) on top of the release workflow

Also I'm looking for advice how to allow consumers to configure the astro.config.ts which is obviously not as straightforward compared to YAML or JSON. I've read other pull requests and issues and it is my understanding that there is no solution or best practice in place. I have thought of the following options:

  1. Allow limited configuration via .projen.ts for most common cases and for extended configuration allow ejecting it so that the end user can configure it manually.
  2. Generate the fully managed astro.config.json and merge it with manually-edited astro.config.ts
  3. Skip configuration from .projen.ts altogether and just keep it simple and let the user manage it
  4. Use https://github.com/facebook/jscodeshift or other codemods to inject pieces of configuration depending on the selected options .projen.ts

Thanks


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@mrgrain
Copy link
Contributor

mrgrain commented Sep 13, 2023

Also I'm looking for advice how to allow consumers to configure the astro.config.ts which is obviously not as straightforward compared to YAML or JSON. I've read other pull requests and issues and it is my understanding that there is no solution or best practice in place. I have thought of the following options:

In general, I think projen wants to foster configuration as code. So if Astro already uses configuration as code - that's great! Provided it's not just a glorified JSON file.

The issue we have is that in order to support projen's component based configuration model, we need to give projen at least some control over the config. As a minimum, projen at least needs to be able to synth required config and replace it with previously synthd config. This is all doable already, and there are various strategies to implement a hybrid approach. The main challenge is for users to provide "complex configuration via projen". That is anything that can't be represented by a simple data type (string, number, bool, list map) or an enum-like class. The latter is very flexible, but falls short of giving users full control, e.g. they can't provide any arbitrary JS expression.

This is tricky to argue about without knowing much about astro's config or seeing some concrete examples.
As an idea, you might get quite far with this approach:

  • Generating astro.config.ts from the (limited) projen interface. Thus enabling components to inject config and abstract away from users.
  • Adding a sample file astro.user.config.ts that can hold any user written configuration.
  • Gracefully loading astro.user.config.ts into astro.config.ts (to do: in case of overlap, which config should get preference?)

@vladcos
Copy link
Contributor Author

vladcos commented Sep 15, 2023

@mrgrain Thanks for your input!

Unfortunately Astro does not support JSON or YML, the only option is generating a .js or a .ts config that might contain arbitrary js expressions.

https://docs.astro.build/en/reference/configuration-reference/

A simple case would look like that

//astro.config.ts
import {defineConfig, sharpImageService} from 'astro/config';

import tailwind from "@astrojs/tailwind";
import react from '@astrojs/react';

// https://astro.build/config
export default defineConfig({
  root: new URL("./foo", import.meta.url).toString(),
  // Resolves to the "./public" directory, relative to this config file
  publicDir: new URL("./public", import.meta.url).toString(),
  integrations: [tailwind(), react()],
  experimental: {
    assets: true
  },
  image: {
    service: sharpImageService(),
  },
});

Do you suggest doing something like

// astro.config.ts
import userConfig from './astro.user.config.ts;

const generatedConfig = defineConfig({
// synthd config
});

// mergeConfig might have special rules for merging  in case of overlap
export default mergeConfig(generatedConfig, userConfig)

Or we could do the merging during synth instead of the runtime approach? That way the user could preview the resulting merge output and make things easier to debug.

@mrgrain
Copy link
Contributor

mrgrain commented Sep 18, 2023

Unfortunately Astro does not support JSON or YML, the only option is generating a .js or a .ts config that might contain arbitrary js expressions.
[...]
A simple case would look like that

That example looks like it would be feasible to generate with the existing tools (read: build the string) from a projen options object. integrations and services would be an enum-like class or even separate classes I suppose.

The key question for me is, how complex configurations would get that we need to ship with projen. There are also other approaches we could explore when they get to complex, like publishing them as separate packages.

Do you suggest doing something like [...]

Yes, that's what I had in mind.

Or we could do the merging during synth instead of the runtime approach? That way the user could preview the resulting merge output and make things easier to debug.

This would be ideal. I just don't know how we would do this if we want/have to to allow users to define their config as arbitrary expressions.

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

Successfully merging this pull request may close these issues.

2 participants