[ci] format
This commit is contained in:
parent
3acb9ec264
commit
b282cdb21f
6 changed files with 71 additions and 65 deletions
|
@ -15,7 +15,7 @@ export async function getStylesForURL(
|
|||
const importedCssUrls = new Set<string>();
|
||||
const importedStylesMap = new Map<string, string>();
|
||||
|
||||
for await(const importedModule of crawlGraph(viteServer, viteID(filePath), true)) {
|
||||
for await (const importedModule of crawlGraph(viteServer, viteID(filePath), true)) {
|
||||
const ext = path.extname(importedModule.url).toLowerCase();
|
||||
if (STYLE_EXTENSIONS.has(ext)) {
|
||||
if (
|
||||
|
|
|
@ -16,8 +16,8 @@ import { render as coreRender } from '../core.js';
|
|||
import { RouteCache } from '../route-cache.js';
|
||||
import { collectMdMetadata } from '../util.js';
|
||||
import { getStylesForURL } from './css.js';
|
||||
import { getScriptsForURL } from './scripts.js';
|
||||
import { resolveClientDevPath } from './resolve.js';
|
||||
import { getScriptsForURL } from './scripts.js';
|
||||
|
||||
export interface SSROptions {
|
||||
/** an instance of the AstroConfig */
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
import type { AstroConfig, SSRElement } from '../../../@types/astro';
|
||||
import type { ModuleInfo } from 'rollup';
|
||||
import type { PluginMetadata as AstroPluginMetadata } from '../../../vite-plugin-astro/types';
|
||||
import vite from 'vite';
|
||||
import slash from 'slash';
|
||||
import { fileURLToPath } from 'url';
|
||||
import vite from 'vite';
|
||||
import type { AstroConfig, SSRElement } from '../../../@types/astro';
|
||||
import type { PluginMetadata as AstroPluginMetadata } from '../../../vite-plugin-astro/types';
|
||||
import { viteID } from '../../util.js';
|
||||
import { createModuleScriptElementWithSrc } from '../ssr-element.js';
|
||||
import { crawlGraph } from './vite.js';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
export async function getScriptsForURL(
|
||||
filePath: URL,
|
||||
astroConfig: AstroConfig,
|
||||
viteServer: vite.ViteDevServer,
|
||||
viteServer: vite.ViteDevServer
|
||||
): Promise<Set<SSRElement>> {
|
||||
const elements = new Set<SSRElement>();
|
||||
const rootID = viteID(filePath);
|
||||
let rootProjectFolder = slash(fileURLToPath(astroConfig.root));
|
||||
const modInfo = viteServer.pluginContainer.getModuleInfo(rootID);
|
||||
addHoistedScripts(elements, modInfo, rootProjectFolder);
|
||||
for await(const moduleNode of crawlGraph(viteServer, rootID, true)) {
|
||||
for await (const moduleNode of crawlGraph(viteServer, rootID, true)) {
|
||||
const id = moduleNode.id;
|
||||
if(id) {
|
||||
if (id) {
|
||||
const info = viteServer.pluginContainer.getModuleInfo(id);
|
||||
addHoistedScripts(elements, info, rootProjectFolder);
|
||||
}
|
||||
|
@ -29,14 +29,18 @@ export async function getScriptsForURL(
|
|||
return elements;
|
||||
}
|
||||
|
||||
function addHoistedScripts(set: Set<SSRElement>, info: ModuleInfo | null, rootProjectFolder: string) {
|
||||
if(!info?.meta?.astro) {
|
||||
function addHoistedScripts(
|
||||
set: Set<SSRElement>,
|
||||
info: ModuleInfo | null,
|
||||
rootProjectFolder: string
|
||||
) {
|
||||
if (!info?.meta?.astro) {
|
||||
return;
|
||||
}
|
||||
|
||||
let id = info.id;
|
||||
const astro = info?.meta?.astro as AstroPluginMetadata['astro'];
|
||||
for(let i = 0; i < astro.scripts.length; i++) {
|
||||
for (let i = 0; i < astro.scripts.length; i++) {
|
||||
const scriptId = `${id}?astro&type=script&index=${i}&lang.ts`;
|
||||
const element = createModuleScriptElementWithSrc(scriptId);
|
||||
set.add(element);
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
import vite from 'vite';
|
||||
import npath from 'path';
|
||||
import vite from 'vite';
|
||||
import { unwrapId } from '../../util.js';
|
||||
|
||||
/**
|
||||
* List of file extensions signalling we can (and should) SSR ahead-of-time
|
||||
* See usage below
|
||||
*/
|
||||
const fileExtensionsToSSR = new Set(['.astro', '.md']);
|
||||
const fileExtensionsToSSR = new Set(['.astro', '.md']);
|
||||
|
||||
/** recursively crawl the module graph to get all style files imported by parent id */
|
||||
export async function * crawlGraph(
|
||||
export async function* crawlGraph(
|
||||
viteServer: vite.ViteDevServer,
|
||||
_id: string,
|
||||
isFile: boolean,
|
||||
scanned = new Set<string>()
|
||||
) : AsyncGenerator<vite.ModuleNode, void, unknown> {
|
||||
): AsyncGenerator<vite.ModuleNode, void, unknown> {
|
||||
const id = unwrapId(_id);
|
||||
const importedModules = new Set<vite.ModuleNode>();
|
||||
const moduleEntriesForId = isFile
|
||||
? // If isFile = true, then you are at the root of your module import tree.
|
||||
// The `id` arg is a filepath, so use `getModulesByFile()` to collect all
|
||||
// nodes for that file. This is needed for advanced imports like Tailwind.
|
||||
viteServer.moduleGraph.getModulesByFile(id) ?? new Set()
|
||||
// The `id` arg is a filepath, so use `getModulesByFile()` to collect all
|
||||
// nodes for that file. This is needed for advanced imports like Tailwind.
|
||||
viteServer.moduleGraph.getModulesByFile(id) ?? new Set()
|
||||
: // Otherwise, you are following an import in the module import tree.
|
||||
// You are safe to use getModuleById() here because Vite has already
|
||||
// resolved the correct `id` for you, by creating the import you followed here.
|
||||
new Set([viteServer.moduleGraph.getModuleById(id)]);
|
||||
// You are safe to use getModuleById() here because Vite has already
|
||||
// resolved the correct `id` for you, by creating the import you followed here.
|
||||
new Set([viteServer.moduleGraph.getModuleById(id)]);
|
||||
|
||||
// Collect all imported modules for the module(s).
|
||||
for (const entry of moduleEntriesForId) {
|
||||
|
@ -45,7 +45,7 @@ export async function * crawlGraph(
|
|||
const { pathname } = new URL(`file://${importedModule.id}`);
|
||||
if (fileExtensionsToSSR.has(npath.extname(pathname))) {
|
||||
const mod = viteServer.moduleGraph.getModuleById(importedModule.id);
|
||||
if(!mod?.ssrModule) {
|
||||
if (!mod?.ssrModule) {
|
||||
await viteServer.ssrLoadModule(importedModule.id);
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +63,6 @@ export async function * crawlGraph(
|
|||
}
|
||||
|
||||
yield importedModule;
|
||||
yield * crawlGraph(viteServer, importedModule.id, false, scanned);
|
||||
yield* crawlGraph(viteServer, importedModule.id, false, scanned);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,45 +16,45 @@ describe('Environment Variables', () => {
|
|||
before(async () => {
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
|
||||
it('builds without throwing', async () => {
|
||||
expect(true).to.equal(true);
|
||||
});
|
||||
|
||||
|
||||
it('does render public env and private env', async () => {
|
||||
let indexHtml = await fixture.readFile('/index.html');
|
||||
|
||||
|
||||
expect(indexHtml).to.include('CLUB_33');
|
||||
expect(indexHtml).to.include('BLUE_BAYOU');
|
||||
});
|
||||
|
||||
|
||||
it('does render destructured public env and private env', async () => {
|
||||
let indexHtml = await fixture.readFile('/destructured/index.html');
|
||||
|
||||
|
||||
expect(indexHtml).to.include('CLUB_33');
|
||||
expect(indexHtml).to.include('BLUE_BAYOU');
|
||||
});
|
||||
|
||||
|
||||
it('does render builtin SITE env', async () => {
|
||||
let indexHtml = await fixture.readFile('/index.html');
|
||||
expect(indexHtml).to.include('http://example.com');
|
||||
});
|
||||
|
||||
|
||||
it('does render destructured builtin SITE env', async () => {
|
||||
let indexHtml = await fixture.readFile('/destructured/index.html');
|
||||
|
||||
|
||||
expect(indexHtml).to.include('http://example.com');
|
||||
});
|
||||
|
||||
|
||||
it('does render builtin BASE_URL env', async () => {
|
||||
let indexHtml = await fixture.readFile('/index.html');
|
||||
expect(indexHtml).to.include('/blog');
|
||||
});
|
||||
|
||||
|
||||
it('includes public env in client-side JS', async () => {
|
||||
let dirs = await fixture.readdir('/');
|
||||
let found = false;
|
||||
|
||||
|
||||
// Look in all of the .js files to see if the public env is inlined.
|
||||
// Testing this way prevents hardcoding expected js files.
|
||||
// If we find it in any of them that's good enough to know its working.
|
||||
|
@ -68,14 +68,14 @@ describe('Environment Variables', () => {
|
|||
}
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
expect(found).to.equal(true, 'found the public env variable in the JS build');
|
||||
});
|
||||
|
||||
|
||||
it('does not include private env in client-side JS', async () => {
|
||||
let dirs = await fixture.readdir('/');
|
||||
let found = false;
|
||||
|
||||
|
||||
// Look in all of the .js files to see if the public env is inlined.
|
||||
// Testing this way prevents hardcoding expected js files.
|
||||
// If we find it in any of them that's good enough to know its NOT working.
|
||||
|
@ -89,7 +89,7 @@ describe('Environment Variables', () => {
|
|||
}
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
expect(found).to.equal(false, 'found the private env variable in the JS build');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -19,99 +19,99 @@ describe('Scripts (hoisted and not)', () => {
|
|||
before(async () => {
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
|
||||
it('Moves external scripts up', async () => {
|
||||
const html = await fixture.readFile('/external/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
|
||||
expect($('head script[type="module"]:not([src="/regular_script.js"])')).to.have.lengthOf(1);
|
||||
expect($('body script')).to.have.lengthOf(0);
|
||||
});
|
||||
|
||||
|
||||
it('Moves inline scripts up', async () => {
|
||||
const html = await fixture.readFile('/inline/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
|
||||
expect($('head script[type="module"]')).to.have.lengthOf(1);
|
||||
expect($('body script')).to.have.lengthOf(0);
|
||||
});
|
||||
|
||||
|
||||
it('Inline page builds the scripts to a single bundle', async () => {
|
||||
// Inline page
|
||||
let inline = await fixture.readFile('/inline/index.html');
|
||||
let $ = cheerio.load(inline);
|
||||
let $el = $('script');
|
||||
|
||||
|
||||
// test 1: Just one entry module
|
||||
expect($el).to.have.lengthOf(1);
|
||||
|
||||
|
||||
// test 2: attr removed
|
||||
expect($el.attr('data-astro')).to.equal(undefined);
|
||||
|
||||
|
||||
expect($el.attr('src')).to.equal(undefined);
|
||||
const inlineEntryJS = $el.text();
|
||||
|
||||
|
||||
// test 3: the JS exists
|
||||
expect(inlineEntryJS).to.be.ok;
|
||||
|
||||
|
||||
// test 4: Inline imported JS is included
|
||||
expect(inlineEntryJS).to.contain(
|
||||
'I AM IMPORTED INLINE',
|
||||
'The inline imported JS is included in the bundle'
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
it("Inline scripts that are shared by multiple pages create chunks, and aren't inlined into the HTML", async () => {
|
||||
let html = await fixture.readFile('/inline-shared-one/index.html');
|
||||
let $ = cheerio.load(html);
|
||||
|
||||
|
||||
expect($('script')).to.have.lengthOf(1);
|
||||
expect($('script').attr('src')).to.not.equal(undefined);
|
||||
});
|
||||
|
||||
|
||||
it('External page builds the hoisted scripts to a single bundle', async () => {
|
||||
let external = await fixture.readFile('/external/index.html');
|
||||
let $ = cheerio.load(external);
|
||||
|
||||
|
||||
// test 1: there are two scripts
|
||||
expect($('script')).to.have.lengthOf(2);
|
||||
|
||||
|
||||
let el = $('script').get(1);
|
||||
expect($(el).attr('src')).to.equal(undefined, 'This should have been inlined');
|
||||
let externalEntryJS = $(el).text();
|
||||
|
||||
|
||||
// test 2: the JS exists
|
||||
expect(externalEntryJS).to.be.ok;
|
||||
});
|
||||
|
||||
|
||||
it('External page using non-hoist scripts that are modules are built standalone', async () => {
|
||||
let external = await fixture.readFile('/external-no-hoist/index.html');
|
||||
let $ = cheerio.load(external);
|
||||
|
||||
|
||||
// test 1: there is 1 scripts
|
||||
expect($('script')).to.have.lengthOf(1);
|
||||
|
||||
|
||||
// test 2: inside assets
|
||||
let entryURL = $('script').attr('src');
|
||||
expect(entryURL.includes('assets/')).to.equal(true);
|
||||
});
|
||||
|
||||
|
||||
it('External page using non-hoist scripts that are not modules are built standalone', async () => {
|
||||
let external = await fixture.readFile('/external-no-hoist-classic/index.html');
|
||||
let $ = cheerio.load(external);
|
||||
|
||||
|
||||
// test 1: there is 1 scripts
|
||||
expect($('script')).to.have.lengthOf(1);
|
||||
|
||||
|
||||
// test 2: inside assets
|
||||
let entryURL = $('script').attr('src');
|
||||
expect(entryURL.includes('assets/')).to.equal(true);
|
||||
});
|
||||
|
||||
|
||||
it('Scripts added via Astro.glob are hoisted', async () => {
|
||||
let glob = await fixture.readFile('/glob/index.html');
|
||||
let $ = cheerio.load(glob);
|
||||
|
||||
|
||||
expect($('script[type="module"]').length).to.be.greaterThan(0);
|
||||
});
|
||||
});
|
||||
|
@ -135,10 +135,12 @@ describe('Scripts (hoisted and not)', () => {
|
|||
let found = 0;
|
||||
let moduleScripts = $('[type=module]');
|
||||
moduleScripts.each((i, el) => {
|
||||
if($(el).attr('src').includes('Glob/GlobComponent.astro?astro&type=script&index=0&lang.ts')) {
|
||||
if (
|
||||
$(el).attr('src').includes('Glob/GlobComponent.astro?astro&type=script&index=0&lang.ts')
|
||||
) {
|
||||
found++;
|
||||
}
|
||||
})
|
||||
});
|
||||
expect(found).to.equal(1);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue