Update compiler, improve tests
This commit is contained in:
parent
00389e3fc0
commit
bf38f9ea93
9 changed files with 105 additions and 94 deletions
|
@ -89,7 +89,7 @@
|
||||||
"srcset-parse": "^1.1.0",
|
"srcset-parse": "^1.1.0",
|
||||||
"string-width": "^5.0.0",
|
"string-width": "^5.0.0",
|
||||||
"supports-esm": "^1.0.0",
|
"supports-esm": "^1.0.0",
|
||||||
"vite": "^2.5.2",
|
"vite": "^2.5.7",
|
||||||
"yargs-parser": "^20.2.9",
|
"yargs-parser": "^20.2.9",
|
||||||
"zod": "^3.8.1"
|
"zod": "^3.8.1"
|
||||||
},
|
},
|
||||||
|
|
|
@ -42,7 +42,7 @@ async function _render(child: any) {
|
||||||
export class AstroComponent {
|
export class AstroComponent {
|
||||||
private htmlParts: string[];
|
private htmlParts: string[];
|
||||||
private expressions: TemplateStringsArray;
|
private expressions: TemplateStringsArray;
|
||||||
|
|
||||||
constructor(htmlParts: string[], expressions: TemplateStringsArray) {
|
constructor(htmlParts: string[], expressions: TemplateStringsArray) {
|
||||||
this.htmlParts = htmlParts;
|
this.htmlParts = htmlParts;
|
||||||
this.expressions = expressions;
|
this.expressions = expressions;
|
||||||
|
@ -74,7 +74,7 @@ export const createComponent = (cb: AstroComponentFactory) => {
|
||||||
// Add a flag to this callback to mark it as an Astro component
|
// Add a flag to this callback to mark it as an Astro component
|
||||||
(cb as any).isAstroComponentFactory = true;
|
(cb as any).isAstroComponentFactory = true;
|
||||||
return cb;
|
return cb;
|
||||||
}
|
};
|
||||||
|
|
||||||
function extractHydrationDirectives(inputProps: Record<string | number, any>): { hydrationDirective: [string, any] | null; props: Record<string | number, any> } {
|
function extractHydrationDirectives(inputProps: Record<string | number, any>): { hydrationDirective: [string, any] | null; props: Record<string | number, any> } {
|
||||||
let props: Record<string | number, any> = {};
|
let props: Record<string | number, any> = {};
|
||||||
|
@ -101,7 +101,7 @@ async function generateHydrateScript(scriptOptions: HydrateScriptOptions, metada
|
||||||
const { hydrate, componentUrl, componentExport } = metadata;
|
const { hydrate, componentUrl, componentExport } = metadata;
|
||||||
|
|
||||||
if (!componentExport) {
|
if (!componentExport) {
|
||||||
throw new Error(`Unable to resolve a componentExport for "${metadata.displayName}"! Please open an issue.`)
|
throw new Error(`Unable to resolve a componentExport for "${metadata.displayName}"! Please open an issue.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let hydrationSource = '';
|
let hydrationSource = '';
|
||||||
|
@ -133,7 +133,7 @@ export const renderComponent = async (result: any, displayName: string, Componen
|
||||||
// children = await renderGenerator(children);
|
// children = await renderGenerator(children);
|
||||||
const { renderers } = result._metadata;
|
const { renderers } = result._metadata;
|
||||||
if (Component && (Component as any).isAstroComponentFactory) {
|
if (Component && (Component as any).isAstroComponentFactory) {
|
||||||
const output = await renderAstroComponent(await (Component as any)(result, Component, _props, children))
|
const output = await renderAstroComponent(await (Component as any)(result, Component, _props, children));
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import type { AstroComponent, AstroComponentFactory } from '../internal';
|
||||||
|
|
||||||
interface SSROptions {
|
interface SSROptions {
|
||||||
/** an instance of the AstroConfig */
|
/** an instance of the AstroConfig */
|
||||||
astroConfig: AstroConfig,
|
astroConfig: AstroConfig;
|
||||||
/** location of file on disk */
|
/** location of file on disk */
|
||||||
filePath: URL;
|
filePath: URL;
|
||||||
/** logging options */
|
/** logging options */
|
||||||
|
@ -51,14 +51,14 @@ export async function renderAstroComponent(component: InstanceType<typeof AstroC
|
||||||
export async function renderToString(result: any, componentFactory: AstroComponentFactory, props: any, children: any) {
|
export async function renderToString(result: any, componentFactory: AstroComponentFactory, props: any, children: any) {
|
||||||
const Component = await componentFactory(result, props, children);
|
const Component = await componentFactory(result, props, children);
|
||||||
let template = await renderAstroComponent(Component);
|
let template = await renderAstroComponent(Component);
|
||||||
return template
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function renderPage(result: any, Component: AstroComponentFactory, props: any, children: any) {
|
async function renderPage(result: any, Component: AstroComponentFactory, props: any, children: any) {
|
||||||
const template = await renderToString(result, Component, props, children);
|
const template = await renderToString(result, Component, props, children);
|
||||||
const styles = Array.from(result.styles).map(style => `<style>${style}</style>`);
|
const styles = Array.from(result.styles).map((style) => `<style>${style}</style>`);
|
||||||
const scripts = Array.from(result.scripts);
|
const scripts = Array.from(result.scripts);
|
||||||
return template.replace("</head>", styles.join('\n') + scripts.join('\n') + "</head>");
|
return template.replace('</head>', styles.join('\n') + scripts.join('\n') + '</head>');
|
||||||
}
|
}
|
||||||
|
|
||||||
const cache = new Map();
|
const cache = new Map();
|
||||||
|
@ -66,44 +66,46 @@ const cache = new Map();
|
||||||
// TODO: improve validation and error handling here.
|
// TODO: improve validation and error handling here.
|
||||||
async function resolveRenderers(viteServer: ViteDevServer, ids: string[]) {
|
async function resolveRenderers(viteServer: ViteDevServer, ids: string[]) {
|
||||||
const resolve = viteServer.config.createResolver();
|
const resolve = viteServer.config.createResolver();
|
||||||
const renderers = await Promise.all(ids.map(async renderer => {
|
const renderers = await Promise.all(
|
||||||
if (cache.has(renderer)) return cache.get(renderer);
|
ids.map(async (renderer) => {
|
||||||
const resolvedRenderer: any = {};
|
if (cache.has(renderer)) return cache.get(renderer);
|
||||||
|
const resolvedRenderer: any = {};
|
||||||
|
|
||||||
// We can dynamically import the renderer by itself because it shouldn't have
|
// We can dynamically import the renderer by itself because it shouldn't have
|
||||||
// any non-standard imports, the index is just meta info.
|
// any non-standard imports, the index is just meta info.
|
||||||
// The other entrypoints need to be loaded through Vite.
|
// The other entrypoints need to be loaded through Vite.
|
||||||
const { default: instance } = await import(renderer);
|
const { default: instance } = await import(renderer);
|
||||||
|
|
||||||
// This resolves the renderer's entrypoints to a final URL through Vite
|
// This resolves the renderer's entrypoints to a final URL through Vite
|
||||||
const getPath = async (src: string) => {
|
const getPath = async (src: string) => {
|
||||||
const spec = path.posix.join(instance.name, src);
|
const spec = path.posix.join(instance.name, src);
|
||||||
const resolved = await resolve(spec);
|
const resolved = await resolve(spec);
|
||||||
if (!resolved) {
|
if (!resolved) {
|
||||||
throw new Error(`Unable to resolve "${spec}" to a package!`)
|
throw new Error(`Unable to resolve "${spec}" to a package!`);
|
||||||
|
}
|
||||||
|
return resolved;
|
||||||
|
};
|
||||||
|
|
||||||
|
resolvedRenderer.name = instance.name;
|
||||||
|
if (instance.client) {
|
||||||
|
resolvedRenderer.source = await getPath(instance.client);
|
||||||
|
}
|
||||||
|
if (Array.isArray(instance.hydrationPolyfills)) {
|
||||||
|
resolvedRenderer.hydrationPolyfills = await Promise.all(instance.hydrationPolyfills.map((src: string) => getPath(src)));
|
||||||
|
}
|
||||||
|
if (Array.isArray(instance.polyfills)) {
|
||||||
|
resolvedRenderer.polyfills = await Promise.all(instance.polyfills.map((src: string) => getPath(src)));
|
||||||
}
|
}
|
||||||
return resolved;
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvedRenderer.name = instance.name;
|
|
||||||
if (instance.client) {
|
|
||||||
resolvedRenderer.source = await getPath(instance.client);
|
|
||||||
}
|
|
||||||
if (Array.isArray(instance.hydrationPolyfills)) {
|
|
||||||
resolvedRenderer.hydrationPolyfills = await Promise.all(instance.hydrationPolyfills.map((src: string) => getPath(src)));
|
|
||||||
}
|
|
||||||
if (Array.isArray(instance.polyfills)) {
|
|
||||||
resolvedRenderer.polyfills = await Promise.all(instance.polyfills.map((src: string) => getPath(src)));
|
|
||||||
}
|
|
||||||
|
|
||||||
const { url } = await viteServer.moduleGraph.ensureEntryFromUrl(await getPath(instance.server));
|
const { url } = await viteServer.moduleGraph.ensureEntryFromUrl(await getPath(instance.server));
|
||||||
const { default: server } = await viteServer.ssrLoadModule(url);
|
const { default: server } = await viteServer.ssrLoadModule(url);
|
||||||
resolvedRenderer.ssr = server;
|
resolvedRenderer.ssr = server;
|
||||||
|
|
||||||
cache.set(renderer, resolvedRenderer);
|
cache.set(renderer, resolvedRenderer);
|
||||||
return resolvedRenderer
|
return resolvedRenderer;
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
return renderers;
|
return renderers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,35 +118,39 @@ async function resolveImportedModules(viteServer: ViteDevServer, file: string) {
|
||||||
|
|
||||||
let importedModules: Record<string, any> = {};
|
let importedModules: Record<string, any> = {};
|
||||||
const moduleNodes = Array.from(modulesByFile);
|
const moduleNodes = Array.from(modulesByFile);
|
||||||
|
|
||||||
// Loop over the importedModules and grab the exports from each one.
|
// Loop over the importedModules and grab the exports from each one.
|
||||||
// We'll pass these to the shared $$result so renderers can match
|
// We'll pass these to the shared $$result so renderers can match
|
||||||
// components to their exported identifier and URL
|
// components to their exported identifier and URL
|
||||||
// NOTE: Important that this is parallelized as much as possible!
|
// NOTE: Important that this is parallelized as much as possible!
|
||||||
await Promise.all(moduleNodes.map(moduleNode => {
|
await Promise.all(
|
||||||
const entries = Array.from(moduleNode.importedModules);
|
moduleNodes.map((moduleNode) => {
|
||||||
|
const entries = Array.from(moduleNode.importedModules);
|
||||||
return Promise.all(entries.map(entry => {
|
|
||||||
// Skip our internal import that every module will have
|
|
||||||
if (entry.id?.endsWith('astro/dist/internal/index.js')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return viteServer.moduleGraph.ensureEntryFromUrl(entry.url).then(mod => {
|
|
||||||
if (mod.ssrModule) {
|
|
||||||
importedModules[mod.url] = mod.ssrModule;
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
return viteServer.ssrLoadModule(mod.url).then(result => {
|
|
||||||
importedModules[mod.url] = result.ssrModule;
|
|
||||||
return;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}))
|
|
||||||
}))
|
|
||||||
|
|
||||||
return importedModules
|
return Promise.all(
|
||||||
|
entries.map((entry) => {
|
||||||
|
// Skip our internal import that every module will have
|
||||||
|
if (entry.id?.endsWith('astro/dist/internal/index.js')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return viteServer.moduleGraph.ensureEntryFromUrl(entry.url).then((mod) => {
|
||||||
|
if (mod.ssrModule) {
|
||||||
|
importedModules[mod.url] = mod.ssrModule;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
return viteServer.ssrLoadModule(mod.url).then((result) => {
|
||||||
|
importedModules[mod.url] = result.ssrModule;
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return importedModules;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** use Vite to SSR */
|
/** use Vite to SSR */
|
||||||
|
@ -154,10 +160,7 @@ export async function ssr({ astroConfig, filePath, logging, mode, origin, pathna
|
||||||
|
|
||||||
// 1.5. resolve renderers and imported modules.
|
// 1.5. resolve renderers and imported modules.
|
||||||
// important that this happens _after_ ssrLoadModule, otherwise `importedModules` would be empty
|
// important that this happens _after_ ssrLoadModule, otherwise `importedModules` would be empty
|
||||||
const [renderers, importedModules] = await Promise.all([
|
const [renderers, importedModules] = await Promise.all([resolveRenderers(viteServer, astroConfig.renderers), resolveImportedModules(viteServer, fileURLToPath(filePath))]);
|
||||||
resolveRenderers(viteServer, astroConfig.renderers),
|
|
||||||
resolveImportedModules(viteServer, fileURLToPath(filePath))
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 2. handle dynamic routes
|
// 2. handle dynamic routes
|
||||||
let params: Params = {};
|
let params: Params = {};
|
||||||
|
@ -192,22 +195,26 @@ export async function ssr({ astroConfig, filePath, logging, mode, origin, pathna
|
||||||
const fullURL = new URL(pathname, origin);
|
const fullURL = new URL(pathname, origin);
|
||||||
|
|
||||||
const Component = await mod.default;
|
const Component = await mod.default;
|
||||||
if (!Component)
|
if (!Component) throw new Error(`Expected an exported Astro component but recieved typeof ${typeof Component}`);
|
||||||
throw new Error(`Expected an exported Astro component but recieved typeof ${typeof Component}`);
|
|
||||||
if (!Component.isAstroComponentFactory) throw new Error(`Unable to SSR non-Astro component (${route?.component})`);
|
if (!Component.isAstroComponentFactory) throw new Error(`Unable to SSR non-Astro component (${route?.component})`);
|
||||||
|
|
||||||
let html = await renderPage({
|
let html = await renderPage(
|
||||||
styles: new Set(),
|
{
|
||||||
scripts: new Set(),
|
styles: new Set(),
|
||||||
/** This function returns the `Astro` faux-global */
|
scripts: new Set(),
|
||||||
createAstro(props: any) {
|
/** This function returns the `Astro` faux-global */
|
||||||
const site = new URL(origin);
|
createAstro(props: any) {
|
||||||
const url = new URL('.' + pathname, site);
|
const site = new URL(origin);
|
||||||
const canonicalURL = getCanonicalURL(pathname, astroConfig.buildOptions.site || origin)
|
const url = new URL('.' + pathname, site);
|
||||||
return { isPage: true, site, request: { url, canonicalURL }, props };
|
const canonicalURL = getCanonicalURL(pathname, astroConfig.buildOptions.site || origin);
|
||||||
|
return { isPage: true, site, request: { url, canonicalURL }, props };
|
||||||
|
},
|
||||||
|
_metadata: { importedModules, renderers },
|
||||||
},
|
},
|
||||||
_metadata: { importedModules, renderers },
|
Component,
|
||||||
}, Component, { }, null);
|
{},
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
// 4. modify response
|
// 4. modify response
|
||||||
if (mode === 'development') {
|
if (mode === 'development') {
|
||||||
|
|
|
@ -18,7 +18,10 @@ const require = createRequire(import.meta.url);
|
||||||
type ViteConfigWithSSR = InlineConfig & { ssr?: { external?: string[]; noExternal?: string[] } };
|
type ViteConfigWithSSR = InlineConfig & { ssr?: { external?: string[]; noExternal?: string[] } };
|
||||||
|
|
||||||
/** Return a common starting point for all Vite actions */
|
/** Return a common starting point for all Vite actions */
|
||||||
export async function loadViteConfig(viteConfig: ViteConfigWithSSR, { astroConfig, logging, devServer }: { astroConfig: AstroConfig; logging: LogOptions, devServer?: AstroDevServer }): Promise<ViteConfigWithSSR> {
|
export async function loadViteConfig(
|
||||||
|
viteConfig: ViteConfigWithSSR,
|
||||||
|
{ astroConfig, logging, devServer }: { astroConfig: AstroConfig; logging: LogOptions; devServer?: AstroDevServer }
|
||||||
|
): Promise<ViteConfigWithSSR> {
|
||||||
const optimizedDeps = new Set<string>(); // dependencies that must be bundled for the client (Vite may not detect all of these)
|
const optimizedDeps = new Set<string>(); // dependencies that must be bundled for the client (Vite may not detect all of these)
|
||||||
const dedupe = new Set<string>(); // dependencies that can’t be duplicated (e.g. React & SolidJS)
|
const dedupe = new Set<string>(); // dependencies that can’t be duplicated (e.g. React & SolidJS)
|
||||||
const plugins: Plugin[] = []; // Vite plugins
|
const plugins: Plugin[] = []; // Vite plugins
|
||||||
|
@ -41,7 +44,8 @@ export async function loadViteConfig(viteConfig: ViteConfigWithSSR, { astroConfi
|
||||||
optimizedDeps.add(name + renderer.client.substr(1));
|
optimizedDeps.add(name + renderer.client.substr(1));
|
||||||
}
|
}
|
||||||
// 2. knownEntrypoints and polyfills need to be added to the client
|
// 2. knownEntrypoints and polyfills need to be added to the client
|
||||||
for (const dep of [...(renderer.knownEntrypoints || []), ...(renderer.polyfills || [])]) {
|
for (let dep of [...(renderer.knownEntrypoints || []), ...(renderer.polyfills || [])]) {
|
||||||
|
if (dep[0] === '.') dep = name + dep.substr(1); // if local polyfill, use full path
|
||||||
optimizedDeps.add(dep);
|
optimizedDeps.add(dep);
|
||||||
dedupe.add(dep); // we can try and dedupe renderers by default
|
dedupe.add(dep); // we can try and dedupe renderers by default
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ describe('Doctype', () => {
|
||||||
expect(html).toEqual(expect.stringMatching(/^<!doctype html>/));
|
expect(html).toEqual(expect.stringMatching(/^<!doctype html>/));
|
||||||
|
|
||||||
// test 2: A link inside of the head
|
// test 2: A link inside of the head
|
||||||
const $ = doc(html);
|
const $ = cheerio.load(html);
|
||||||
expect($('head link')).toHaveLength(1);
|
expect($('head link')).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ describe.skip('HMR tests', () => {
|
||||||
const result = await runtime.load('/static');
|
const result = await runtime.load('/static');
|
||||||
assert.ok(!result.error, `build error: ${result.error}`);
|
assert.ok(!result.error, `build error: ${result.error}`);
|
||||||
const html = result.contents;
|
const html = result.contents;
|
||||||
const $ = doc(html);
|
const $ = cheerio.load(html);
|
||||||
assert.equal($('[src="/_snowpack/hmr-client.js"]').length, 1);
|
assert.equal($('[src="/_snowpack/hmr-client.js"]').length, 1);
|
||||||
assert.ok(/window\.HMR_WEBSOCKET_PORT/.test(html), 'websocket port added');
|
assert.ok(/window\.HMR_WEBSOCKET_PORT/.test(html), 'websocket port added');
|
||||||
});
|
});
|
||||||
|
@ -39,7 +39,7 @@ describe.skip('HMR tests', () => {
|
||||||
const result = await runtime.load('/no-elements');
|
const result = await runtime.load('/no-elements');
|
||||||
assert.ok(!result.error, `build error: ${result.error}`);
|
assert.ok(!result.error, `build error: ${result.error}`);
|
||||||
const html = result.contents;
|
const html = result.contents;
|
||||||
const $ = doc(html);
|
const $ = cheerio.load(html);
|
||||||
assert.equal($('[src="/_snowpack/hmr-client.js"]').length, 1);
|
assert.equal($('[src="/_snowpack/hmr-client.js"]').length, 1);
|
||||||
assert.ok(/window\.HMR_WEBSOCKET_PORT/.test(html), 'websocket port added');
|
assert.ok(/window\.HMR_WEBSOCKET_PORT/.test(html), 'websocket port added');
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,7 +18,7 @@ describe('Hoisted scripts', () => {
|
||||||
|
|
||||||
test('Moves external scripts up', async () => {
|
test('Moves external scripts up', async () => {
|
||||||
const html = await fixture.fetch('/external').then((res) => res.text());
|
const html = await fixture.fetch('/external').then((res) => res.text());
|
||||||
const $ = doc(html);
|
const $ = cheerio.load(html);
|
||||||
|
|
||||||
expect($('head script[type="module"][data-astro="hoist"]')).toHaveLength(2);
|
expect($('head script[type="module"][data-astro="hoist"]')).toHaveLength(2);
|
||||||
expect($('body script')).toHaveLength(0);
|
expect($('body script')).toHaveLength(0);
|
||||||
|
@ -26,7 +26,7 @@ describe('Hoisted scripts', () => {
|
||||||
|
|
||||||
test('Moves inline scripts up', async () => {
|
test('Moves inline scripts up', async () => {
|
||||||
const html = await fixture.fetch('/inline').then((res) => res.text());
|
const html = await fixture.fetch('/inline').then((res) => res.text());
|
||||||
const $ = doc(html);
|
const $ = cheerio.load(html);
|
||||||
|
|
||||||
expect($('head script[type="module"][data-astro="hoist"]')).toHaveLength(1);
|
expect($('head script[type="module"][data-astro="hoist"]')).toHaveLength(1);
|
||||||
expect($('body script')).toHaveLength(0);
|
expect($('body script')).toHaveLength(0);
|
||||||
|
@ -63,7 +63,7 @@ describe('Hoisted scripts', () => {
|
||||||
|
|
||||||
test('External page builds the scripts to a single bundle', async () => {
|
test('External page builds the scripts to a single bundle', async () => {
|
||||||
let external = await fixture.readFile('/external/index.html');
|
let external = await fixture.readFile('/external/index.html');
|
||||||
$ = doc(external);
|
$ = cheerio.load(external);
|
||||||
|
|
||||||
// test 1: there are two scripts
|
// test 1: there are two scripts
|
||||||
assert.equal($('script')).toHaveLength(2);
|
assert.equal($('script')).toHaveLength(2);
|
||||||
|
|
|
@ -19,7 +19,7 @@ describe('LitElement test', () => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const html = await fixture.fetch('/').then((res) => res.text());
|
const html = await fixture.fetch('/').then((res) => res.text());
|
||||||
const $ = doc(html);
|
const $ = cheerio.load(html);
|
||||||
|
|
||||||
// test 1: attributes rendered
|
// test 1: attributes rendered
|
||||||
expect($('my-element').attr('foo')).toBe('bar');
|
expect($('my-element').attr('foo')).toBe('bar');
|
||||||
|
@ -31,7 +31,7 @@ describe('LitElement test', () => {
|
||||||
// Skipped because not supported by Lit
|
// Skipped because not supported by Lit
|
||||||
test.skip('Renders a custom element by the constructor', async () => {
|
test.skip('Renders a custom element by the constructor', async () => {
|
||||||
const html = await fixture.fetch('/ctr').then((res) => res.text());
|
const html = await fixture.fetch('/ctr').then((res) => res.text());
|
||||||
const $ = doc(html);
|
const $ = cheerio.load(html);
|
||||||
|
|
||||||
// test 1: attributes rendered
|
// test 1: attributes rendered
|
||||||
expect($('my-element').attr('foo')).toBe('bar');
|
expect($('my-element').attr('foo')).toBe('bar');
|
||||||
|
|
|
@ -11679,10 +11679,10 @@ vfile@^5.0.0:
|
||||||
unist-util-stringify-position "^3.0.0"
|
unist-util-stringify-position "^3.0.0"
|
||||||
vfile-message "^3.0.0"
|
vfile-message "^3.0.0"
|
||||||
|
|
||||||
vite@^2.5.2:
|
vite@^2.5.7:
|
||||||
version "2.5.2"
|
version "2.5.7"
|
||||||
resolved "https://registry.yarnpkg.com/vite/-/vite-2.5.2.tgz#3963a4ec1e6ecae49359eddfdd67f6cb1e6e07a1"
|
resolved "https://registry.yarnpkg.com/vite/-/vite-2.5.7.tgz#e495be9d8bcbf9d30c7141efdccacde746ee0125"
|
||||||
integrity sha512-JK5uhiVyMqHiAJbgBa8rCvpP8bEhAE9dKDv1gCmP+EUP2FSPmEeW3WXlCXauPB3MDa8behPW+ntyNXqnGaxslg==
|
integrity sha512-hyUoWmRPhjN1aI+ZSBqDINKdIq7aokHE2ZXiztOg4YlmtpeQtMwMeyxv6X9YxHZmvGzg/js/eATM9Z1nwyakxg==
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild "^0.12.17"
|
esbuild "^0.12.17"
|
||||||
postcss "^8.3.6"
|
postcss "^8.3.6"
|
||||||
|
|
Loading…
Reference in a new issue