summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorGravatar Drew Powers <1369770+drwpow@users.noreply.github.com> 2021-11-16 13:59:41 -0700
committerGravatar GitHub <noreply@github.com> 2021-11-16 13:59:41 -0700
commit3cd1458aa7f86a058eb3d942457c416d4f80adf1 (patch)
treee126929620f74d14dcd98fb3e41421c2446846ca /packages
parentd9265df0e9a6de25afffe1a8da874b345498b739 (diff)
downloadastro-3cd1458aa7f86a058eb3d942457c416d4f80adf1.tar.gz
astro-3cd1458aa7f86a058eb3d942457c416d4f80adf1.tar.zst
astro-3cd1458aa7f86a058eb3d942457c416d4f80adf1.zip
Fix Windows CSS bundling bug (#1840)
* Fix Windows CSS bundling bug JS components’ styles accidentally left out of final build on Windows * Review feedback
Diffstat (limited to 'packages')
-rw-r--r--packages/astro/src/core/ssr/css.ts9
-rw-r--r--packages/astro/src/core/ssr/index.ts9
-rw-r--r--packages/astro/src/core/util.ts2
-rw-r--r--packages/astro/src/vite-plugin-astro/index.ts4
-rw-r--r--packages/astro/src/vite-plugin-build-html/extract-assets.ts5
-rw-r--r--packages/astro/src/vite-plugin-build-html/index.ts9
-rw-r--r--packages/astro/test/astro-styles-ssr.test.js211
-rw-r--r--packages/astro/test/fixtures/astro-styles-ssr/src/components/VueScoped.vue4
-rw-r--r--packages/astro/test/postcss.test.js7
-rw-r--r--packages/renderers/renderer-preact/package.json2
-rw-r--r--packages/renderers/renderer-react/package.json2
-rw-r--r--packages/renderers/renderer-solid/package.json4
-rw-r--r--packages/renderers/renderer-svelte/package.json4
-rw-r--r--packages/renderers/renderer-vue/package.json8
14 files changed, 149 insertions, 131 deletions
diff --git a/packages/astro/src/core/ssr/css.ts b/packages/astro/src/core/ssr/css.ts
index 28fcbafd8..f091a6467 100644
--- a/packages/astro/src/core/ssr/css.ts
+++ b/packages/astro/src/core/ssr/css.ts
@@ -1,15 +1,18 @@
import type vite from '../../../vendor/vite';
+import { fileURLToPath } from 'url';
import path from 'path';
+import slash from 'slash';
// https://vitejs.dev/guide/features.html#css-pre-processors
export const STYLE_EXTENSIONS = new Set(['.css', '.pcss', '.scss', '.sass', '.styl', '.stylus', '.less']);
/** find unloaded styles */
-export function getStylesForID(id: string, viteServer: vite.ViteDevServer): Set<string> {
+export function getStylesForURL(filePath: URL, viteServer: vite.ViteDevServer): Set<string> {
const css = new Set<string>();
const { idToModuleMap } = viteServer.moduleGraph;
- const moduleGraph = idToModuleMap.get(id);
+ const rootID = slash(fileURLToPath(filePath)); // Vite fix: Windows URLs must have forward slashes
+ const moduleGraph = idToModuleMap.get(rootID);
if (!moduleGraph) return css;
// recursively crawl module graph to get all style files imported by parent id
@@ -27,7 +30,7 @@ export function getStylesForID(id: string, viteServer: vite.ViteDevServer): Set<
scanned.add(importedModule.id);
}
}
- crawlCSS(id);
+ crawlCSS(rootID);
return css;
}
diff --git a/packages/astro/src/core/ssr/index.ts b/packages/astro/src/core/ssr/index.ts
index 720acbad6..193aa43bc 100644
--- a/packages/astro/src/core/ssr/index.ts
+++ b/packages/astro/src/core/ssr/index.ts
@@ -6,9 +6,11 @@ import type { LogOptions } from '../logger';
import fs from 'fs';
import path from 'path';
+import slash from 'slash';
+import { fileURLToPath } from 'url';
import { renderPage, renderSlot } from '../../runtime/server/index.js';
import { canonicalURL as getCanonicalURL, codeFrame, resolveDependency, viteifyPath } from '../util.js';
-import { getStylesForID } from './css.js';
+import { getStylesForURL } from './css.js';
import { injectTags } from './html.js';
import { generatePaginateFunction } from './paginate.js';
import { getParams, validateGetStaticPathsModule, validateGetStaticPathsResult } from './routing.js';
@@ -215,7 +217,7 @@ export async function render(renderers: Renderer[], mod: ComponentInstance, ssrO
}
// inject CSS
- [...getStylesForID(filePath.pathname, viteServer)].forEach((href) => {
+ [...getStylesForURL(filePath, viteServer)].forEach((href) => {
tags.push({
tag: 'link',
attrs: {
@@ -232,7 +234,8 @@ export async function render(renderers: Renderer[], mod: ComponentInstance, ssrO
// run transformIndexHtml() in dev to run Vite dev transformations
if (mode === 'development') {
- html = await viteServer.transformIndexHtml(filePath.pathname, html, pathname);
+ const viteFilePath = slash(fileURLToPath(filePath)); // Vite Windows fix: URLs on Windows have forward slashes (not .pathname, which has a leading '/' on Windows)
+ html = await viteServer.transformIndexHtml(viteFilePath, html, pathname);
}
return html;
diff --git a/packages/astro/src/core/util.ts b/packages/astro/src/core/util.ts
index 3981aad95..2e91d6229 100644
--- a/packages/astro/src/core/util.ts
+++ b/packages/astro/src/core/util.ts
@@ -73,5 +73,5 @@ export function resolveDependency(dep: string, astroConfig: AstroConfig) {
}
export function viteifyPath(pathname: string): string {
- return `/@fs${pathname}`;
+ return `/@fs/${pathname.replace(/^\//, '')}`;
}
diff --git a/packages/astro/src/vite-plugin-astro/index.ts b/packages/astro/src/vite-plugin-astro/index.ts
index 821dd3b36..f88dc24fb 100644
--- a/packages/astro/src/vite-plugin-astro/index.ts
+++ b/packages/astro/src/vite-plugin-astro/index.ts
@@ -33,11 +33,13 @@ function isSSR(options: undefined | boolean | { ssr: boolean }): boolean {
/** Transform .astro files for Vite */
export default function astro({ config, devServer }: AstroPluginOptions): vite.Plugin {
+ let platform: NodeJS.Platform;
let viteTransform: TransformHook;
return {
name: '@astrojs/vite-plugin-astro',
enforce: 'pre', // run transforms before other plugins can
configResolved(resolvedConfig) {
+ platform = os.platform(); // TODO: remove macOS hack
viteTransform = getViteTransform(resolvedConfig);
},
// note: don’t claim .astro files with resolveId() — it prevents Vite from transpiling the final JS (import.meta.globEager, etc.)
@@ -82,7 +84,7 @@ export default function astro({ config, devServer }: AstroPluginOptions): vite.P
});
// macOS fix: remove null chars generated by compiler
- if (os.platform() === 'darwin') {
+ if (platform === 'darwin') {
tsResult.code = tsResult.code.replace(/\x00/g, '');
}
diff --git a/packages/astro/src/vite-plugin-build-html/extract-assets.ts b/packages/astro/src/vite-plugin-build-html/extract-assets.ts
index 33bfbc35e..1f3f6d360 100644
--- a/packages/astro/src/vite-plugin-build-html/extract-assets.ts
+++ b/packages/astro/src/vite-plugin-build-html/extract-assets.ts
@@ -5,6 +5,7 @@ import adapter from 'parse5/lib/tree-adapters/default.js';
const hashedLinkRels = ['stylesheet', 'preload'];
const linkRels = [...hashedLinkRels, 'icon', 'manifest', 'apple-touch-icon', 'mask-icon'];
+const windowsPathRE = /^[A-Z]:\//;
function getSrcSetUrls(srcset: string) {
if (!srcset) {
@@ -54,6 +55,10 @@ function isAsset(node: Element) {
if (!path) {
return false;
}
+ // Windows fix: if path starts with C:/, avoid URL parsing
+ if (windowsPathRE.test(path)) {
+ return true;
+ }
try {
new URL(path);
return false;
diff --git a/packages/astro/src/vite-plugin-build-html/index.ts b/packages/astro/src/vite-plugin-build-html/index.ts
index efeb1a05a..6e8181e1f 100644
--- a/packages/astro/src/vite-plugin-build-html/index.ts
+++ b/packages/astro/src/vite-plugin-build-html/index.ts
@@ -8,6 +8,8 @@ import srcsetParse from 'srcset-parse';
import * as npath from 'path';
import { promises as fs } from 'fs';
import { getAttribute, hasAttribute, getTagName, insertBefore, remove, createScript, createElement, setAttribute } from '@web/parse5-utils';
+import slash from 'slash';
+import { fileURLToPath } from 'url';
import { addRollupInput } from './add-rollup-input.js';
import { findAssets, findExternalScripts, findInlineScripts, findInlineStyles, getTextContent, isStylesheetLink } from './extract-assets.js';
import { render as ssrRender } from '../core/ssr/index.js';
@@ -26,7 +28,12 @@ const ASTRO_EMPTY = '@astro-empty';
const tagsWithSrcSet = new Set(['img', 'source']);
const isAstroInjectedLink = (node: parse5.Element) => isStylesheetLink(node) && getAttribute(node, 'data-astro-injected') === '';
-const isBuildableLink = (node: parse5.Element, srcRoot: string) => isAstroInjectedLink(node) || getAttribute(node, 'href')?.startsWith(srcRoot);
+const isBuildableLink = (node: parse5.Element, srcRoot: string) => {
+ if (isAstroInjectedLink(node)) return true;
+ const href = getAttribute(node, 'href');
+ if (typeof href !== 'string' || !href.length) return false;
+ return href.startsWith(srcRoot) || `/${href}`.startsWith(srcRoot); // Windows fix: some paths are missing leading "/"
+};
const isBuildableImage = (node: parse5.Element, srcRoot: string) => getTagName(node) === 'img' && getAttribute(node, 'src')?.startsWith(srcRoot);
const hasSrcSet = (node: parse5.Element) => tagsWithSrcSet.has(getTagName(node)) && !!getAttribute(node, 'srcset');
const isHoistedScript = (node: parse5.Element) => getTagName(node) === 'script' && hasAttribute(node, 'hoist');
diff --git a/packages/astro/test/astro-styles-ssr.test.js b/packages/astro/test/astro-styles-ssr.test.js
index 982d3f267..7241d4095 100644
--- a/packages/astro/test/astro-styles-ssr.test.js
+++ b/packages/astro/test/astro-styles-ssr.test.js
@@ -2,136 +2,141 @@ import { expect } from 'chai';
import cheerio from 'cheerio';
import { loadFixture } from './test-utils.js';
+let fixture;
+let index$;
+let bundledCSS;
+
+before(async () => {
+ fixture = await loadFixture({
+ projectRoot: './fixtures/astro-styles-ssr/',
+ renderers: ['@astrojs/renderer-react', '@astrojs/renderer-svelte', '@astrojs/renderer-vue'],
+ });
+ await fixture.build();
+
+ // get bundled CSS (will be hashed, hence DOM query)
+ const html = await fixture.readFile('/index.html');
+ index$ = cheerio.load(html);
+ const bundledCSSHREF = index$('link[rel=stylesheet][href^=assets/]').attr('href');
+ bundledCSS = await fixture.readFile(bundledCSSHREF.replace(/^\/?/, '/'));
+});
+
describe('Styles SSR', () => {
- let fixture;
+ describe('Astro styles', () => {
+ it('HTML and CSS scoped correctly', async () => {
+ const $ = index$;
- before(async () => {
- fixture = await loadFixture({ projectRoot: './fixtures/astro-styles-ssr/' });
- await fixture.build();
- });
+ const el1 = $('#dynamic-class');
+ const el2 = $('#dynamic-vis');
+ const classes = $('#class').attr('class').split(' ');
+ const scopedClass = classes.find((name) => /^astro-[A-Za-z0-9-]+/.test(name));
- it('Has <link> tags', async () => {
- const MUST_HAVE_LINK_TAGS = ['assets/index'];
+ // 1. check HTML
+ expect(el1.attr('class')).to.equal(`blue ${scopedClass}`);
+ expect(el2.attr('class')).to.equal(`visible ${scopedClass}`);
- const html = await fixture.readFile('/index.html');
- const $ = cheerio.load(html);
+ // 2. check CSS
+ expect(bundledCSS).to.include(`.blue.${scopedClass}{color:#b0e0e6}.color\\:blue.${scopedClass}{color:#b0e0e6}.visible.${scopedClass}{display:block}`);
+ });
- for (const href of [...$('link[rel="stylesheet"]')].map((el) => el.attribs.href)) {
- const hasTag = MUST_HAVE_LINK_TAGS.some((mustHaveHref) => href.includes(mustHaveHref));
- expect(hasTag).to.equal(true);
- }
- });
+ it('No <style> skips scoping', async () => {
+ const $ = index$;
- it('Has correct CSS classes', async () => {
- const html = await fixture.readFile('/index.html');
- const $ = cheerio.load(html);
-
- const MUST_HAVE_CLASSES = {
- '#react-css': 'react-title',
- '#react-modules': 'title', // ⚠️ this should be transformed
- '#vue-css': 'vue-title',
- '#vue-modules': 'title', // ⚠️ this should also be transformed
- '#vue-scoped': 'vue-title', // also has data-v-* property
- '#svelte-scoped': 'svelte-title', // also has additional class
- };
-
- for (const [selector, className] of Object.entries(MUST_HAVE_CLASSES)) {
- const el = $(selector);
- if (selector === '#react-modules' || selector === '#vue-modules') {
- // this will generate differently on Unix vs Windows. Here we simply test that it has transformed
- expect(el.attr('class')).to.match(new RegExp(`^_${className}_[A-Za-z0-9-_]+`)); // className should be transformed, surrounded by underscores and other stuff
- } else {
- // if this is not a CSS module, it should remain as expected
- expect(el.attr('class')).to.include(className);
- }
-
- // add’l test: Vue Scoped styles should have data-v-* attribute
- if (selector === '#vue-scoped') {
- const { attribs } = el.get(0);
- const scopeId = Object.keys(attribs).find((k) => k.startsWith('data-v-'));
- expect(scopeId).to.be.ok;
- }
-
- // add’l test: Svelte should have another class
- if (selector === '#svelte-title') {
- expect(el.attr('class')).not.to.equal(className);
- }
- }
- });
+ // Astro component without <style> should not include scoped class
+ expect($('#no-scope').attr('class')).to.equal(undefined);
+ });
- it('CSS scoped support in .astro', async () => {
- const html = await fixture.readFile('/index.html');
- const $ = cheerio.load(html);
+ it('Child inheritance', async () => {
+ const $ = index$;
- const href = '/' + $('link').attr('href');
- const raw = await fixture.readFile(href);
+ expect($('#passed-in').attr('class')).to.match(/outer astro-[A-Z0-9]+ astro-[A-Z0-9]+/);
+ });
- let scopedClass;
+ it('Using hydrated components adds astro-root styles', async () => {
+ expect(bundledCSS).to.include('display:contents');
+ });
+ });
- // test 1: <style> tag in <head> is transformed
- const css = raw.replace(/\.astro-[A-Za-z0-9-]+/, (match) => {
- scopedClass = match; // get class hash from result
- return match;
+ describe('JSX', () => {
+ it('CSS', async () => {
+ const $ = index$;
+ const el = $('#react-css');
+
+ // 1. check HTML
+ expect(el.attr('class')).to.include('react-title');
+
+ // 2. check CSS
+ expect(bundledCSS).to.include('.react-title{');
});
- expect(css).to.include(`.wrapper${scopedClass}{margin-left:auto;margin-right:auto;max-width:1200px}.outer${scopedClass}{color:red}`);
+ it('CSS Modules', async () => {
+ const $ = index$;
+ const el = $('#react-modules');
+ const classes = el.attr('class').split(' ');
+ const moduleClass = classes.find((name) => /^_title_[A-Za-z0-9-_]+/.test(name));
+
+ // 1. check HTML
+ expect(el.attr('class')).to.include(moduleClass);
- // test 2: element received .astro-XXXXXX class (this selector will succeed if transformed correctly)
- const wrapper = $(`.wrapper${scopedClass}`);
- expect(wrapper).to.have.lengthOf(1);
+ // 2. check CSS
+ expect(bundledCSS).to.include(`.${moduleClass}{`);
+ });
});
- it('Astro scoped styles', async () => {
- const html = await fixture.readFile('/index.html');
- const $ = cheerio.load(html);
+ describe('Vue', () => {
+ it('CSS', async () => {
+ const $ = index$;
+ const el = $('#vue-css');
- const el1 = $('#dynamic-class');
- const el2 = $('#dynamic-vis');
+ // 1. check HTML
+ expect(el.attr('class')).to.include('vue-title');
- let scopedClass;
+ // 2. check CSS
+ expect(bundledCSS).to.include('.vue-title{');
+ });
- $('#class')
- .attr('class')
- .replace(/astro-[A-Za-z0-9-]+/, (match) => {
- scopedClass = match;
- return match;
- });
+ // TODO: fix Vue scoped styles in build bug
+ it.skip('Scoped styles', async () => {
+ const $ = index$;
+ const el = $('#vue-scoped');
- // test 1: Astro component has some scoped class
- expect(scopedClass).to.be.ok;
+ // find data-v-* attribute (how Vue CSS scoping works)
+ const { attribs } = el.get(0);
+ const scopeId = Object.keys(attribs).find((k) => k.startsWith('data-v-'));
+ expect(scopeId).to.be.ok;
- // test 2–3: children get scoped class
- expect(el1.attr('class')).to.equal(`blue ${scopedClass}`);
- expect(el2.attr('class')).to.equal(`visible ${scopedClass}`);
+ // 1. check HTML
+ expect(el.attr('class')).to.include('vue-scoped');
- const href = '/' + $('link').attr('href');
- const css = await fixture.readFile(href);
+ // 2. check CSS
+ expect(bundledCSS).to.include(`.vue-scoped[${scopeId}]`);
+ });
- // test 4: CSS generates as expected
- expect(css).to.include(`.blue.${scopedClass}{color:#b0e0e6}.color\\:blue.${scopedClass}{color:#b0e0e6}.visible.${scopedClass}{display:block}`);
- });
+ it('CSS Modules', async () => {
+ const $ = index$;
+ const el = $('#vue-modules');
+ const classes = el.attr('class').split(' ');
+ const moduleClass = classes.find((name) => /^_title_[A-Za-z0-9-_]+/.test(name));
- it('Astro scoped styles skipped without <style>', async () => {
- const html = await fixture.readFile('/index.html');
- const $ = cheerio.load(html);
+ // 1. check HTML
+ expect(el.attr('class')).to.include(moduleClass);
- // test 1: Astro component without <style> should not include scoped class
- expect($('#no-scope').attr('class')).to.equal(undefined);
+ // 2. check CSS
+ expect(bundledCSS).to.include(`${moduleClass}{`);
+ });
});
- it('Astro scoped styles can be passed to child components', async () => {
- const html = await fixture.readFile('/index.html');
- const $ = cheerio.load(html);
+ describe('Svelte', () => {
+ it('Scoped styles', async () => {
+ const $ = index$;
+ const el = $('#svelte-scoped');
+ const classes = el.attr('class').split(' ');
+ const scopedClass = classes.find((name) => /^s-[A-Za-z0-9-]+/.test(name));
- expect($('#passed-in').attr('class')).to.match(/outer astro-[A-Z0-9]+ astro-[A-Z0-9]+/);
- });
+ // 1. check HTML
+ expect(el.attr('class')).to.include('svelte-title');
- it('Using hydrated components adds astro-root styles', async () => {
- const html = await fixture.readFile('/index.html');
- const $ = cheerio.load(html);
-
- const href = '/' + $('link').attr('href');
- const css = await fixture.readFile(href);
- expect(css).to.include('display:contents');
+ // 2. check CSS
+ expect(bundledCSS).to.include(`.svelte-title.${scopedClass}`);
+ });
});
});
diff --git a/packages/astro/test/fixtures/astro-styles-ssr/src/components/VueScoped.vue b/packages/astro/test/fixtures/astro-styles-ssr/src/components/VueScoped.vue
index 0eee4dff1..2aaca8a18 100644
--- a/packages/astro/test/fixtures/astro-styles-ssr/src/components/VueScoped.vue
+++ b/packages/astro/test/fixtures/astro-styles-ssr/src/components/VueScoped.vue
@@ -1,9 +1,9 @@
<style scoped>
-.vue-title {
+.vue-scoped {
font-family: cursive;
}
</style>
<template>
- <h1 id="vue-scoped" class="vue-title">Vue Scoped CSS</h1>
+ <h1 id="vue-scoped" class="vue-scoped">Vue Scoped CSS</h1>
</template>
diff --git a/packages/astro/test/postcss.test.js b/packages/astro/test/postcss.test.js
index ac38f6622..56959c97f 100644
--- a/packages/astro/test/postcss.test.js
+++ b/packages/astro/test/postcss.test.js
@@ -1,7 +1,6 @@
import { expect } from 'chai';
import cheerio from 'cheerio';
import eol from 'eol';
-import os from 'os';
import { loadFixture } from './test-utils.js';
const PREFIXED_CSS = `{-webkit-appearance:none;-moz-appearance:none;appearance:none}`;
@@ -36,20 +35,14 @@ describe('PostCSS', () => {
});
it('works in JSX', () => {
- // TODO: fix in Windows
- if (os.platform() === 'win32') return;
expect(bundledCSS).to.match(new RegExp(`.solid${PREFIXED_CSS}`));
});
it('works in Vue', () => {
- // TODO: fix in Windows
- if (os.platform() === 'win32') return;
expect(bundledCSS).to.match(new RegExp(`.vue${PREFIXED_CSS}`));
});
it('works in Svelte', () => {
- // TODO: fix in Windows
- if (os.platform() === 'win32') return;
expect(bundledCSS).to.match(new RegExp(`.svelte.s[^{]+${PREFIXED_CSS}`));
});
diff --git a/packages/renderers/renderer-preact/package.json b/packages/renderers/renderer-preact/package.json
index fbc32750c..836e700fd 100644
--- a/packages/renderers/renderer-preact/package.json
+++ b/packages/renderers/renderer-preact/package.json
@@ -11,7 +11,7 @@
"./package.json": "./package.json"
},
"dependencies": {
- "@babel/plugin-transform-react-jsx": "^7.14.9",
+ "@babel/plugin-transform-react-jsx": "^7.16.0",
"preact": "^10.5.15",
"preact-render-to-string": "^5.1.19"
},
diff --git a/packages/renderers/renderer-react/package.json b/packages/renderers/renderer-react/package.json
index 5ab761a33..d198fa717 100644
--- a/packages/renderers/renderer-react/package.json
+++ b/packages/renderers/renderer-react/package.json
@@ -10,7 +10,7 @@
"./package.json": "./package.json"
},
"dependencies": {
- "@babel/plugin-transform-react-jsx": "^7.14.9",
+ "@babel/plugin-transform-react-jsx": "^7.16.0",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
diff --git a/packages/renderers/renderer-solid/package.json b/packages/renderers/renderer-solid/package.json
index 49b3c5638..615823212 100644
--- a/packages/renderers/renderer-solid/package.json
+++ b/packages/renderers/renderer-solid/package.json
@@ -11,8 +11,8 @@
},
"dependencies": {
"babel-plugin-module-resolver": "^4.1.0",
- "babel-preset-solid": "^1.1.7",
- "solid-js": "^1.1.7"
+ "babel-preset-solid": "^1.2.3",
+ "solid-js": "^1.2.3"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
diff --git a/packages/renderers/renderer-svelte/package.json b/packages/renderers/renderer-svelte/package.json
index 9ac4e9147..c1f4cf135 100644
--- a/packages/renderers/renderer-svelte/package.json
+++ b/packages/renderers/renderer-svelte/package.json
@@ -10,8 +10,8 @@
"./package.json": "./package.json"
},
"dependencies": {
- "@sveltejs/vite-plugin-svelte": "^1.0.0-next.29",
- "svelte": "^3.44.0"
+ "@sveltejs/vite-plugin-svelte": "^1.0.0-next.30",
+ "svelte": "^3.44.1"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
diff --git a/packages/renderers/renderer-vue/package.json b/packages/renderers/renderer-vue/package.json
index 8b3d6bbe5..82d1dc3ce 100644
--- a/packages/renderers/renderer-vue/package.json
+++ b/packages/renderers/renderer-vue/package.json
@@ -10,10 +10,10 @@
"./package.json": "./package.json"
},
"dependencies": {
- "@vitejs/plugin-vue": "^1.9.3",
- "@vue/compiler-sfc": "^3.2.20",
- "@vue/server-renderer": "^3.2.20",
- "vue": "^3.2.20"
+ "@vitejs/plugin-vue": "^1.9.4",
+ "@vue/compiler-sfc": "^3.2.22",
+ "@vue/server-renderer": "^3.2.22",
+ "vue": "^3.2.22"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"