Support integrations added in updateConfig() in astro:config:setup (#8672)
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
This commit is contained in:
parent
e8495c853b
commit
9b0114c7d3
3 changed files with 95 additions and 2 deletions
34
.changeset/cold-schools-yell.md
Normal file
34
.changeset/cold-schools-yell.md
Normal file
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
'astro': minor
|
||||
---
|
||||
|
||||
Support adding integrations dynamically
|
||||
|
||||
Astro integrations can now themselves dynamically add and configure additional integrations during set-up. This makes it possible for integration authors to bundle integrations more intelligently for their users.
|
||||
|
||||
In the following example, a custom integration checks whether `@astrojs/sitemap` is already configured. If not, the integration adds Astro’s sitemap integration, passing any desired configuration options:
|
||||
|
||||
```ts
|
||||
import sitemap from '@astrojs/sitemap';
|
||||
import type { AstroIntegration } from 'astro';
|
||||
|
||||
const MyIntegration = (): AstroIntegration => {
|
||||
return {
|
||||
name: 'my-integration',
|
||||
|
||||
'astro:config:setup': ({ config, updateConfig }) => {
|
||||
// Look for sitemap in user-configured integrations.
|
||||
const userSitemap = config.integrations.find(
|
||||
({ name }) => name === '@astrojs/sitemap'
|
||||
);
|
||||
|
||||
if (!userSitemap) {
|
||||
// If sitemap wasn’t found, add it.
|
||||
updateConfig({
|
||||
integrations: [sitemap({ /* opts */ }],
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
```
|
|
@ -75,7 +75,10 @@ export async function runHookConfigSetup({
|
|||
let addedClientDirectives = new Map<string, Promise<string>>();
|
||||
let astroJSXRenderer: AstroRenderer | null = null;
|
||||
|
||||
for (const integration of settings.config.integrations) {
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-for-of -- We need a for loop to be able to read integrations pushed while the loop is running.
|
||||
for (let i = 0; i < updatedConfig.integrations.length; i++) {
|
||||
const integration = updatedConfig.integrations[i];
|
||||
|
||||
/**
|
||||
* By making integration hooks optional, Astro can now ignore null or undefined Integrations
|
||||
* instead of giving an internal error most people can't read
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { expect } from 'chai';
|
||||
import { runHookBuildSetup } from '../../../dist/integrations/index.js';
|
||||
import { runHookBuildSetup, runHookConfigSetup } from '../../../dist/integrations/index.js';
|
||||
import { validateSupportedFeatures } from '../../../dist/integrations/astroFeaturesValidation.js';
|
||||
import { defaultLogger } from '../test-utils.js';
|
||||
|
||||
|
@ -29,6 +29,62 @@ describe('Integration API', () => {
|
|||
});
|
||||
expect(updatedViteConfig).to.haveOwnProperty('define');
|
||||
});
|
||||
|
||||
it('runHookConfigSetup can update Astro config', async () => {
|
||||
const site = 'https://test.com/';
|
||||
const updatedSettings = await runHookConfigSetup({
|
||||
logger: defaultLogger,
|
||||
settings: {
|
||||
config: {
|
||||
integrations: [
|
||||
{
|
||||
name: 'test',
|
||||
hooks: {
|
||||
"astro:config:setup": ({ updateConfig }) => {
|
||||
updateConfig({ site });
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(updatedSettings.config.site).to.equal(site);
|
||||
});
|
||||
|
||||
it('runHookConfigSetup runs integrations added by another integration', async () => {
|
||||
const site = 'https://test.com/';
|
||||
const updatedSettings = await runHookConfigSetup({
|
||||
logger: defaultLogger,
|
||||
settings: {
|
||||
config: {
|
||||
integrations: [
|
||||
{
|
||||
name: 'test',
|
||||
hooks: {
|
||||
"astro:config:setup": ({ updateConfig }) => {
|
||||
updateConfig({
|
||||
integrations: [{
|
||||
name: 'dynamically-added',
|
||||
hooks: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||
"astro:config:setup": ({ updateConfig }) => {
|
||||
updateConfig({ site });
|
||||
}
|
||||
},
|
||||
}],
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(updatedSettings.config.site).to.equal(site);
|
||||
expect(updatedSettings.config.integrations.length).to.equal(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Astro feature map', function () {
|
||||
|
|
Loading…
Reference in a new issue