Output assets to _astro
directory (#5772)
* WIP: emit assets to _astro * chore: better _astro handling * refactor: emit server assets to `chunks/` * chore: update /asset tests * test: add explicit build output tests * fix: update image to emit to configured asset path * chore: update changeset * chore: update image tests * chore: update image tests * test: update css test * test: update bundling test * test: update tests * Update packages/astro/src/@types/astro.ts Co-authored-by: Chris Swithinbank <swithinbank@gmail.com> * Update packages/astro/src/@types/astro.ts Co-authored-by: Chris Swithinbank <swithinbank@gmail.com> * Update packages/astro/src/@types/astro.ts Co-authored-by: Chris Swithinbank <swithinbank@gmail.com> * chore: add clarifying comment Co-authored-by: Nate Moore <nate@astro.build> Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
This commit is contained in:
parent
7572f74022
commit
f8f4d49aba
32 changed files with 367 additions and 135 deletions
|
@ -1,8 +1,10 @@
|
|||
---
|
||||
'@astrojs/deno': major
|
||||
'@astrojs/netlify': major
|
||||
'@astrojs/image': minor
|
||||
'@astrojs/image': major
|
||||
'astro': major
|
||||
---
|
||||
|
||||
Builds chunks into the `assets` folder. This simplifies configuring immutable caching with your adapter provider as all files are now in the same `assets` folder.
|
||||
**Breaking Change**: client assets are built to an `_astro` directory rather than the previous `assets` directory. This setting can now be controlled by the new `build` configuration option named `assets`.
|
||||
|
||||
This should simplify configuring immutable caching with your adapter provider as all files are now in the same `_astro` directory.
|
||||
|
|
|
@ -586,6 +586,25 @@ export interface AstroUserConfig {
|
|||
* ```
|
||||
*/
|
||||
server?: string;
|
||||
/**
|
||||
* @docs
|
||||
* @name build.assets
|
||||
* @type {string}
|
||||
* @default `'_astro'`
|
||||
* @see outDir
|
||||
* @version 2.0.0
|
||||
* @description
|
||||
* Specifies the directory in the build output where Astro-generated assets (bundled JS and CSS for example) should live.
|
||||
*
|
||||
* ```js
|
||||
* {
|
||||
* build: {
|
||||
* assets: '_custom'
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
assets?: string;
|
||||
/**
|
||||
* @docs
|
||||
* @name build.serverEntry
|
||||
|
|
|
@ -10,9 +10,10 @@ import {
|
|||
BuildInternals,
|
||||
createBuildInternals,
|
||||
eachPrerenderedPageData,
|
||||
isHoistedScript,
|
||||
} from '../../core/build/internal.js';
|
||||
import { emptyDir, removeDir } from '../../core/fs/index.js';
|
||||
import { prependForwardSlash } from '../../core/path.js';
|
||||
import { emptyDir, removeDir, removeEmptyDirs } from '../../core/fs/index.js';
|
||||
import { appendForwardSlash, prependForwardSlash } from '../../core/path.js';
|
||||
import { isModeServerWithNoAdapter } from '../../core/util.js';
|
||||
import { runHookBuildSetup } from '../../integrations/index.js';
|
||||
import { PAGE_SCRIPT_ID } from '../../vite-plugin-scripts/index.js';
|
||||
|
@ -133,8 +134,10 @@ async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, inp
|
|||
input: [],
|
||||
output: {
|
||||
format: 'esm',
|
||||
chunkFileNames: 'chunks/[name].[hash].mjs',
|
||||
assetFileNames: 'assets/[name].[hash][extname]',
|
||||
// Server chunks can't go in the assets (_astro) folder
|
||||
// We need to keep these separate
|
||||
chunkFileNames: `chunks/[name].[hash].mjs`,
|
||||
assetFileNames: `${settings.config.build.assets}/[name].[hash][extname]`,
|
||||
...viteConfig.build?.rollupOptions?.output,
|
||||
entryFileNames: opts.buildConfig.serverEntry,
|
||||
},
|
||||
|
@ -212,9 +215,9 @@ async function clientBuild(
|
|||
input: Array.from(input),
|
||||
output: {
|
||||
format: 'esm',
|
||||
entryFileNames: 'assets/[name].[hash].js',
|
||||
chunkFileNames: 'assets/chunks/[name].[hash].js',
|
||||
assetFileNames: 'assets/[name].[hash][extname]',
|
||||
entryFileNames: `${settings.config.build.assets}/[name].[hash].js`,
|
||||
chunkFileNames: `${settings.config.build.assets}/[name].[hash].js`,
|
||||
assetFileNames: `${settings.config.build.assets}/[name].[hash][extname]`,
|
||||
...viteConfig.build?.rollupOptions?.output,
|
||||
},
|
||||
preserveEntrySignatures: 'exports-only',
|
||||
|
@ -285,25 +288,8 @@ async function cleanStaticOutput(opts: StaticBuildOptions, internals: BuildInter
|
|||
await fs.promises.writeFile(url, value, { encoding: 'utf8' });
|
||||
})
|
||||
);
|
||||
// Map directories heads from the .mjs files
|
||||
const directories: Set<string> = new Set();
|
||||
files.forEach((i) => {
|
||||
const splitFilePath = i.split(path.sep);
|
||||
// If the path is more than just a .mjs filename itself
|
||||
if (splitFilePath.length > 1) {
|
||||
directories.add(splitFilePath[0]);
|
||||
}
|
||||
});
|
||||
// Attempt to remove only those folders which are empty
|
||||
await Promise.all(
|
||||
Array.from(directories).map(async (filename) => {
|
||||
const url = new URL(filename, out);
|
||||
const folder = await fs.promises.readdir(url);
|
||||
if (!folder.length) {
|
||||
await fs.promises.rm(url, { recursive: true, force: true });
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
removeEmptyDirs(out);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,28 +307,10 @@ async function cleanServerOutput(opts: StaticBuildOptions) {
|
|||
await fs.promises.rm(url);
|
||||
})
|
||||
);
|
||||
// Map directories heads from the .mjs files
|
||||
const directories: Set<string> = new Set();
|
||||
files.forEach((i) => {
|
||||
const splitFilePath = i.split(path.sep);
|
||||
// If the path is more than just a .mjs filename itself
|
||||
if (splitFilePath.length > 1) {
|
||||
directories.add(splitFilePath[0]);
|
||||
}
|
||||
});
|
||||
// Attempt to remove only those folders which are empty
|
||||
await Promise.all(
|
||||
Array.from(directories).map(async (filename) => {
|
||||
const url = new URL(filename, out);
|
||||
const dir = await glob(fileURLToPath(url));
|
||||
// Do not delete chunks/ directory!
|
||||
if (filename === 'chunks') return;
|
||||
if (!dir.length) {
|
||||
await fs.promises.rm(url, { recursive: true, force: true });
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
removeEmptyDirs(out);
|
||||
}
|
||||
|
||||
// Clean out directly if the outDir is outside of root
|
||||
if (out.toString() !== opts.settings.config.outDir.toString()) {
|
||||
// Copy assets before cleaning directory if outside root
|
||||
|
@ -374,10 +342,11 @@ async function ssrMoveAssets(opts: StaticBuildOptions) {
|
|||
const serverRoot =
|
||||
opts.settings.config.output === 'static' ? opts.buildConfig.client : opts.buildConfig.server;
|
||||
const clientRoot = opts.buildConfig.client;
|
||||
const serverAssets = new URL('./assets/', serverRoot);
|
||||
const clientAssets = new URL('./assets/', clientRoot);
|
||||
const files = await glob('assets/**/*', {
|
||||
cwd: fileURLToPath(serverRoot),
|
||||
const assets = opts.settings.config.build.assets;
|
||||
const serverAssets = new URL(`./${assets}/`, appendForwardSlash(serverRoot.toString()));
|
||||
const clientAssets = new URL(`./${assets}/`, appendForwardSlash(clientRoot.toString()));
|
||||
const files = await glob(`**/*`, {
|
||||
cwd: fileURLToPath(serverAssets),
|
||||
});
|
||||
|
||||
if (files.length > 0) {
|
||||
|
@ -385,11 +354,11 @@ async function ssrMoveAssets(opts: StaticBuildOptions) {
|
|||
await fs.promises.mkdir(clientAssets, { recursive: true });
|
||||
await Promise.all(
|
||||
files.map(async (filename) => {
|
||||
const currentUrl = new URL(filename, serverRoot);
|
||||
const clientUrl = new URL(filename, clientRoot);
|
||||
const currentUrl = new URL(filename, appendForwardSlash(serverAssets.toString()));
|
||||
const clientUrl = new URL(filename, appendForwardSlash(clientAssets.toString()));
|
||||
return fs.promises.rename(currentUrl, clientUrl);
|
||||
})
|
||||
);
|
||||
removeDir(serverAssets);
|
||||
removeEmptyDirs(serverAssets);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ const ASTRO_CONFIG_DEFAULTS: AstroUserConfig & any = {
|
|||
format: 'directory',
|
||||
client: './dist/client/',
|
||||
server: './dist/server/',
|
||||
assets: '_astro',
|
||||
serverEntry: 'entry.mjs',
|
||||
},
|
||||
server: {
|
||||
|
@ -102,6 +103,7 @@ export const AstroConfigSchema = z.object({
|
|||
.optional()
|
||||
.default(ASTRO_CONFIG_DEFAULTS.build.server)
|
||||
.transform((val) => new URL(val)),
|
||||
assets: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.assets),
|
||||
serverEntry: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.serverEntry),
|
||||
})
|
||||
.optional()
|
||||
|
@ -246,6 +248,7 @@ export function createRelativeSchema(cmd: string, fileProtocolRoot: URL) {
|
|||
.optional()
|
||||
.default(ASTRO_CONFIG_DEFAULTS.build.server)
|
||||
.transform((val) => new URL(val, fileProtocolRoot)),
|
||||
assets: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.assets),
|
||||
serverEntry: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.serverEntry),
|
||||
})
|
||||
.optional()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { appendForwardSlash } from '../path.js';
|
||||
|
||||
const isWindows = process.platform === 'win32';
|
||||
|
||||
|
@ -10,6 +11,24 @@ export function removeDir(_dir: URL): void {
|
|||
fs.rmSync(dir, { recursive: true, force: true, maxRetries: 3 });
|
||||
}
|
||||
|
||||
export function removeEmptyDirs(root: URL): void {
|
||||
const dir = fileURLToPath(root);
|
||||
if (!fs.statSync(dir).isDirectory()) return;
|
||||
let files = fs.readdirSync(dir);
|
||||
|
||||
if (files.length > 0) {
|
||||
files.map(file => {
|
||||
const url = new URL(`./${file}`, appendForwardSlash(root.toString()));
|
||||
removeEmptyDirs(url);
|
||||
})
|
||||
files = fs.readdirSync(dir);
|
||||
}
|
||||
|
||||
if (files.length === 0) {
|
||||
fs.rmdirSync(dir);
|
||||
}
|
||||
}
|
||||
|
||||
export function emptyDir(_dir: URL, skip?: Set<string>): void {
|
||||
const dir = fileURLToPath(_dir);
|
||||
if (!fs.existsSync(dir)) return undefined;
|
||||
|
|
|
@ -29,7 +29,7 @@ describe('CSS', function () {
|
|||
// get bundled CSS (will be hashed, hence DOM query)
|
||||
html = await fixture.readFile('/index.html');
|
||||
$ = cheerio.load(html);
|
||||
const bundledCSSHREF = $('link[rel=stylesheet][href^=/assets/]').attr('href');
|
||||
const bundledCSSHREF = $('link[rel=stylesheet][href^=/_astro/]').attr('href');
|
||||
bundledCSS = (await fixture.readFile(bundledCSSHREF.replace(/^\/?/, '/')))
|
||||
.replace(/\s/g, '')
|
||||
.replace('/n', '');
|
||||
|
@ -364,7 +364,7 @@ describe('CSS', function () {
|
|||
});
|
||||
|
||||
it('remove unused styles from client:load components', async () => {
|
||||
const bundledAssets = await fixture.readdir('./assets');
|
||||
const bundledAssets = await fixture.readdir('./_astro');
|
||||
// SvelteDynamic styles is already included in the main page css asset
|
||||
const unusedCssAsset = bundledAssets.find((asset) => /SvelteDynamic\..*\.css/.test(asset));
|
||||
expect(unusedCssAsset, 'Found unused style ' + unusedCssAsset).to.be.undefined;
|
||||
|
|
|
@ -5,9 +5,9 @@ import { loadFixture } from './test-utils.js';
|
|||
// note: the hashes should be deterministic, but updating the file contents will change hashes
|
||||
// be careful not to test that the HTML simply contains CSS, because it always will! filename and quanity matter here (bundling).
|
||||
const EXPECTED_CSS = {
|
||||
'/index.html': ['/assets/'], // don’t match hashes, which change based on content
|
||||
'/one/index.html': ['/assets/'],
|
||||
'/two/index.html': ['/assets/'],
|
||||
'/index.html': ['/_astro/'], // don’t match hashes, which change based on content
|
||||
'/one/index.html': ['/_astro/'],
|
||||
'/two/index.html': ['/_astro/'],
|
||||
};
|
||||
const UNEXPECTED_CSS = [
|
||||
'/src/components/nav.css',
|
||||
|
@ -61,12 +61,12 @@ describe('CSS Bundling', function () {
|
|||
});
|
||||
|
||||
it('there are 4 css files', async () => {
|
||||
const dir = await fixture.readdir('/assets');
|
||||
const dir = await fixture.readdir('/_astro');
|
||||
expect(dir).to.have.a.lengthOf(4);
|
||||
});
|
||||
|
||||
it('CSS includes hashes', async () => {
|
||||
const [firstFound] = await fixture.readdir('/assets');
|
||||
const [firstFound] = await fixture.readdir('/_astro');
|
||||
expect(firstFound).to.match(/[a-z]+\.[0-9a-z]{8}\.css/);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -75,6 +75,6 @@ describe('Dynamic components subpath', () => {
|
|||
expect($('astro-island').html()).to.equal('');
|
||||
// test 2: has component url
|
||||
const attr = $('astro-island').attr('component-url');
|
||||
expect(attr).to.include(`blog/assets/PersistentCounter`);
|
||||
expect(attr).to.include(`blog/_astro/PersistentCounter`);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -52,7 +52,7 @@ describe('Environment Variables', () => {
|
|||
});
|
||||
|
||||
it('includes public env in client-side JS', async () => {
|
||||
let dirs = await fixture.readdir('/assets');
|
||||
let dirs = await fixture.readdir('/_astro');
|
||||
console.log(dirs);
|
||||
let found = false;
|
||||
|
||||
|
@ -62,7 +62,7 @@ describe('Environment Variables', () => {
|
|||
await Promise.all(
|
||||
dirs.map(async (path) => {
|
||||
if (path.endsWith('.js')) {
|
||||
let js = await fixture.readFile(`/assets/${path}`);
|
||||
let js = await fixture.readFile(`/_astro/${path}`);
|
||||
if (js.includes('BLUE_BAYOU')) {
|
||||
found = true;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ describe('Scripts (hoisted and not)', () => {
|
|||
|
||||
// test 2: inside assets
|
||||
let entryURL = $('script').attr('src');
|
||||
expect(entryURL.includes('assets/')).to.equal(true);
|
||||
expect(entryURL.includes('_astro/')).to.equal(true);
|
||||
});
|
||||
|
||||
it('External page using non-hoist scripts that are not modules are built standalone', async () => {
|
||||
|
@ -85,7 +85,7 @@ describe('Scripts (hoisted and not)', () => {
|
|||
|
||||
// test 2: inside assets
|
||||
let entryURL = $('script').attr('src');
|
||||
expect(entryURL.includes('assets/')).to.equal(true);
|
||||
expect(entryURL.includes('_astro/')).to.equal(true);
|
||||
});
|
||||
|
||||
it('Scripts added via Astro.glob are hoisted', async () => {
|
||||
|
|
171
packages/astro/test/build-assets.test.js
Normal file
171
packages/astro/test/build-assets.test.js
Normal file
|
@ -0,0 +1,171 @@
|
|||
import { expect } from 'chai';
|
||||
import * as cheerio from 'cheerio';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { preact } from './fixtures/before-hydration/deps.mjs';
|
||||
import testAdapter from './test-adapter.js';
|
||||
|
||||
describe('build assets (static)', () => {
|
||||
describe('with default configuration', () => {
|
||||
/** @type {import('./test-utils').Fixture} */
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/build-assets/',
|
||||
integrations: [preact()],
|
||||
});
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('Populates /_astro directory', async () => {
|
||||
let files = await fixture.readdir('/_astro');
|
||||
expect(files.length).to.be.greaterThan(0);
|
||||
});
|
||||
|
||||
it('Defaults to flat /_astro output', async () => {
|
||||
let files = await fixture.readdir('/_astro');
|
||||
for (const file of files) {
|
||||
expect(file.slice(1)).to.not.contain('/');
|
||||
}
|
||||
});
|
||||
|
||||
it('emits CSS assets to /_astro', async () => {
|
||||
let html = await fixture.readFile('/index.html');
|
||||
let $ = cheerio.load(html);
|
||||
|
||||
expect($('link[href$=".css"]').attr('href')).to.match(/^\/_astro\//);
|
||||
});
|
||||
|
||||
it('emits JS assets to /_astro', async () => {
|
||||
let html = await fixture.readFile('/index.html');
|
||||
let $ = cheerio.load(html);
|
||||
|
||||
const island = $('astro-island');
|
||||
expect(island.length).to.eq(1);
|
||||
expect(island.attr('component-url')).to.match(/^\/_astro\//);
|
||||
expect(island.attr('renderer-url')).to.match(/^\/_astro\//);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with custom configuration', () => {
|
||||
/** @type {import('./test-utils').Fixture} */
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/build-assets/',
|
||||
integrations: [preact()],
|
||||
build: {
|
||||
assets: 'custom-assets',
|
||||
},
|
||||
});
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('Populates /custom-assets directory', async () => {
|
||||
let files = await fixture.readdir('/custom-assets');
|
||||
expect(files.length).to.be.greaterThan(0);
|
||||
});
|
||||
|
||||
it('emits CSS assets to /custom-assets', async () => {
|
||||
let html = await fixture.readFile('/index.html');
|
||||
let $ = cheerio.load(html);
|
||||
|
||||
expect($('link[href$=".css"]').attr('href')).to.match(/^\/custom-assets\//);
|
||||
});
|
||||
|
||||
it('emits JS assets to /custom-assets', async () => {
|
||||
let html = await fixture.readFile('/index.html');
|
||||
let $ = cheerio.load(html);
|
||||
|
||||
const island = $('astro-island');
|
||||
expect(island.length).to.eq(1);
|
||||
expect(island.attr('component-url')).to.match(/^\/custom-assets\//);
|
||||
expect(island.attr('renderer-url')).to.match(/^\/custom-assets\//);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('build assets (server)', () => {
|
||||
describe('with default configuration', () => {
|
||||
/** @type {import('./test-utils').Fixture} */
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/build-assets/',
|
||||
integrations: [preact()],
|
||||
adapter: testAdapter(),
|
||||
});
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('Populates /_astro directory', async () => {
|
||||
let files = await fixture.readdir('/_astro');
|
||||
expect(files.length).to.be.greaterThan(0);
|
||||
});
|
||||
|
||||
it('Defaults to flat /_astro output', async () => {
|
||||
let files = await fixture.readdir('/_astro');
|
||||
for (const file of files) {
|
||||
expect(file.slice(1)).to.not.contain('/');
|
||||
}
|
||||
});
|
||||
|
||||
it('emits CSS assets to /_astro', async () => {
|
||||
let html = await fixture.readFile('/index.html');
|
||||
let $ = cheerio.load(html);
|
||||
|
||||
expect($('link[href$=".css"]').attr('href')).to.match(/^\/_astro\//);
|
||||
});
|
||||
|
||||
it('emits JS assets to /_astro', async () => {
|
||||
let html = await fixture.readFile('/index.html');
|
||||
let $ = cheerio.load(html);
|
||||
|
||||
const island = $('astro-island');
|
||||
expect(island.length).to.eq(1);
|
||||
expect(island.attr('component-url')).to.match(/^\/_astro\//);
|
||||
expect(island.attr('renderer-url')).to.match(/^\/_astro\//);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with custom configuration', () => {
|
||||
/** @type {import('./test-utils').Fixture} */
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/build-assets/',
|
||||
integrations: [preact()],
|
||||
build: {
|
||||
assets: 'custom-assets',
|
||||
},
|
||||
adapter: testAdapter(),
|
||||
});
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('Populates /custom-assets directory', async () => {
|
||||
let files = await fixture.readdir('/custom-assets');
|
||||
expect(files.length).to.be.greaterThan(0);
|
||||
});
|
||||
|
||||
it('emits CSS assets to /custom-assets', async () => {
|
||||
let html = await fixture.readFile('/index.html');
|
||||
let $ = cheerio.load(html);
|
||||
|
||||
expect($('link[href$=".css"]').attr('href')).to.match(/^\/custom-assets\//);
|
||||
});
|
||||
|
||||
it('emits JS assets to /custom-assets', async () => {
|
||||
let html = await fixture.readFile('/index.html');
|
||||
let $ = cheerio.load(html);
|
||||
|
||||
const island = $('astro-island');
|
||||
expect(island.length).to.eq(1);
|
||||
expect(island.attr('component-url')).to.match(/^\/custom-assets\//);
|
||||
expect(island.attr('renderer-url')).to.match(/^\/custom-assets\//);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -24,7 +24,7 @@ describe('CSS', function () {
|
|||
// get bundled CSS (will be hashed, hence DOM query)
|
||||
html = await fixture.readFile('/index.html');
|
||||
$ = cheerio.load(html);
|
||||
const bundledCSSHREF = $('link[rel=stylesheet][href^=/assets/]').attr('href');
|
||||
const bundledCSSHREF = $('link[rel=stylesheet][href^=/_astro/]').attr('href');
|
||||
bundledCSS = (await fixture.readFile(bundledCSSHREF.replace(/^\/?/, '/')))
|
||||
.replace(/\s/g, '')
|
||||
.replace('/n', '');
|
||||
|
|
|
@ -14,7 +14,7 @@ describe('vite.build.cssCodeSplit: false', () => {
|
|||
it('loads styles correctly', async () => {
|
||||
let html = await fixture.readFile('/index.html');
|
||||
let $ = cheerio.load(html);
|
||||
const cssHref = $('link[rel=stylesheet][href^=/assets/]').attr('href');
|
||||
expect(cssHref).to.match(/\/assets\/style\..*?\.css/);
|
||||
const cssHref = $('link[rel=stylesheet][href^=/_astro/]').attr('href');
|
||||
expect(cssHref).to.match(/\/_astro\/style\..*?\.css/);
|
||||
});
|
||||
});
|
||||
|
|
8
packages/astro/test/fixtures/build-assets/package.json
vendored
Normal file
8
packages/astro/test/fixtures/build-assets/package.json
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "@test/build-assets",
|
||||
"dependencies": {
|
||||
"@astrojs/preact": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"preact": "^10.11.0"
|
||||
}
|
||||
}
|
6
packages/astro/test/fixtures/build-assets/src/components/SomeComponent.jsx
vendored
Normal file
6
packages/astro/test/fixtures/build-assets/src/components/SomeComponent.jsx
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
export default function() {
|
||||
return (
|
||||
<div>Testing</div>
|
||||
);
|
||||
}
|
22
packages/astro/test/fixtures/build-assets/src/pages/index.astro
vendored
Normal file
22
packages/astro/test/fixtures/build-assets/src/pages/index.astro
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
import SomeComponent from '../components/SomeComponent';
|
||||
---
|
||||
<html>
|
||||
<head>
|
||||
<title>Testing</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello world!</h1>
|
||||
<SomeComponent client:idle />
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
console.log("Hello world!")
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -18,7 +18,7 @@ describe('PostCSS', function () {
|
|||
// get bundled CSS (will be hashed, hence DOM query)
|
||||
const html = await fixture.readFile('/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
const bundledCSSHREF = $('link[rel=stylesheet][href^=/assets/]').attr('href');
|
||||
const bundledCSSHREF = $('link[rel=stylesheet][href^=/_astro/]').attr('href');
|
||||
bundledCSS = (await fixture.readFile(bundledCSSHREF.replace(/^\/?/, '/')))
|
||||
.replace(/\s/g, '')
|
||||
.replace('/n', '');
|
||||
|
|
|
@ -10,7 +10,7 @@ describe('Sourcemap', async () => {
|
|||
});
|
||||
|
||||
it('Builds sourcemap', async () => {
|
||||
const dir = await fixture.readdir('./assets');
|
||||
const dir = await fixture.readdir('./_astro');
|
||||
const counterMap = dir.find((file) => file.match(/^Counter\.\w+\.js\.map$/));
|
||||
expect(counterMap).to.be.ok;
|
||||
});
|
||||
|
|
|
@ -22,7 +22,7 @@ describe('Tailwind', () => {
|
|||
// get bundled CSS (will be hashed, hence DOM query)
|
||||
const html = await fixture.readFile('/index.html');
|
||||
$ = cheerio.load(html);
|
||||
const bundledCSSHREF = $('link[rel=stylesheet][href^=/assets/]').attr('href');
|
||||
const bundledCSSHREF = $('link[rel=stylesheet][href^=/_astro/]').attr('href');
|
||||
bundledCSS = await fixture.readFile(bundledCSSHREF.replace(/^\/?/, '/'));
|
||||
});
|
||||
|
||||
|
@ -61,7 +61,7 @@ describe('Tailwind', () => {
|
|||
it('handles Markdown pages', async () => {
|
||||
const html = await fixture.readFile('/markdown-page/index.html');
|
||||
const $md = cheerio.load(html);
|
||||
const bundledCSSHREF = $md('link[rel=stylesheet][href^=/assets/]').attr('href');
|
||||
const bundledCSSHREF = $md('link[rel=stylesheet][href^=/_astro/]').attr('href');
|
||||
const mdBundledCSS = await fixture.readFile(bundledCSSHREF.replace(/^\/?/, '/'));
|
||||
expect(mdBundledCSS, 'includes used component classes').to.match(/\.bg-purple-600{/);
|
||||
});
|
||||
|
@ -69,7 +69,7 @@ describe('Tailwind', () => {
|
|||
it('handles MDX pages (with integration)', async () => {
|
||||
const html = await fixture.readFile('/mdx-page/index.html');
|
||||
const $md = cheerio.load(html);
|
||||
const bundledCSSHREF = $md('link[rel=stylesheet][href^=/assets/]').attr('href');
|
||||
const bundledCSSHREF = $md('link[rel=stylesheet][href^=/_astro/]').attr('href');
|
||||
const mdBundledCSS = await fixture.readFile(bundledCSSHREF.replace(/^\/?/, '/'));
|
||||
expect(mdBundledCSS, 'includes used component classes').to.match(/\.bg-purple-600{/);
|
||||
});
|
||||
|
|
|
@ -7,6 +7,7 @@ import { fileURLToPath } from 'url';
|
|||
interface BuildConfig {
|
||||
server: URL;
|
||||
serverEntry: string;
|
||||
assets: string;
|
||||
}
|
||||
|
||||
interface Options {
|
||||
|
@ -86,7 +87,7 @@ export default function createIntegration(args?: Options): AstroIntegration {
|
|||
// Remove chunks, if they exist. Since we have bundled via esbuild these chunks are trash.
|
||||
try {
|
||||
const chunkFileNames =
|
||||
_vite?.build?.rollupOptions?.output?.chunkFileNames ?? 'assets/chunks/chunk.[hash].mjs';
|
||||
_vite?.build?.rollupOptions?.output?.chunkFileNames ?? `chunks/chunk.[hash].mjs`;
|
||||
const chunkPath = npath.dirname(chunkFileNames);
|
||||
const chunksDirUrl = new URL(chunkPath + '/', _buildConfig.server);
|
||||
await fs.promises.rm(chunksDirUrl, { recursive: true, force: true });
|
||||
|
|
|
@ -172,10 +172,10 @@ export async function ssgBuild({
|
|||
let outputFileURL: URL;
|
||||
|
||||
if (isRemoteImage(src)) {
|
||||
outputFileURL = new URL(path.join('./assets', path.basename(filename)), outDir);
|
||||
outputFileURL = new URL(path.join(`./${config.build.assets}`, path.basename(filename)), outDir);
|
||||
outputFile = fileURLToPath(outputFileURL);
|
||||
} else {
|
||||
outputFileURL = new URL(path.join('./assets', filename), outDir);
|
||||
outputFileURL = new URL(path.join(`./${config.build.assets}`, filename), outDir);
|
||||
outputFile = fileURLToPath(outputFileURL);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ const UNSUPPORTED_ADAPTERS = new Set([
|
|||
interface BuildConfig {
|
||||
client: URL;
|
||||
server: URL;
|
||||
assets: string;
|
||||
}
|
||||
|
||||
interface ImageIntegration {
|
||||
|
@ -130,7 +131,7 @@ export default function integration(options: IntegrationOptions = {}): AstroInte
|
|||
// Doing this here makes sure that base is ignored when building
|
||||
// staticImages to /dist, but the rendered HTML will include the
|
||||
// base prefix for `src`.
|
||||
return prependForwardSlash(joinPaths(_config.base, 'assets', filename));
|
||||
return prependForwardSlash(joinPaths(_config.base, _buildConfig.assets, filename));
|
||||
}
|
||||
|
||||
// Helpers for building static images should only be available for SSG
|
||||
|
@ -146,7 +147,7 @@ export default function integration(options: IntegrationOptions = {}): AstroInte
|
|||
// For the Squoosh service, copy all wasm files to dist/chunks.
|
||||
// Because the default loader is dynamically imported (above),
|
||||
// Vite will bundle squoosh to dist/chunks and expect to find the wasm files there
|
||||
await copyWasmFiles(new URL('./assets/chunks', dir));
|
||||
await copyWasmFiles(new URL('./chunks', dir));
|
||||
}
|
||||
|
||||
if (loader && 'transform' in loader && staticImages.size > 0) {
|
||||
|
@ -166,7 +167,7 @@ export default function integration(options: IntegrationOptions = {}): AstroInte
|
|||
},
|
||||
'astro:build:ssr': async () => {
|
||||
if (resolvedOptions.serviceEntryPoint === '@astrojs/image/squoosh') {
|
||||
await copyWasmFiles(new URL('./assets/chunks/', _buildConfig.server));
|
||||
await copyWasmFiles(new URL('./chunks/', _buildConfig.server));
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
@ -23,7 +23,7 @@ describe('SSR image with background', function () {
|
|||
f: 'jpeg',
|
||||
w: '256',
|
||||
h: '256',
|
||||
href: /^\/assets\/file-icon.\w{8}.png/,
|
||||
href: /^\/_astro\/file-icon.\w{8}.png/,
|
||||
bg: 'dimgray',
|
||||
},
|
||||
},
|
||||
|
@ -34,7 +34,7 @@ describe('SSR image with background', function () {
|
|||
f: 'jpeg',
|
||||
w: '256',
|
||||
h: '256',
|
||||
href: /^\/assets\/file-icon.\w{8}.png/,
|
||||
href: /^\/_astro\/file-icon.\w{8}.png/,
|
||||
bg: '#696969',
|
||||
},
|
||||
},
|
||||
|
@ -45,7 +45,7 @@ describe('SSR image with background', function () {
|
|||
f: 'jpeg',
|
||||
w: '256',
|
||||
h: '256',
|
||||
href: /^\/assets\/file-icon.\w{8}.png/,
|
||||
href: /^\/_astro\/file-icon.\w{8}.png/,
|
||||
bg: '#666',
|
||||
},
|
||||
},
|
||||
|
@ -56,7 +56,7 @@ describe('SSR image with background', function () {
|
|||
f: 'jpeg',
|
||||
w: '256',
|
||||
h: '256',
|
||||
href: /^\/assets\/file-icon.\w{8}.png/,
|
||||
href: /^\/_astro\/file-icon.\w{8}.png/,
|
||||
bg: 'rgb(105,105,105)',
|
||||
},
|
||||
},
|
||||
|
@ -67,7 +67,7 @@ describe('SSR image with background', function () {
|
|||
f: 'jpeg',
|
||||
w: '256',
|
||||
h: '256',
|
||||
href: /^\/assets\/file-icon.\w{8}.png/,
|
||||
href: /^\/_astro\/file-icon.\w{8}.png/,
|
||||
bg: 'rgb(105, 105, 105)',
|
||||
},
|
||||
},
|
||||
|
@ -78,7 +78,7 @@ describe('SSR image with background', function () {
|
|||
f: 'jpeg',
|
||||
w: '256',
|
||||
h: '256',
|
||||
href: /^\/assets\/file-icon.\w{8}.png/,
|
||||
href: /^\/_astro\/file-icon.\w{8}.png/,
|
||||
bg: 'rgb(105,105,105,0.5)',
|
||||
},
|
||||
},
|
||||
|
@ -89,7 +89,7 @@ describe('SSR image with background', function () {
|
|||
f: 'jpeg',
|
||||
w: '256',
|
||||
h: '256',
|
||||
href: /^\/assets\/file-icon.\w{8}.png/,
|
||||
href: /^\/_astro\/file-icon.\w{8}.png/,
|
||||
bg: 'rgb(105, 105, 105, 0.5)',
|
||||
},
|
||||
},
|
||||
|
|
|
@ -11,7 +11,7 @@ describe('getImage', function () {
|
|||
});
|
||||
|
||||
it('Remote images works', async () => {
|
||||
const assets = await fixture.readdir('/assets');
|
||||
const assets = await fixture.readdir('/_astro');
|
||||
expect(assets).to.have.a.lengthOf(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -220,43 +220,43 @@ describe('SSG images - build', function () {
|
|||
{
|
||||
title: 'Local images',
|
||||
id: '#social-jpg',
|
||||
regex: /^\/assets\/social.\w{8}_\w{4,10}.jpg/,
|
||||
regex: /^\/_astro\/social.\w{8}_\w{4,10}.jpg/,
|
||||
size: { width: 506, height: 253, type: 'jpg' },
|
||||
},
|
||||
{
|
||||
title: 'Filename with spaces',
|
||||
id: '#spaces',
|
||||
regex: /^\/assets\/introducing astro.\w{8}_\w{4,10}.webp/,
|
||||
regex: /^\/_astro\/introducing astro.\w{8}_\w{4,10}.webp/,
|
||||
size: { width: 768, height: 414, type: 'webp' },
|
||||
},
|
||||
{
|
||||
title: 'Inline imports',
|
||||
id: '#inline',
|
||||
regex: /^\/assets\/social.\w{8}_\w{4,10}.jpg/,
|
||||
regex: /^\/_astro\/social.\w{8}_\w{4,10}.jpg/,
|
||||
size: { width: 506, height: 253, type: 'jpg' },
|
||||
},
|
||||
{
|
||||
title: 'Remote images',
|
||||
id: '#google',
|
||||
regex: /^\/assets\/googlelogo_color_272x92dp_\w{4,10}.webp/,
|
||||
regex: /^\/_astro\/googlelogo_color_272x92dp_\w{4,10}.webp/,
|
||||
size: { width: 544, height: 184, type: 'webp' },
|
||||
},
|
||||
{
|
||||
title: 'Remote without file extension',
|
||||
id: '#ipsum',
|
||||
regex: /^\/assets\/200x300_\w{4,10}/,
|
||||
regex: /^\/_astro\/200x300_\w{4,10}/,
|
||||
size: { width: 200, height: 300, type: 'jpg' },
|
||||
},
|
||||
{
|
||||
title: 'Public images',
|
||||
id: '#hero',
|
||||
regex: /^\/assets\/hero_\w{4,10}.webp/,
|
||||
regex: /^\/_astro\/hero_\w{4,10}.webp/,
|
||||
size: { width: 768, height: 414, type: 'webp' },
|
||||
},
|
||||
{
|
||||
title: 'Remote images',
|
||||
id: '#bg-color',
|
||||
regex: /^\/assets\/googlelogo_color_272x92dp_\w{4,10}.jpeg/,
|
||||
regex: /^\/_astro\/googlelogo_color_272x92dp_\w{4,10}.jpeg/,
|
||||
size: { width: 544, height: 184, type: 'jpg' },
|
||||
},
|
||||
].forEach(({ title, id, regex, size }) => {
|
||||
|
@ -302,43 +302,43 @@ describe('SSG images with subpath - build', function () {
|
|||
{
|
||||
title: 'Local images',
|
||||
id: '#social-jpg',
|
||||
regex: /^\/docs\/assets\/social.\w{8}_\w{4,10}.jpg/,
|
||||
regex: /^\/docs\/_astro\/social.\w{8}_\w{4,10}.jpg/,
|
||||
size: { width: 506, height: 253, type: 'jpg' },
|
||||
},
|
||||
{
|
||||
title: 'Filename with spaces',
|
||||
id: '#spaces',
|
||||
regex: /^\/docs\/assets\/introducing astro.\w{8}_\w{4,10}.webp/,
|
||||
regex: /^\/docs\/_astro\/introducing astro.\w{8}_\w{4,10}.webp/,
|
||||
size: { width: 768, height: 414, type: 'webp' },
|
||||
},
|
||||
{
|
||||
title: 'Inline imports',
|
||||
id: '#inline',
|
||||
regex: /^\/docs\/assets\/social.\w{8}_\w{4,10}.jpg/,
|
||||
regex: /^\/docs\/_astro\/social.\w{8}_\w{4,10}.jpg/,
|
||||
size: { width: 506, height: 253, type: 'jpg' },
|
||||
},
|
||||
{
|
||||
title: 'Remote images',
|
||||
id: '#google',
|
||||
regex: /^\/docs\/assets\/googlelogo_color_272x92dp_\w{4,10}.webp/,
|
||||
regex: /^\/docs\/_astro\/googlelogo_color_272x92dp_\w{4,10}.webp/,
|
||||
size: { width: 544, height: 184, type: 'webp' },
|
||||
},
|
||||
{
|
||||
title: 'Remote without file extension',
|
||||
id: '#ipsum',
|
||||
regex: /^\/docs\/assets\/200x300_\w{4,10}/,
|
||||
regex: /^\/docs\/_astro\/200x300_\w{4,10}/,
|
||||
size: { width: 200, height: 300, type: 'jpg' },
|
||||
},
|
||||
{
|
||||
title: 'Public images',
|
||||
id: '#hero',
|
||||
regex: /^\/docs\/assets\/hero_\w{4,10}.webp/,
|
||||
regex: /^\/docs\/_astro\/hero_\w{4,10}.webp/,
|
||||
size: { width: 768, height: 414, type: 'webp' },
|
||||
},
|
||||
{
|
||||
title: 'Remote images',
|
||||
id: '#bg-color',
|
||||
regex: /^\/docs\/assets\/googlelogo_color_272x92dp_\w{4,10}.jpeg/,
|
||||
regex: /^\/docs\/_astro\/googlelogo_color_272x92dp_\w{4,10}.jpeg/,
|
||||
size: { width: 544, height: 184, type: 'jpg' },
|
||||
},
|
||||
].forEach(({ title, id, regex, size }) => {
|
||||
|
|
|
@ -20,19 +20,19 @@ describe('SSR images - build', async function () {
|
|||
title: 'Local images',
|
||||
id: '#social-jpg',
|
||||
url: '/_image',
|
||||
query: { f: 'jpg', w: '506', h: '253', href: /^\/assets\/social.\w{8}.jpg/ },
|
||||
query: { f: 'jpg', w: '506', h: '253', href: /^\/_astro\/social.\w{8}.jpg/ },
|
||||
},
|
||||
{
|
||||
title: 'Filename with spaces',
|
||||
id: '#spaces',
|
||||
url: '/_image',
|
||||
query: { f: 'webp', w: '768', h: '414', href: /^\/assets\/introducing astro.\w{8}.jpg/ },
|
||||
query: { f: 'webp', w: '768', h: '414', href: /^\/_astro\/introducing astro.\w{8}.jpg/ },
|
||||
},
|
||||
{
|
||||
title: 'Inline imports',
|
||||
id: '#inline',
|
||||
url: '/_image',
|
||||
query: { f: 'jpg', w: '506', h: '253', href: /^\/assets\/social.\w{8}.jpg/ },
|
||||
query: { f: 'jpg', w: '506', h: '253', href: /^\/_astro\/social.\w{8}.jpg/ },
|
||||
},
|
||||
{
|
||||
title: 'Remote images',
|
||||
|
@ -131,7 +131,7 @@ describe('SSR images with subpath - build', function () {
|
|||
title: 'Local images',
|
||||
id: '#social-jpg',
|
||||
url: '/_image',
|
||||
query: { f: 'jpg', w: '506', h: '253', href: /^\/docs\/assets\/social.\w{8}.jpg/ },
|
||||
query: { f: 'jpg', w: '506', h: '253', href: /^\/docs\/_astro\/social.\w{8}.jpg/ },
|
||||
},
|
||||
{
|
||||
title: 'Filename with spaces',
|
||||
|
@ -141,14 +141,14 @@ describe('SSR images with subpath - build', function () {
|
|||
f: 'webp',
|
||||
w: '768',
|
||||
h: '414',
|
||||
href: /^\/docs\/assets\/introducing astro.\w{8}.jpg/,
|
||||
href: /^\/docs\/_astro\/introducing astro.\w{8}.jpg/,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Inline imports',
|
||||
id: '#inline',
|
||||
url: '/_image',
|
||||
query: { f: 'jpg', w: '506', h: '253', href: /^\/docs\/assets\/social.\w{8}.jpg/ },
|
||||
query: { f: 'jpg', w: '506', h: '253', href: /^\/docs\/_astro\/social.\w{8}.jpg/ },
|
||||
},
|
||||
{
|
||||
title: 'Remote images',
|
||||
|
|
|
@ -211,42 +211,42 @@ describe('SSG pictures - build', function () {
|
|||
{
|
||||
title: 'Local images',
|
||||
id: '#social-jpg',
|
||||
regex: /^\/assets\/social.\w{8}_\w{4,10}.jpg/,
|
||||
regex: /^\/_astro\/social.\w{8}_\w{4,10}.jpg/,
|
||||
size: { width: 506, height: 253, type: 'jpg' },
|
||||
alt: 'Social image',
|
||||
},
|
||||
{
|
||||
title: 'Filename with spaces',
|
||||
id: '#spaces',
|
||||
regex: /^\/assets\/introducing astro.\w{8}_\w{4,10}.jpg/,
|
||||
regex: /^\/_astro\/introducing astro.\w{8}_\w{4,10}.jpg/,
|
||||
size: { width: 768, height: 414, type: 'jpg' },
|
||||
alt: 'spaces',
|
||||
},
|
||||
{
|
||||
title: 'Inline images',
|
||||
id: '#inline',
|
||||
regex: /^\/assets\/social.\w{8}_\w{4,10}.jpg/,
|
||||
regex: /^\/_astro\/social.\w{8}_\w{4,10}.jpg/,
|
||||
size: { width: 506, height: 253, type: 'jpg' },
|
||||
alt: 'Inline social image',
|
||||
},
|
||||
{
|
||||
title: 'Remote images',
|
||||
id: '#google',
|
||||
regex: /^\/assets\/googlelogo_color_272x92dp_\w{4,10}.png/,
|
||||
regex: /^\/_astro\/googlelogo_color_272x92dp_\w{4,10}.png/,
|
||||
size: { width: 544, height: 184, type: 'png' },
|
||||
alt: 'Google logo',
|
||||
},
|
||||
{
|
||||
title: 'Remote without file extension',
|
||||
id: '#ipsum',
|
||||
regex: /^\/assets\/200x300_\w{4,10}/,
|
||||
regex: /^\/_astro\/200x300_\w{4,10}/,
|
||||
size: { width: 200, height: 300, type: 'jpg' },
|
||||
alt: 'ipsum',
|
||||
},
|
||||
{
|
||||
title: 'Public images',
|
||||
id: '#hero',
|
||||
regex: /^\/assets\/hero_\w{4,10}.jpg/,
|
||||
regex: /^\/_astro\/hero_\w{4,10}.jpg/,
|
||||
size: { width: 768, height: 414, type: 'jpg' },
|
||||
alt: 'Hero image',
|
||||
},
|
||||
|
@ -318,35 +318,35 @@ describe('SSG pictures with subpath - build', function () {
|
|||
{
|
||||
title: 'Local images',
|
||||
id: '#social-jpg',
|
||||
regex: /^\/docs\/assets\/social.\w{8}_\w{4,10}.jpg/,
|
||||
regex: /^\/docs\/_astro\/social.\w{8}_\w{4,10}.jpg/,
|
||||
size: { width: 506, height: 253, type: 'jpg' },
|
||||
alt: 'Social image',
|
||||
},
|
||||
{
|
||||
title: 'Inline images',
|
||||
id: '#inline',
|
||||
regex: /^\/docs\/assets\/social.\w{8}_\w{4,10}.jpg/,
|
||||
regex: /^\/docs\/_astro\/social.\w{8}_\w{4,10}.jpg/,
|
||||
size: { width: 506, height: 253, type: 'jpg' },
|
||||
alt: 'Inline social image',
|
||||
},
|
||||
{
|
||||
title: 'Remote images',
|
||||
id: '#google',
|
||||
regex: /^\/docs\/assets\/googlelogo_color_272x92dp_\w{4,10}.png/,
|
||||
regex: /^\/docs\/_astro\/googlelogo_color_272x92dp_\w{4,10}.png/,
|
||||
size: { width: 544, height: 184, type: 'png' },
|
||||
alt: 'Google logo',
|
||||
},
|
||||
{
|
||||
title: 'Remote without file extension',
|
||||
id: '#ipsum',
|
||||
regex: /^\/docs\/assets\/200x300_\w{4,10}/,
|
||||
regex: /^\/docs\/_astro\/200x300_\w{4,10}/,
|
||||
size: { width: 200, height: 300, type: 'jpg' },
|
||||
alt: 'ipsum',
|
||||
},
|
||||
{
|
||||
title: 'Public images',
|
||||
id: '#hero',
|
||||
regex: /^\/docs\/assets\/hero_\w{4,10}.jpg/,
|
||||
regex: /^\/docs\/_astro\/hero_\w{4,10}.jpg/,
|
||||
size: { width: 768, height: 414, type: 'jpg' },
|
||||
alt: 'Hero image',
|
||||
},
|
||||
|
|
|
@ -20,21 +20,21 @@ describe('SSR pictures - build', function () {
|
|||
title: 'Local images',
|
||||
id: '#social-jpg',
|
||||
url: '/_image',
|
||||
query: { f: 'jpg', w: '506', h: '253', href: /^\/assets\/social.\w{8}.jpg/ },
|
||||
query: { f: 'jpg', w: '506', h: '253', href: /^\/_astro\/social.\w{8}.jpg/ },
|
||||
alt: 'Social image',
|
||||
},
|
||||
{
|
||||
title: 'Filename with spaces',
|
||||
id: '#spaces',
|
||||
url: '/_image',
|
||||
query: { w: '768', h: '414', f: 'jpg', href: /^\/assets\/introducing astro.\w{8}.jpg/ },
|
||||
query: { w: '768', h: '414', f: 'jpg', href: /^\/_astro\/introducing astro.\w{8}.jpg/ },
|
||||
alt: 'spaces',
|
||||
},
|
||||
{
|
||||
title: 'Inline imports',
|
||||
id: '#inline',
|
||||
url: '/_image',
|
||||
query: { f: 'jpg', w: '506', h: '253', href: /^\/assets\/social.\w{8}.jpg/ },
|
||||
query: { f: 'jpg', w: '506', h: '253', href: /^\/_astro\/social.\w{8}.jpg/ },
|
||||
alt: 'Inline social image',
|
||||
},
|
||||
{
|
||||
|
@ -131,21 +131,21 @@ describe('SSR pictures with subpath - build', function () {
|
|||
title: 'Local images',
|
||||
id: '#social-jpg',
|
||||
url: '/_image',
|
||||
query: { f: 'jpg', w: '506', h: '253', href: /^\/docs\/assets\/social.\w{8}.jpg/ },
|
||||
query: { f: 'jpg', w: '506', h: '253', href: /^\/docs\/_astro\/social.\w{8}.jpg/ },
|
||||
alt: 'Social image',
|
||||
},
|
||||
{
|
||||
title: 'Filename with spaces',
|
||||
id: '#spaces',
|
||||
url: '/_image',
|
||||
query: { w: '768', h: '414', f: 'jpg', href: /^\/docs\/assets\/introducing astro.\w{8}.jpg/ },
|
||||
query: { w: '768', h: '414', f: 'jpg', href: /^\/docs\/_astro\/introducing astro.\w{8}.jpg/ },
|
||||
alt: 'spaces',
|
||||
},
|
||||
{
|
||||
title: 'Inline imports',
|
||||
id: '#inline',
|
||||
url: '/_image',
|
||||
query: { f: 'jpg', w: '506', h: '253', href: /^\/docs\/assets\/social.\w{8}.jpg/ },
|
||||
query: { f: 'jpg', w: '506', h: '253', href: /^\/docs\/_astro\/social.\w{8}.jpg/ },
|
||||
alt: 'Inline social image',
|
||||
},
|
||||
{
|
||||
|
|
|
@ -32,7 +32,7 @@ describe('Image rotation', function () {
|
|||
it('Landscape images', () => {
|
||||
for (let i = 0; i < 9; i++) {
|
||||
const image = $(`#landscape-${i}`);
|
||||
const regex = new RegExp(`\^/assets\/Landscape_${i}.\\w{8}_\\w{4,10}.jpg`);
|
||||
const regex = new RegExp(`\^/_astro\/Landscape_${i}.\\w{8}_\\w{4,10}.jpg`);
|
||||
|
||||
expect(image.attr('src')).to.match(regex);
|
||||
expect(image.attr('width')).to.equal('1800');
|
||||
|
@ -49,7 +49,7 @@ describe('Image rotation', function () {
|
|||
it('Portait images', () => {
|
||||
for (let i = 0; i < 9; i++) {
|
||||
const image = $(`#portrait-${i}`);
|
||||
const regex = new RegExp(`\^/assets\/Portrait_${i}.\\w{8}_\\w{4,10}.jpg`);
|
||||
const regex = new RegExp(`\^/_astro\/Portrait_${i}.\\w{8}_\\w{4,10}.jpg`);
|
||||
|
||||
expect(image.attr('src')).to.match(regex);
|
||||
expect(image.attr('width')).to.equal('1200');
|
||||
|
|
|
@ -28,31 +28,31 @@ describe('Images in MDX - build', function () {
|
|||
{
|
||||
title: 'Local images',
|
||||
id: '#social-jpg',
|
||||
regex: /^\/assets\/social.\w{8}_\w{4,10}.jpg/,
|
||||
regex: /^\/_astro\/social.\w{8}_\w{4,10}.jpg/,
|
||||
size: { width: 506, height: 253, type: 'jpg' },
|
||||
},
|
||||
{
|
||||
title: 'Inline imports',
|
||||
id: '#inline',
|
||||
regex: /^\/assets\/social.\w{8}_\w{4,10}.jpg/,
|
||||
regex: /^\/_astro\/social.\w{8}_\w{4,10}.jpg/,
|
||||
size: { width: 506, height: 253, type: 'jpg' },
|
||||
},
|
||||
{
|
||||
title: 'Remote images',
|
||||
id: '#google',
|
||||
regex: /^\/assets\/googlelogo_color_272x92dp_\w{4,10}.webp/,
|
||||
regex: /^\/_astro\/googlelogo_color_272x92dp_\w{4,10}.webp/,
|
||||
size: { width: 544, height: 184, type: 'webp' },
|
||||
},
|
||||
{
|
||||
title: 'Public images',
|
||||
id: '#hero',
|
||||
regex: /^\/assets\/hero_\w{4,10}.webp/,
|
||||
regex: /^\/_astro\/hero_\w{4,10}.webp/,
|
||||
size: { width: 768, height: 414, type: 'webp' },
|
||||
},
|
||||
{
|
||||
title: 'Background color',
|
||||
id: '#bg-color',
|
||||
regex: /^\/assets\/googlelogo_color_272x92dp_\w{4,10}.jpeg/,
|
||||
regex: /^\/_astro\/googlelogo_color_272x92dp_\w{4,10}.jpeg/,
|
||||
size: { width: 544, height: 184, type: 'jpg' },
|
||||
},
|
||||
].forEach(({ title, id, regex, size }) => {
|
||||
|
|
|
@ -10,6 +10,7 @@ interface BuildConfig {
|
|||
server: URL;
|
||||
client: URL;
|
||||
serverEntry: string;
|
||||
assets: string;
|
||||
}
|
||||
|
||||
const SHIM = `globalThis.process = {
|
||||
|
@ -100,7 +101,7 @@ async function bundleServerEntry({ serverEntry, server }: BuildConfig, vite: any
|
|||
// Remove chunks, if they exist. Since we have bundled via esbuild these chunks are trash.
|
||||
try {
|
||||
const chunkFileNames =
|
||||
vite?.build?.rollupOptions?.output?.chunkFileNames ?? 'assets/chunks/chunk.[hash].mjs';
|
||||
vite?.build?.rollupOptions?.output?.chunkFileNames ?? `chunks/chunk.[hash].mjs`;
|
||||
const chunkPath = npath.dirname(chunkFileNames);
|
||||
const chunksDirUrl = new URL(chunkPath + '/', server);
|
||||
await fs.promises.rm(chunksDirUrl, { recursive: true, force: true });
|
||||
|
|
|
@ -1582,6 +1582,16 @@ importers:
|
|||
astro: link:../../..
|
||||
preact: 10.11.3
|
||||
|
||||
packages/astro/test/fixtures/build-assets:
|
||||
specifiers:
|
||||
'@astrojs/preact': workspace:*
|
||||
astro: workspace:*
|
||||
preact: ^10.11.0
|
||||
dependencies:
|
||||
'@astrojs/preact': link:../../../../integrations/preact
|
||||
astro: link:../../..
|
||||
preact: 10.11.3
|
||||
|
||||
packages/astro/test/fixtures/client-address:
|
||||
specifiers:
|
||||
astro: workspace:*
|
||||
|
|
Loading…
Reference in a new issue