[ci] yarn format

This commit is contained in:
matthewp 2021-08-27 14:13:41 +00:00 committed by GitHub Actions
parent 788c769d78
commit 5cc7947a58
9 changed files with 65 additions and 69 deletions

View file

@ -281,7 +281,7 @@ By default Astro does not make any assumptions on how you want scripts to be ser
However if you'd like all of your scripts to be hoisted out of components and moved to the top of the page, and then later bundled together in production, you can achieve this with hoisted scripts. However if you'd like all of your scripts to be hoisted out of components and moved to the top of the page, and then later bundled together in production, you can achieve this with hoisted scripts.
A __hoisted script__ looks like this: A **hoisted script** looks like this:
```astro ```astro
<script hoist> <script hoist>

View file

@ -140,7 +140,7 @@ ${stack}
const pageDeps = findDeps(buildState[id].contents as string, { const pageDeps = findDeps(buildState[id].contents as string, {
astroConfig, astroConfig,
srcPath: buildState[id].srcPath, srcPath: buildState[id].srcPath,
id id,
}); });
depTree[id] = pageDeps; depTree[id] = pageDeps;
@ -178,7 +178,7 @@ ${stack}
bundleCSS({ buildState, astroConfig, logging, depTree }).then(() => { bundleCSS({ buildState, astroConfig, logging, depTree }).then(() => {
debug(logging, 'build', `bundled CSS [${stopTimer(timer.prebundleCSS)}]`); debug(logging, 'build', `bundled CSS [${stopTimer(timer.prebundleCSS)}]`);
}), }),
bundleHoistedJS({ buildState, astroConfig, logging, depTree, runtime: astroRuntime, dist: astroConfig.dist }) bundleHoistedJS({ buildState, astroConfig, logging, depTree, runtime: astroRuntime, dist: astroConfig.dist }),
// TODO: optimize images? // TODO: optimize images?
]); ]);
// TODO: minify HTML? // TODO: minify HTML?
@ -272,7 +272,7 @@ ${stack}
} }
/** Given an HTML string, collect <link> and <img> tags */ /** Given an HTML string, collect <link> and <img> tags */
export function findDeps(html: string, { astroConfig, srcPath }: { astroConfig: AstroConfig; srcPath: URL, id: string }): PageDependencies { export function findDeps(html: string, { astroConfig, srcPath }: { astroConfig: AstroConfig; srcPath: URL; id: string }): PageDependencies {
const pageDeps: PageDependencies = { const pageDeps: PageDependencies = {
js: new Set<string>(), js: new Set<string>(),
css: new Set<string>(), css: new Set<string>(),
@ -285,15 +285,15 @@ export function findDeps(html: string, { astroConfig, srcPath }: { astroConfig:
$('script').each((_i, el) => { $('script').each((_i, el) => {
const src = $(el).attr('src'); const src = $(el).attr('src');
const hoist = $(el).attr('data-astro') === 'hoist'; const hoist = $(el).attr('data-astro') === 'hoist';
if(hoist) { if (hoist) {
if(src) { if (src) {
pageDeps.hoistedJS.set(src, { pageDeps.hoistedJS.set(src, {
src src,
}); });
} else { } else {
let content = $(el).html() || ''; let content = $(el).html() || '';
pageDeps.hoistedJS.set(`astro-virtual:${hash.unique(content)}`, { pageDeps.hoistedJS.set(`astro-virtual:${hash.unique(content)}`, {
content content,
}); });
} }
} else if (src) { } else if (src) {

View file

@ -6,7 +6,7 @@ import type { LogOptions } from '../../logger.js';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import { rollup } from 'rollup'; import { rollup } from 'rollup';
import { terser } from 'rollup-plugin-terser'; import { terser } from 'rollup-plugin-terser';
import { createBundleStats, addBundleStats, BundleStatsMap } from '../stats.js' import { createBundleStats, addBundleStats, BundleStatsMap } from '../stats.js';
import { IS_ASTRO_FILE_URL } from '../util.js'; import { IS_ASTRO_FILE_URL } from '../util.js';
import cheerio from 'cheerio'; import cheerio from 'cheerio';
import path from 'path'; import path from 'path';
@ -35,7 +35,7 @@ export async function bundleHoistedJS({
logging, logging,
depTree, depTree,
dist, dist,
runtime runtime,
}: { }: {
astroConfig: AstroConfig; astroConfig: AstroConfig;
buildState: BuildOutput; buildState: BuildOutput;
@ -46,7 +46,7 @@ export async function bundleHoistedJS({
}) { }) {
const sortedPages = Object.keys(depTree); // these were scanned in parallel; sort to create somewhat deterministic order const sortedPages = Object.keys(depTree); // these were scanned in parallel; sort to create somewhat deterministic order
sortedPages.sort((a, b) => a.localeCompare(b, 'en', { numeric: true })); sortedPages.sort((a, b) => a.localeCompare(b, 'en', { numeric: true }));
/** /**
* 1. Go over sorted pages and create a virtual module for all of its dependencies * 1. Go over sorted pages and create a virtual module for all of its dependencies
*/ */
@ -54,44 +54,45 @@ export async function bundleHoistedJS({
const virtualScripts = new Map<string, ScriptInfo>(); const virtualScripts = new Map<string, ScriptInfo>();
const pageToEntryMap = new Map<string, string>(); const pageToEntryMap = new Map<string, string>();
for(let pageUrl of sortedPages) { for (let pageUrl of sortedPages) {
const hoistedJS = depTree[pageUrl].hoistedJS; const hoistedJS = depTree[pageUrl].hoistedJS;
if(hoistedJS.size) { if (hoistedJS.size) {
for(let [url, scriptInfo] of hoistedJS) { for (let [url, scriptInfo] of hoistedJS) {
if(virtualScripts.has(url) || !url.startsWith('astro-virtual:')) continue; if (virtualScripts.has(url) || !url.startsWith('astro-virtual:')) continue;
virtualScripts.set(url, scriptInfo); virtualScripts.set(url, scriptInfo);
} }
const entryURL = pageUrlToVirtualJSEntry(pageUrl); const entryURL = pageUrlToVirtualJSEntry(pageUrl);
const entryJS = Array.from(hoistedJS.keys()).map(url => `import '${url}';`).join('\n'); const entryJS = Array.from(hoistedJS.keys())
.map((url) => `import '${url}';`)
.join('\n');
virtualScripts.set(entryURL, { virtualScripts.set(entryURL, {
content: entryJS content: entryJS,
}); });
entryImports.push(entryURL); entryImports.push(entryURL);
pageToEntryMap.set(pageUrl, entryURL); pageToEntryMap.set(pageUrl, entryURL);
} }
} }
if(!entryImports.length) { if (!entryImports.length) {
// There are no hoisted scripts, bail // There are no hoisted scripts, bail
return; return;
} }
/** /**
* 2. Run the bundle to bundle each pages JS into a single bundle (with shared content) * 2. Run the bundle to bundle each pages JS into a single bundle (with shared content)
*/ */
const inputOptions: InputOptions = { const inputOptions: InputOptions = {
input: entryImports, input: entryImports,
plugins: [ plugins: [
{ {
name: 'astro:build', name: 'astro:build',
resolveId(source: string, imported?: string) { resolveId(source: string, imported?: string) {
if(virtualScripts.has(source)) { if (virtualScripts.has(source)) {
return source; return source;
} }
if (source.startsWith('/')) { if (source.startsWith('/')) {
return source; return source;
} }
if (imported) { if (imported) {
const outUrl = new URL(source, 'http://example.com' + imported); const outUrl = new URL(source, 'http://example.com' + imported);
@ -101,12 +102,11 @@ export async function bundleHoistedJS({
return null; return null;
}, },
async load(id: string) { async load(id: string) {
if(virtualScripts.has(id)) { if (virtualScripts.has(id)) {
let info = virtualScripts.get(id) as InlineScriptInfo; let info = virtualScripts.get(id) as InlineScriptInfo;
return info.content; return info.content;
} }
const result = await runtime.load(id); const result = await runtime.load(id);
if (result.statusCode !== 200) { if (result.statusCode !== 200) {
@ -128,8 +128,7 @@ export async function bundleHoistedJS({
entryFileNames(chunk) { entryFileNames(chunk) {
const { facadeModuleId } = chunk; const { facadeModuleId } = chunk;
if (!facadeModuleId) throw new Error(`facadeModuleId missing: ${chunk.name}`); if (!facadeModuleId) throw new Error(`facadeModuleId missing: ${chunk.name}`);
return facadeModuleId.substr('astro-virtual:/'.length, facadeModuleId.length - 'astro-virtual:/'.length - 3 /* .js */) return facadeModuleId.substr('astro-virtual:/'.length, facadeModuleId.length - 'astro-virtual:/'.length - 3 /* .js */) + '-[hash].js';
+ '-[hash].js';
}, },
plugins: [ plugins: [
// We are using terser for the demo, but might switch to something else long term // We are using terser for the demo, but might switch to something else long term
@ -146,7 +145,7 @@ export async function bundleHoistedJS({
const entryToChunkFileName = new Map<string, string>(); const entryToChunkFileName = new Map<string, string>();
output.forEach((chunk) => { output.forEach((chunk) => {
const { fileName, facadeModuleId, isEntry } = chunk as OutputChunk; const { fileName, facadeModuleId, isEntry } = chunk as OutputChunk;
if(!facadeModuleId || !isEntry) return; if (!facadeModuleId || !isEntry) return;
entryToChunkFileName.set(facadeModuleId, fileName); entryToChunkFileName.set(facadeModuleId, fileName);
}); });
@ -161,7 +160,7 @@ export async function bundleHoistedJS({
const $ = cheerio.load(buildState[id].contents); const $ = cheerio.load(buildState[id].contents);
$('script[data-astro="hoist"]').each((i, el) => { $('script[data-astro="hoist"]').each((i, el) => {
hasHoisted = true; hasHoisted = true;
if(i === 0) { if (i === 0) {
let chunkName = entryToChunkFileName.get(entryVirtualURL); let chunkName = entryToChunkFileName.get(entryVirtualURL);
if (!chunkName) return; if (!chunkName) return;
let chunkPathname = '/' + chunkName; let chunkPathname = '/' + chunkName;
@ -174,7 +173,7 @@ export async function bundleHoistedJS({
} }
}); });
if(hasHoisted) { if (hasHoisted) {
(buildState[id] as any).contents = $.html(); // save updated HTML in global buildState (buildState[id] as any).contents = $.html(); // save updated HTML in global buildState
} }
}); });
@ -200,7 +199,6 @@ export async function bundleJS(imports: Set<string>, { astroRuntime, dist }: Bun
if (source.startsWith('/')) { if (source.startsWith('/')) {
return source; return source;
} }
if (imported) { if (imported) {
const outUrl = new URL(source, 'http://example.com' + imported); const outUrl = new URL(source, 'http://example.com' + imported);

View file

@ -673,14 +673,14 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
buffers[curr] += `h(__astro_slot_content, { name: ${attributes.slot} },`; buffers[curr] += `h(__astro_slot_content, { name: ${attributes.slot} },`;
paren++; paren++;
} }
if(attributes.hoist) { if (attributes.hoist) {
if(attributes.src) { if (attributes.src) {
state.hoistedScripts.push({ state.hoistedScripts.push({
src: attributes.src.substr(1, attributes.src.length - 2) src: attributes.src.substr(1, attributes.src.length - 2),
}); });
} else if(node.children && node.children.length === 1 && node.children[0].type === 'Text') { } else if (node.children && node.children.length === 1 && node.children[0].type === 'Text') {
state.hoistedScripts.push({ state.hoistedScripts.push({
content: node.children[0].data content: node.children[0].data,
}); });
} }
this.skip(); this.skip();

View file

@ -155,7 +155,7 @@ ${result.getStaticPaths || ''}
import { h, Fragment } from 'astro/dist/internal/h.js'; import { h, Fragment } from 'astro/dist/internal/h.js';
import { __astro_hoisted_scripts } from 'astro/dist/internal/__astro_hoisted_scripts.js'; import { __astro_hoisted_scripts } from 'astro/dist/internal/__astro_hoisted_scripts.js';
const __astroScripts = __astro_hoisted_scripts([${result.components.map(n => `typeof ${n} !== 'undefined' && ${n}`)}], ${JSON.stringify(result.hoistedScripts)}); const __astroScripts = __astro_hoisted_scripts([${result.components.map((n) => `typeof ${n} !== 'undefined' && ${n}`)}], ${JSON.stringify(result.hoistedScripts)});
const __astroInternal = Symbol('astro.internal'); const __astroInternal = Symbol('astro.internal');
const __astroContext = Symbol.for('astro.context'); const __astroContext = Symbol.for('astro.context');
async function __render(props, ...children) { async function __render(props, ...children) {

View file

@ -138,9 +138,9 @@ export default function (opts: TransformOptions): Transformer {
{ {
type: 'Text', type: 'Text',
raw: 'module', raw: 'module',
data: 'module' data: 'module',
} },
] ],
}, },
{ {
type: 'Attribute', type: 'Attribute',
@ -157,8 +157,8 @@ export default function (opts: TransformOptions): Transformer {
codeChunks: ['script.src'], codeChunks: ['script.src'],
children: [], children: [],
}, },
} },
] ],
}, },
{ {
type: 'Attribute', type: 'Attribute',
@ -167,10 +167,10 @@ export default function (opts: TransformOptions): Transformer {
{ {
type: 'Text', type: 'Text',
raw: 'hoist', raw: 'hoist',
data: 'hoist' data: 'hoist',
} },
] ],
} },
], ],
start: 0, start: 0,
end: 0, end: 0,
@ -187,9 +187,9 @@ export default function (opts: TransformOptions): Transformer {
{ {
type: 'Text', type: 'Text',
raw: 'module', raw: 'module',
data: 'module' data: 'module',
} },
] ],
}, },
{ {
type: 'Attribute', type: 'Attribute',
@ -198,10 +198,10 @@ export default function (opts: TransformOptions): Transformer {
{ {
type: 'Text', type: 'Text',
raw: 'hoist', raw: 'hoist',
data: 'hoist' data: 'hoist',
} },
] ],
} },
], ],
start: 0, start: 0,
end: 0, end: 0,
@ -217,11 +217,11 @@ export default function (opts: TransformOptions): Transformer {
codeChunks: ['script.content'], codeChunks: ['script.content'],
children: [], children: [],
}, },
} },
], ],
}, },
] ],
} },
], ],
}, },
], ],

View file

@ -3,7 +3,7 @@ import type { ScriptInfo } from '../@types/astro';
const sym = Symbol.for('astro.hoistedScripts'); const sym = Symbol.for('astro.hoistedScripts');
interface ComponentThatMaybeHasHoistedScripts { interface ComponentThatMaybeHasHoistedScripts {
[sym]: ScriptInfo[] [sym]: ScriptInfo[];
} }
/** /**
@ -14,24 +14,22 @@ interface ComponentThatMaybeHasHoistedScripts {
function hoistedScripts(Components: ComponentThatMaybeHasHoistedScripts[], scripts: ScriptInfo[]) { function hoistedScripts(Components: ComponentThatMaybeHasHoistedScripts[], scripts: ScriptInfo[]) {
const flatScripts = []; const flatScripts = [];
const allScripts: ScriptInfo[] = Components.map(c => c && c[sym]) const allScripts: ScriptInfo[] = Components.map((c) => c && c[sym])
.filter(a => a) .filter((a) => a)
.concat(scripts) .concat(scripts)
.flatMap(a => a); .flatMap((a) => a);
const visitedSource = new Set(); const visitedSource = new Set();
for(let script of allScripts) { for (let script of allScripts) {
if(!('src' in script)) { if (!('src' in script)) {
flatScripts.push(script); flatScripts.push(script);
} else if(!visitedSource.has(script.src)) { } else if (!visitedSource.has(script.src)) {
flatScripts.push(script); flatScripts.push(script);
visitedSource.add(script.src); visitedSource.add(script.src);
} }
} }
return flatScripts; return flatScripts;
} }
export { export { hoistedScripts as __astro_hoisted_scripts };
hoistedScripts as __astro_hoisted_scripts
};

View file

@ -163,7 +163,7 @@ async function load(config: AstroRuntimeConfig, rawPathname: string | undefined)
children: [], children: [],
props: pageProps, props: pageProps,
css: Array.isArray(mod.css) ? mod.css : typeof mod.css === 'string' ? [mod.css] : [], css: Array.isArray(mod.css) ? mod.css : typeof mod.css === 'string' ? [mod.css] : [],
scripts: mod.exports.default[Symbol.for('astro.hoistedScripts')] scripts: mod.exports.default[Symbol.for('astro.hoistedScripts')],
})) as string; })) as string;
return { return {

View file

@ -31,10 +31,10 @@ Scripts('Moves inline scripts up', async ({ runtime }) => {
assert.equal($('body script').length, 0); assert.equal($('body script').length, 0);
}); });
Scripts('Builds the scripts to a single bundle', async({ build, readFile }) => { Scripts('Builds the scripts to a single bundle', async ({ build, readFile }) => {
try { try {
await build(); await build();
} catch(err) { } catch (err) {
console.error(err.stack); console.error(err.stack);
assert.ok(!err); assert.ok(!err);
return; return;