Remove deprecated APIs (#5707)

* Remove deprecated Astro globals

* Remove deprecated hook param

* Fix test

* Add changeset

* Add TODO
This commit is contained in:
Bjorn Lu 2023-01-04 03:06:07 +08:00 committed by GitHub
parent 8fb28648f6
commit 5eba34fcc6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 87 additions and 217 deletions

View file

@ -0,0 +1,10 @@
---
'@astrojs/cloudflare': major
'@astrojs/deno': major
'@astrojs/image': minor
'@astrojs/netlify': major
'@astrojs/node': major
'@astrojs/vercel': major
---
Remove `astro:build:start` backwards compatibility code

View file

@ -0,0 +1,36 @@
---
'astro': major
---
Remove deprecated `Astro` global APIs, including `Astro.resolve`, `Astro.fetchContent`, and `Astro.canonicalURL`.
#### `Astro.resolve`
You can resolve asset paths using `import` instead. For example:
```astro
---
import 'style.css'
import imageUrl from './image.png'
---
<img src={imageUrl} />
```
See the [v0.25 migration guide](https://docs.astro.build/en/migrate/#deprecated-astroresolve) for more information.
#### `Astro.fetchContent`
Use `Astro.glob` instead to fetch markdown files, or migrate to the [Content Collections](https://docs.astro.build/en/guides/content-collections/) feature.
```js
let allPosts = await Astro.glob('./posts/*.md');
```
#### `Astro.canonicalURL`
Use `Astro.url` instead to construct the canonical URL.
```js
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
```

View file

@ -0,0 +1,24 @@
---
'astro': major
---
Remove `buildConfig` option parameter from integration `astro:build:start` hook in favour of the `build.config` option in the `astro:config:setup` hook.
```js
export default function myIntegration() {
return {
name: 'my-integration',
hooks: {
'astro:config:setup': ({ updateConfig }) => {
updateConfig({
build: {
client: '...',
server: '...',
serverEntry: '...',
},
});
},
},
};
}
```

View file

@ -10,7 +10,7 @@ export default function createIntegration(): AstroIntegration {
// See the @astrojs/react integration for an example
// https://github.com/withastro/astro/blob/main/packages/integrations/react/src/index.ts
},
'astro:build:start': ({ buildConfig }) => {
'astro:build:setup': ({ config, updateConfig }) => {
// See the @astrojs/netlify integration for an example
// https://github.com/withastro/astro/blob/main/packages/integrations/netlify/src/integration-functions.ts
},

View file

@ -109,18 +109,6 @@ export interface BuildConfig {
export interface AstroGlobal<Props extends Record<string, any> = Record<string, any>>
extends AstroGlobalPartial,
AstroSharedContext<Props> {
/**
* Canonical URL of the current page.
* @deprecated Use `Astro.url` instead.
*
* Example:
* ```astro
* ---
* const canonicalURL = new URL(Astro.url.pathname, Astro.site);
* ---
* ```
*/
canonicalURL: URL;
/**
* A full URL object of the request URL.
* Equivalent to: `new URL(Astro.request.url)`
@ -254,12 +242,6 @@ export interface AstroGlobal<Props extends Record<string, any> = Record<string,
type MarkdowFileExtension = typeof SUPPORTED_MARKDOWN_FILE_EXTENSIONS[number];
export interface AstroGlobalPartial {
/**
* @deprecated since version 0.24. See the {@link https://astro.build/deprecated/resolve upgrade guide} for more details.
*/
resolve(path: string): string;
/** @deprecated since version 0.26. Use [Astro.glob()](https://docs.astro.build/en/reference/api-reference/#astroglob) instead. */
fetchContent(globStr: string): Promise<any[]>;
/**
* Fetch local files into your static site setup
*
@ -1390,7 +1372,7 @@ export interface AstroIntegration {
'astro:server:start'?: (options: { address: AddressInfo }) => void | Promise<void>;
'astro:server:done'?: () => void | Promise<void>;
'astro:build:ssr'?: (options: { manifest: SerializedSSRManifest }) => void | Promise<void>;
'astro:build:start'?: (options: { buildConfig: BuildConfig }) => void | Promise<void>;
'astro:build:start'?: () => void | Promise<void>;
'astro:build:setup'?: (options: {
vite: vite.InlineConfig;
pages: Map<string, PageBuildData>;

View file

@ -90,7 +90,7 @@ class AstroBuilder {
server: this.settings.config.build.server,
serverEntry: this.settings.config.build.serverEntry,
};
await runHookBuildStart({ config: this.settings.config, buildConfig, logging: this.logging });
await runHookBuildStart({ config: this.settings.config, logging: this.logging });
this.validateConfig();
info(this.logging, 'build', `output target: ${colors.green(this.settings.config.output)}`);

View file

@ -183,7 +183,7 @@ export function createResult(args: CreateResultArgs): SSRResult {
}
}
return Reflect.get(request, clientAddressSymbol);
return Reflect.get(request, clientAddressSymbol) as string;
},
get cookies() {
if (cookies) {
@ -207,59 +207,10 @@ export function createResult(args: CreateResultArgs): SSRResult {
});
}
: onlyAvailableInSSR('Astro.redirect'),
resolve(path: string) {
let extra = `This can be replaced with a dynamic import like so: await import("${path}")`;
if (isCSSRequest(path)) {
extra = `It looks like you are resolving styles. If you are adding a link tag, replace with this:
---
import "${path}";
---
`;
} else if (isScriptRequest(path)) {
extra = `It looks like you are resolving scripts. If you are adding a script tag, replace with this:
<script type="module" src={(await import("${path}?url")).default}></script>
or consider make it a module like so:
<script>
import MyModule from "${path}";
</script>
`;
}
warn(
args.logging,
`deprecation`,
`${bold(
'Astro.resolve()'
)} is deprecated. We see that you are trying to resolve ${path}.
${extra}`
);
// Intentionally return an empty string so that it is not relied upon.
return '';
},
response: response as AstroGlobal['response'],
slots: astroSlots as unknown as AstroGlobal['slots'],
};
Object.defineProperty(Astro, 'canonicalURL', {
get: function () {
warn(
args.logging,
'deprecation',
`${bold('Astro.canonicalURL')} is deprecated! Use \`Astro.url\` instead.
Example:
---
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
---
`
);
return new URL(this.request.url.pathname, this.site);
},
});
Object.defineProperty(Astro, '__renderMarkdown', {
// Ensure this API is not exposed to users
enumerable: false,

View file

@ -206,55 +206,18 @@ export async function runHookServerDone({
export async function runHookBuildStart({
config,
buildConfig,
logging,
}: {
config: AstroConfig;
buildConfig: BuildConfig;
logging: LogOptions;
}) {
function warnDeprecated(
integration: AstroIntegration,
prop: 'server' | 'client' | 'serverEntry'
) {
let value: any = Reflect.get(buildConfig, prop);
Object.defineProperty(buildConfig, prop, {
enumerable: true,
get() {
return value;
},
set(newValue) {
value = newValue;
warn(
logging,
'astro:build:start',
`Your adapter ${bold(integration.name)} is using a deprecated API, buildConfig. ${bold(
prop
)} config should be set via config.build.${prop} instead.`
);
},
});
return () => {
Object.defineProperty(buildConfig, prop, {
enumerable: true,
value,
});
};
}
for (const integration of config.integrations) {
if (integration?.hooks?.['astro:build:start']) {
const undoClientWarning = warnDeprecated(integration, 'client');
const undoServerWarning = warnDeprecated(integration, 'server');
const undoServerEntryWarning = warnDeprecated(integration, 'serverEntry');
await withTakingALongTimeMsg({
name: integration.name,
hookResult: integration.hooks['astro:build:start']({ buildConfig }),
hookResult: integration.hooks['astro:build:start'](),
logging,
});
undoClientWarning();
undoServerEntryWarning();
undoServerWarning();
}
}
}

View file

@ -1,13 +1,6 @@
import type { AstroGlobalPartial } from '../../@types/astro';
import { ASTRO_VERSION } from '../../core/constants.js';
/** Create the Astro.fetchContent() runtime function. */
function createDeprecatedFetchContentFn() {
return () => {
throw new Error('Deprecated: Astro.fetchContent() has been replaced with Astro.glob().');
};
}
/** Create the Astro.glob() runtime function. */
function createAstroGlobFn() {
const globHandler = (importMetaGlobResult: Record<string, any>, globValue: () => any) => {
@ -25,29 +18,15 @@ function createAstroGlobFn() {
// This is used to create the top-level Astro global; the one that you can use
// Inside of getStaticPaths.
// TODO: remove `_filePathname` and `_projectRootStr` from the compiler
export function createAstro(
filePathname: string,
_site: string | undefined,
projectRootStr: string
_filePathname: string,
site: string | undefined,
_projectRootStr: string
): AstroGlobalPartial {
const site = _site ? new URL(_site) : undefined;
const referenceURL = new URL(filePathname, `http://localhost`);
const projectRoot = new URL(projectRootStr);
return {
site,
site: site ? new URL(site) : undefined,
generator: `Astro v${ASTRO_VERSION}`,
fetchContent: createDeprecatedFetchContentFn(),
glob: createAstroGlobFn(),
// INVESTIGATE is there a use-case for multi args?
// TODO remove in 2.0
resolve(...segments: string[]) {
let resolved = segments.reduce((u, segment) => new URL(segment, u), referenceURL).pathname;
// When inside of project root, remove the leading path so you are
// left with only `/src/images/tower.png`
if (resolved.startsWith(projectRoot.pathname)) {
resolved = '/' + resolved.slice(projectRoot.pathname.length);
}
return resolved;
},
};
}

View file

@ -1,5 +1,4 @@
import { expect } from 'chai';
import { load as cheerioLoad } from 'cheerio';
import { loadFixture } from './test-utils.js';
import { viteID } from '../dist/core/util.js';
@ -8,15 +7,18 @@ describe('Integration buildConfig hook', () => {
let fixture;
before(async () => {
let _config;
fixture = await loadFixture({
root: './fixtures/ssr-request/',
output: 'server',
adapter: {
name: 'my-ssr-adapter',
hooks: {
'astro:config:setup': ({ updateConfig }) => {
'astro:config:setup': ({ config, updateConfig }) => {
updateConfig({
build: {
server: new URL('./dist/.root/server/', config.root),
client: new URL('./dist/.root/client/', config.root),
},
vite: {
plugins: [
{
@ -40,12 +42,7 @@ describe('Integration buildConfig hook', () => {
},
});
},
'astro:build:start': ({ buildConfig }) => {
buildConfig.server = new URL('./dist/.root/server/', _config.root);
buildConfig.client = new URL('./dist/.root/client/', _config.root);
},
'astro:config:done': ({ config, setAdapter }) => {
_config = config;
'astro:config:done': ({ setAdapter }) => {
setAdapter({
name: 'my-ssr-adapter',
serverEntrypoint: '@my-ssr',

View file

@ -39,14 +39,12 @@ const SERVER_BUILD_FOLDER = '/$server_build/';
export default function createIntegration(args?: Options): AstroIntegration {
let _config: AstroConfig;
let _buildConfig: BuildConfig;
let needsBuildConfig = false;
const isModeDirectory = args?.mode === 'directory';
return {
name: '@astrojs/cloudflare',
hooks: {
'astro:config:setup': ({ config, updateConfig }) => {
needsBuildConfig = !config.build.client;
updateConfig({
build: {
client: new URL(`.${config.base}`, config.outDir),
@ -90,14 +88,6 @@ export default function createIntegration(args?: Options): AstroIntegration {
vite.ssr.target = vite.ssr.target || 'webworker';
}
},
'astro:build:start': ({ buildConfig }) => {
// Backwards compat
if (needsBuildConfig) {
buildConfig.client = new URL(`.${_config.base}`, _config.outDir);
buildConfig.server = new URL(`.${SERVER_BUILD_FOLDER}`, _config.outDir);
buildConfig.serverEntry = '_worker.js';
}
},
'astro:build:done': async () => {
const entryPath = fileURLToPath(new URL(_buildConfig.serverEntry, _buildConfig.server)),
entryUrl = new URL(_buildConfig.serverEntry, _config.outDir),

View file

@ -31,12 +31,10 @@ export function getAdapter(args?: Options): AstroAdapter {
export default function createIntegration(args?: Options): AstroIntegration {
let _buildConfig: BuildConfig;
let _vite: any;
let needsBuildConfig = false;
return {
name: '@astrojs/deno',
hooks: {
'astro:config:done': ({ setAdapter, config }) => {
needsBuildConfig = !config.build.client;
setAdapter(getAdapter(args));
_buildConfig = config.build;
@ -47,12 +45,6 @@ export default function createIntegration(args?: Options): AstroIntegration {
);
}
},
'astro:build:start': ({ buildConfig }) => {
// Backwards compat
if (needsBuildConfig) {
_buildConfig = buildConfig;
}
},
'astro:build:setup': ({ vite, target }) => {
if (target === 'server') {
_vite = vite;

View file

@ -53,7 +53,6 @@ export default function integration(options: IntegrationOptions = {}): AstroInte
let _config: AstroConfig;
let _buildConfig: BuildConfig;
let needsBuildConfig = false;
// During SSG builds, this is used to track all transformed images required.
const staticImages = new Map<string, Map<string, TransformOptions>>();
@ -80,7 +79,6 @@ export default function integration(options: IntegrationOptions = {}): AstroInte
name: PKG_NAME,
hooks: {
'astro:config:setup': async ({ command, config, updateConfig, injectRoute }) => {
needsBuildConfig = !config.build?.server;
_config = config;
updateConfig({
vite: getViteConfiguration(command === 'dev'),
@ -107,18 +105,13 @@ export default function integration(options: IntegrationOptions = {}): AstroInte
_config = config;
_buildConfig = config.build;
},
'astro:build:start': ({ buildConfig }) => {
'astro:build:start': () => {
const adapterName = _config.adapter?.name;
if (adapterName && UNSUPPORTED_ADAPTERS.has(adapterName)) {
throw new Error(
`@astrojs/image is not supported with the ${adapterName} adapter. Please choose a Node.js compatible adapter.`
);
}
// Backwards compat
if (needsBuildConfig) {
_buildConfig = buildConfig;
}
},
'astro:build:setup': async () => {
// Used to cache all images rendered to HTML

View file

@ -111,13 +111,11 @@ export function netlifyEdgeFunctions({ dist }: NetlifyEdgeFunctionsOptions = {})
let _config: AstroConfig;
let entryFile: string;
let _buildConfig: BuildConfig;
let needsBuildConfig = false;
let _vite: any;
return {
name: '@astrojs/netlify/edge-functions',
hooks: {
'astro:config:setup': ({ config, updateConfig }) => {
needsBuildConfig = !config.build.client;
// Add a plugin that shims the global environment.
const injectPlugin: VitePlugin = {
name: '@astrojs/netlify/plugin-inject',
@ -156,15 +154,6 @@ export function netlifyEdgeFunctions({ dist }: NetlifyEdgeFunctionsOptions = {})
);
}
},
'astro:build:start': ({ buildConfig }) => {
if (needsBuildConfig) {
buildConfig.client = _config.outDir;
buildConfig.server = new URL('./.netlify/edge-functions/', _config.root);
buildConfig.serverEntry = 'entry.js';
_buildConfig = buildConfig;
entryFile = buildConfig.serverEntry.replace(/\.m?js/, '');
}
},
'astro:build:setup': ({ vite, target }) => {
if (target === 'server') {
_vite = vite;

View file

@ -22,12 +22,10 @@ function netlifyFunctions({
}: NetlifyFunctionsOptions = {}): AstroIntegration {
let _config: AstroConfig;
let entryFile: string;
let needsBuildConfig = false;
return {
name: '@astrojs/netlify',
hooks: {
'astro:config:setup': ({ config, updateConfig }) => {
needsBuildConfig = !config.build.client;
const outDir = dist ?? new URL('./dist/', config.root);
updateConfig({
outDir,
@ -49,13 +47,6 @@ function netlifyFunctions({
);
}
},
'astro:build:start': ({ buildConfig }) => {
if (needsBuildConfig) {
buildConfig.client = _config.outDir;
buildConfig.server = new URL('./.netlify/functions-internal/', _config.root);
entryFile = buildConfig.serverEntry.replace(/\.m?js/, '');
}
},
'astro:build:done': async ({ routes, dir }) => {
await createRedirects(routes, dir, entryFile, false);
},

View file

@ -16,7 +16,6 @@ export default function createIntegration(userOptions: UserOptions): AstroIntegr
throw new Error(`[@astrojs/node] Setting the 'mode' option is required.`);
}
let needsBuildConfig = false;
let _options: Options;
return {
name: '@astrojs/node',
@ -31,7 +30,6 @@ export default function createIntegration(userOptions: UserOptions): AstroIntegr
});
},
'astro:config:done': ({ setAdapter, config }) => {
needsBuildConfig = !config.build?.server;
_options = {
...userOptions,
client: config.build.client?.toString(),
@ -45,13 +43,6 @@ export default function createIntegration(userOptions: UserOptions): AstroIntegr
console.warn(`[@astrojs/node] \`output: "server"\` is required to use this adapter.`);
}
},
'astro:build:start': ({ buildConfig }) => {
// Backwards compat
if (needsBuildConfig) {
_options.client = buildConfig.client.toString();
_options.server = buildConfig.server.toString();
}
},
},
};
}

View file

@ -30,13 +30,11 @@ export default function vercelEdge({ includeFiles = [] }: VercelEdgeConfig = {})
let buildTempFolder: URL;
let functionFolder: URL;
let serverEntry: string;
let needsBuildConfig = false;
return {
name: PACKAGE_NAME,
hooks: {
'astro:config:setup': ({ config, updateConfig }) => {
needsBuildConfig = !config.build.client;
const outDir = getVercelOutput(config.root);
updateConfig({
outDir,
@ -61,13 +59,6 @@ export default function vercelEdge({ includeFiles = [] }: VercelEdgeConfig = {})
`);
}
},
'astro:build:start': ({ buildConfig }) => {
if (needsBuildConfig) {
buildConfig.client = new URL('./static/', _config.outDir);
buildTempFolder = buildConfig.server = new URL('./dist/', _config.root);
serverEntry = buildConfig.serverEntry = 'entry.mjs';
}
},
'astro:build:setup': ({ vite, target }) => {
if (target === 'server') {
vite.resolve ||= {};

View file

@ -29,13 +29,11 @@ export default function vercelServerless({
let buildTempFolder: URL;
let functionFolder: URL;
let serverEntry: string;
let needsBuildConfig = false;
return {
name: PACKAGE_NAME,
hooks: {
'astro:config:setup': ({ config, updateConfig }) => {
needsBuildConfig = !config.build.client;
const outDir = getVercelOutput(config.root);
updateConfig({
outDir,
@ -60,13 +58,6 @@ export default function vercelServerless({
`);
}
},
'astro:build:start': ({ buildConfig }) => {
if (needsBuildConfig) {
buildConfig.client = new URL('./static/', _config.outDir);
buildTempFolder = buildConfig.server = new URL('./dist/', _config.root);
serverEntry = buildConfig.serverEntry = 'entry.js';
}
},
'astro:build:done': async ({ routes }) => {
// Merge any includes from `vite.assetsInclude
const inc = includeFiles?.map((file) => new URL(file, _config.root)) || [];