mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-06 02:26:04 +02:00
deps: Update vite to v8 (#17238)
* deps: Update vite to v8 * fix * migrate some plugins to rolldown-based * fix broken lockfile * wip * update rolldown * override rolldown version * perf * spdx * fix * update vite to 8.0.1 * chore: rewrite rollup-plugin-unwind-css-module-class-name with MagicString * format * swap type definitions * replace using MagicString * provided magicString * fix code style * fix * fix * fix * fix * fix --------- Co-authored-by: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com> * fix: lint fixes * swap sass with sass-embedded * fix lint * fix: インライン化されたVue SFC出力に対してCSS Module定義削除が効かないのを修正 * fix * fix: バックエンドのCSS読み込みの方法が悪いのを修正 * fix: 使用されないpreloadを削除 * fix lint [ci skip] * Apply suggestion from @syuilo * Add comment in pnpm-workspace.yaml [ci skip] * update vite/rolldown * remove magic-string --------- Co-authored-by: cm-ayf <cm.ayf2734@gmail.com> Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
This commit is contained in:
@@ -3,15 +3,15 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { parse } from 'acorn';
|
||||
import { generate } from 'astring';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { normalizeClass, unwindCssModuleClassName } from './rollup-plugin-unwind-css-module-class-name.js';
|
||||
import type * as estree from 'estree';
|
||||
import { parseAst } from 'rolldown/parseAst';
|
||||
import type { ESTree } from 'rolldown/utils';
|
||||
import { RolldownMagicString } from 'rolldown';
|
||||
|
||||
function parseExpression(code: string): estree.Expression {
|
||||
const program = parse(code, { ecmaVersion: 'latest', sourceType: 'module' }) as unknown as estree.Program;
|
||||
const statement = program.body[0] as estree.ExpressionStatement;
|
||||
function parseExpression(code: string): ESTree.Expression {
|
||||
const program = parseAst(code, { sourceType: 'module' });
|
||||
const statement = program.body[0] as ESTree.ExpressionStatement;
|
||||
return statement.expression;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ describe(normalizeClass.name, () => {
|
||||
});
|
||||
|
||||
it('Composition API (standard)', () => {
|
||||
const ast = parse(`
|
||||
const code = `
|
||||
import { c as api, d as store, i as i18n, aD as notePage, bN as ImgWithBlurhash, bY as getStaticImageUrl, _ as _export_sfc } from './app-!~{001}~.js';
|
||||
import { M as MkContainer } from './MkContainer-!~{03M}~.js';
|
||||
import { b as defineComponent, a as ref, e as onMounted, z as resolveComponent, g as openBlock, h as createBlock, i as withCtx, K as createTextVNode, E as toDisplayString, u as unref, l as createBaseVNode, q as normalizeClass, B as createCommentVNode, k as createElementBlock, F as Fragment, C as renderList, A as createVNode } from './vue-!~{002}~.js';
|
||||
@@ -170,17 +170,19 @@ const cssModules = {
|
||||
const index_photos = /* @__PURE__ */ _export_sfc(_sfc_main, [["__cssModules", cssModules]]);
|
||||
|
||||
export { index_photos as default };
|
||||
`.slice(1), { ecmaVersion: 'latest', sourceType: 'module' });
|
||||
unwindCssModuleClassName(ast);
|
||||
expect(generate(ast)).toBe(`
|
||||
import {c as api, d as store, i as i18n, aD as notePage, bN as ImgWithBlurhash, bY as getStaticImageUrl, _ as _export_sfc} from './app-!~{001}~.js';
|
||||
import {M as MkContainer} from './MkContainer-!~{03M}~.js';
|
||||
import {b as defineComponent, a as ref, e as onMounted, z as resolveComponent, g as openBlock, h as createBlock, i as withCtx, K as createTextVNode, E as toDisplayString, u as unref, l as createBaseVNode, q as normalizeClass, B as createCommentVNode, k as createElementBlock, F as Fragment, C as renderList, A as createVNode} from './vue-!~{002}~.js';
|
||||
`.slice(1);
|
||||
const ast = parseAst(code, { sourceType: 'module' });
|
||||
const magicString = new RolldownMagicString(code);
|
||||
unwindCssModuleClassName(ast, magicString);
|
||||
expect(magicString.toString()).toBe(
|
||||
`
|
||||
import { c as api, d as store, i as i18n, aD as notePage, bN as ImgWithBlurhash, bY as getStaticImageUrl, _ as _export_sfc } from './app-!~{001}~.js';
|
||||
import { M as MkContainer } from './MkContainer-!~{03M}~.js';
|
||||
import { b as defineComponent, a as ref, e as onMounted, z as resolveComponent, g as openBlock, h as createBlock, i as withCtx, K as createTextVNode, E as toDisplayString, u as unref, l as createBaseVNode, q as normalizeClass, B as createCommentVNode, k as createElementBlock, F as Fragment, C as renderList, A as createVNode } from './vue-!~{002}~.js';
|
||||
import './photoswipe-!~{003}~.js';
|
||||
const _hoisted_1 = createBaseVNode("i", {
|
||||
class: "ti ti-photo"
|
||||
}, null, -1);
|
||||
const index_photos = defineComponent({
|
||||
|
||||
const _hoisted_1 = /* @__PURE__ */ createBaseVNode("i", { class: "ti ti-photo" }, null, -1);
|
||||
const index_photos = /* @__PURE__ */ defineComponent({
|
||||
__name: "index.photos",
|
||||
props: {
|
||||
user: {}
|
||||
@@ -193,12 +195,20 @@ const index_photos = defineComponent({
|
||||
return store.s.disableShowingAnimatedImages ? getStaticImageUrl(image.url) : image.thumbnailUrl;
|
||||
}
|
||||
onMounted(() => {
|
||||
const image = ["image/jpeg", "image/webp", "image/avif", "image/png", "image/gif", "image/apng", "image/vnd.mozilla.apng"];
|
||||
const image = [
|
||||
"image/jpeg",
|
||||
"image/webp",
|
||||
"image/avif",
|
||||
"image/png",
|
||||
"image/gif",
|
||||
"image/apng",
|
||||
"image/vnd.mozilla.apng"
|
||||
];
|
||||
api("users/notes", {
|
||||
userId: props.user.id,
|
||||
fileType: image,
|
||||
limit: 10
|
||||
}).then(notes => {
|
||||
}).then((notes) => {
|
||||
for (const note of notes) {
|
||||
for (const file of note.files) {
|
||||
images.value.push({
|
||||
@@ -213,60 +223,77 @@ const index_photos = defineComponent({
|
||||
return (_ctx, _cache) => {
|
||||
const _component_MkLoading = resolveComponent("MkLoading");
|
||||
const _component_MkA = resolveComponent("MkA");
|
||||
return (openBlock(), createBlock(MkContainer, {
|
||||
return openBlock(), createBlock(MkContainer, {
|
||||
"max-height": 300,
|
||||
foldable: true
|
||||
}, {
|
||||
icon: withCtx(() => [_hoisted_1]),
|
||||
header: withCtx(() => [createTextVNode(toDisplayString(unref(i18n).ts.images), 1)]),
|
||||
default: withCtx(() => [createBaseVNode("div", {
|
||||
class: "xenMW"
|
||||
}, [unref(fetching) ? (openBlock(), createBlock(_component_MkLoading, {
|
||||
key: 0
|
||||
})) : createCommentVNode("", true), !unref(fetching) && unref(images).length > 0 ? (openBlock(), createElementBlock("div", {
|
||||
key: 1,
|
||||
class: "xaZzf"
|
||||
}, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(images), image => {
|
||||
return (openBlock(), createBlock(_component_MkA, {
|
||||
key: image.note.id + image.file.id,
|
||||
class: "xtA8t",
|
||||
to: unref(notePage)(image.note)
|
||||
}, {
|
||||
default: withCtx(() => [createVNode(ImgWithBlurhash, {
|
||||
hash: image.file.blurhash,
|
||||
src: thumbnail(image.file),
|
||||
title: image.file.name
|
||||
}, null, 8, ["hash", "src", "title"])]),
|
||||
_: 2
|
||||
}, 1032, ["class", "to"]));
|
||||
}), 128))], 2)) : createCommentVNode("", true), !unref(fetching) && unref(images).length == 0 ? (openBlock(), createElementBlock("p", {
|
||||
key: 2,
|
||||
class: "xhYKj"
|
||||
}, toDisplayString(unref(i18n).ts.nothing), 3)) : createCommentVNode("", true)], 2)]),
|
||||
icon: withCtx(() => [
|
||||
_hoisted_1
|
||||
]),
|
||||
header: withCtx(() => [
|
||||
createTextVNode(toDisplayString(unref(i18n).ts.images), 1)
|
||||
]),
|
||||
default: withCtx(() => [
|
||||
createBaseVNode("div", {
|
||||
class: "xenMW"
|
||||
}, [
|
||||
unref(fetching) ? (openBlock(), createBlock(_component_MkLoading, { key: 0 })) : createCommentVNode("", true),
|
||||
!unref(fetching) && unref(images).length > 0 ? (openBlock(), createElementBlock("div", {
|
||||
key: 1,
|
||||
class: "xaZzf"
|
||||
}, [
|
||||
(openBlock(true), createElementBlock(Fragment, null, renderList(unref(images), (image) => {
|
||||
return openBlock(), createBlock(_component_MkA, {
|
||||
key: image.note.id + image.file.id,
|
||||
class: "xtA8t",
|
||||
to: unref(notePage)(image.note)
|
||||
}, {
|
||||
default: withCtx(() => [
|
||||
createVNode(ImgWithBlurhash, {
|
||||
hash: image.file.blurhash,
|
||||
src: thumbnail(image.file),
|
||||
title: image.file.name
|
||||
}, null, 8, ["hash", "src", "title"])
|
||||
]),
|
||||
_: 2
|
||||
}, 1032, ["class", "to"]);
|
||||
}), 128))
|
||||
], 2)) : createCommentVNode("", true),
|
||||
!unref(fetching) && unref(images).length == 0 ? (openBlock(), createElementBlock("p", {
|
||||
key: 2,
|
||||
class: "xhYKj"
|
||||
}, toDisplayString(unref(i18n).ts.nothing), 3)) : createCommentVNode("", true)
|
||||
], 2)
|
||||
]),
|
||||
_: 1
|
||||
}));
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const root = "xenMW";
|
||||
const stream = "xaZzf";
|
||||
const img = "xtA8t";
|
||||
const empty = "xhYKj";
|
||||
const style0 = {
|
||||
root: root,
|
||||
stream: stream,
|
||||
img: img,
|
||||
empty: empty
|
||||
root: root,
|
||||
stream: stream,
|
||||
img: img,
|
||||
empty: empty
|
||||
};
|
||||
|
||||
const cssModules = {
|
||||
"$style": style0
|
||||
};
|
||||
export {index_photos as default};
|
||||
`.slice(1));
|
||||
|
||||
|
||||
export { index_photos as default };
|
||||
`.slice(1),
|
||||
);
|
||||
});
|
||||
|
||||
it('Composition API (with `useCssModule()`)', () => {
|
||||
const ast = parse(`
|
||||
const code = `
|
||||
import { a7 as getCurrentInstance, b as defineComponent, G as useCssModule, a1 as h, H as TransitionGroup } from './!~{002}~.js';
|
||||
import { d as store, aK as toast, b5 as MkAd, i as i18n, _ as _export_sfc } from './app-!~{001}~.js';
|
||||
|
||||
@@ -437,11 +464,15 @@ const cssModules = {
|
||||
const MkDateSeparatedList = /* @__PURE__ */ _export_sfc(_sfc_main, [["__cssModules", cssModules]]);
|
||||
|
||||
export { MkDateSeparatedList as M };
|
||||
`.slice(1), { ecmaVersion: 'latest', sourceType: 'module' });
|
||||
unwindCssModuleClassName(ast);
|
||||
expect(generate(ast)).toBe(`
|
||||
import {a7 as getCurrentInstance, b as defineComponent, G as useCssModule, a1 as h, H as TransitionGroup} from './!~{002}~.js';
|
||||
import {d as store, aK as toast, b5 as MkAd, i as i18n, _ as _export_sfc} from './app-!~{001}~.js';
|
||||
`.slice(1);
|
||||
const ast = parseAst(code, { sourceType: 'module' });
|
||||
const magicString = new RolldownMagicString(code);
|
||||
unwindCssModuleClassName(ast, magicString);
|
||||
expect(magicString.toString()).toBe(
|
||||
`
|
||||
import { a7 as getCurrentInstance, b as defineComponent, G as useCssModule, a1 as h, H as TransitionGroup } from './!~{002}~.js';
|
||||
import { d as store, aK as toast, b5 as MkAd, i as i18n, _ as _export_sfc } from './app-!~{001}~.js';
|
||||
|
||||
function isDebuggerEnabled(id) {
|
||||
try {
|
||||
return localStorage.getItem(\`DEBUG_\${id}\`) !== null;
|
||||
@@ -458,6 +489,7 @@ function stackTraceInstances() {
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
const _sfc_main = defineComponent({
|
||||
props: {
|
||||
items: {
|
||||
@@ -485,7 +517,7 @@ const _sfc_main = defineComponent({
|
||||
default: false
|
||||
}
|
||||
},
|
||||
setup(props, {slots, expose}) {
|
||||
setup(props, { slots, expose }) {
|
||||
const $style = useCssModule();
|
||||
function getDateText(time) {
|
||||
const date = new Date(time).getDate();
|
||||
@@ -495,28 +527,40 @@ const _sfc_main = defineComponent({
|
||||
day: date.toString()
|
||||
});
|
||||
}
|
||||
if (props.items.length === 0) return;
|
||||
if (props.items.length === 0)
|
||||
return;
|
||||
const renderChildrenImpl = () => props.items.map((item, i) => {
|
||||
if (!slots || !slots.default) return;
|
||||
if (!slots || !slots.default)
|
||||
return;
|
||||
const el = slots.default({
|
||||
item
|
||||
})[0];
|
||||
if (el.key == null && item.id) el.key = item.id;
|
||||
if (el.key == null && item.id)
|
||||
el.key = item.id;
|
||||
if (i !== props.items.length - 1 && new Date(item.createdAt).getDate() !== new Date(props.items[i + 1].createdAt).getDate()) {
|
||||
const separator = h("div", {
|
||||
class: $style["separator"],
|
||||
key: item.id + ":separator"
|
||||
}, h("p", {
|
||||
class: $style["date"]
|
||||
}, [h("span", {
|
||||
class: $style["date-1"]
|
||||
}, [h("i", {
|
||||
class: \`ti ti-chevron-up \${$style["date-1-icon"]}\`
|
||||
}), getDateText(item.createdAt)]), h("span", {
|
||||
class: $style["date-2"]
|
||||
}, [getDateText(props.items[i + 1].createdAt), h("i", {
|
||||
class: \`ti ti-chevron-down \${$style["date-2-icon"]}\`
|
||||
})])]));
|
||||
}, [
|
||||
h("span", {
|
||||
class: $style["date-1"]
|
||||
}, [
|
||||
h("i", {
|
||||
class: \`ti ti-chevron-up \${$style["date-1-icon"]}\`
|
||||
}),
|
||||
getDateText(item.createdAt)
|
||||
]),
|
||||
h("span", {
|
||||
class: $style["date-2"]
|
||||
}, [
|
||||
getDateText(props.items[i + 1].createdAt),
|
||||
h("i", {
|
||||
class: \`ti ti-chevron-down \${$style["date-2-icon"]}\`
|
||||
})
|
||||
])
|
||||
]));
|
||||
return [el, separator];
|
||||
} else {
|
||||
if (props.ad && item._shouldInsertAd_) {
|
||||
@@ -532,17 +576,13 @@ const _sfc_main = defineComponent({
|
||||
const renderChildren = () => {
|
||||
const children = renderChildrenImpl();
|
||||
if (isDebuggerEnabled(6864)) {
|
||||
const nodes = children.flatMap(node => node ?? []);
|
||||
const keys = new Set(nodes.map(node => node.key));
|
||||
const nodes = children.flatMap((node) => node ?? []);
|
||||
const keys = new Set(nodes.map((node) => node.key));
|
||||
if (keys.size !== nodes.length) {
|
||||
const id = crypto.randomUUID();
|
||||
const instances = stackTraceInstances();
|
||||
toast(instances.reduce((a, c) => \`\${a} at \${c.type.name}\`, \`[DEBUG_6864 (\${id})]: \${nodes.length - keys.size} duplicated keys found\`));
|
||||
console.warn({
|
||||
id,
|
||||
debugId: 6864,
|
||||
stack: instances
|
||||
});
|
||||
console.warn({ id, debugId: 6864, stack: instances });
|
||||
}
|
||||
}
|
||||
return children;
|
||||
@@ -555,45 +595,136 @@ const _sfc_main = defineComponent({
|
||||
el.style.top = "";
|
||||
el.style.left = "";
|
||||
}
|
||||
return () => h(prefer.s.animation ? TransitionGroup : "div", {
|
||||
class: {
|
||||
[$style["date-separated-list"]]: true,
|
||||
[$style["date-separated-list-nogap"]]: props.noGap,
|
||||
[$style["reversed"]]: props.reversed,
|
||||
[$style["direction-down"]]: props.direction === "down",
|
||||
[$style["direction-up"]]: props.direction === "up"
|
||||
return () => h(
|
||||
prefer.s.animation ? TransitionGroup : "div",
|
||||
{
|
||||
class: {
|
||||
[$style["date-separated-list"]]: true,
|
||||
[$style["date-separated-list-nogap"]]: props.noGap,
|
||||
[$style["reversed"]]: props.reversed,
|
||||
[$style["direction-down"]]: props.direction === "down",
|
||||
[$style["direction-up"]]: props.direction === "up"
|
||||
},
|
||||
...prefer.s.animation ? {
|
||||
name: "list",
|
||||
tag: "div",
|
||||
onBeforeLeave,
|
||||
onLeaveCanceled
|
||||
} : {}
|
||||
},
|
||||
...prefer.s.animation ? {
|
||||
name: "list",
|
||||
tag: "div",
|
||||
onBeforeLeave,
|
||||
onLeaveCanceled
|
||||
} : {}
|
||||
}, {
|
||||
default: renderChildren
|
||||
});
|
||||
{ default: renderChildren }
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const reversed = "xxiZh";
|
||||
const separator = "xxeDx";
|
||||
const date = "xxawD";
|
||||
const style0 = {
|
||||
"date-separated-list": "xfKPa",
|
||||
"date-separated-list-nogap": "xf9zr",
|
||||
"direction-up": "x7AeO",
|
||||
"direction-down": "xBIqc",
|
||||
reversed: reversed,
|
||||
separator: separator,
|
||||
date: date,
|
||||
"date-1": "xwtmh",
|
||||
"date-1-icon": "xsNPa",
|
||||
"date-2": "x1xvw",
|
||||
"date-2-icon": "x9ZiG"
|
||||
"date-separated-list": "xfKPa",
|
||||
"date-separated-list-nogap": "xf9zr",
|
||||
"direction-up": "x7AeO",
|
||||
"direction-down": "xBIqc",
|
||||
reversed: reversed,
|
||||
separator: separator,
|
||||
date: date,
|
||||
"date-1": "xwtmh",
|
||||
"date-1-icon": "xsNPa",
|
||||
"date-2": "x1xvw",
|
||||
"date-2-icon": "x9ZiG"
|
||||
};
|
||||
|
||||
const cssModules = {
|
||||
"$style": style0
|
||||
};
|
||||
const MkDateSeparatedList = _export_sfc(_sfc_main, [["__cssModules", cssModules]]);
|
||||
export {MkDateSeparatedList as M};
|
||||
const MkDateSeparatedList = /* @__PURE__ */ _export_sfc(_sfc_main, [["__cssModules", cssModules]]);
|
||||
|
||||
export { MkDateSeparatedList as M };
|
||||
`.slice(1));
|
||||
});
|
||||
|
||||
it('Composition API (inlined output)', () => {
|
||||
const code = `
|
||||
import { a as normalizeClass, b as defineComponent, c as _export_sfc } from './runtime.js';
|
||||
|
||||
const CurrentComponent = /* @__PURE__ */ _export_sfc(defineComponent({
|
||||
__name: "CurrentComponent",
|
||||
setup() {
|
||||
return (e, n) => h("div", {
|
||||
class: normalizeClass([e.$style.root, "extra"])
|
||||
}, null, 2);
|
||||
}
|
||||
}), [["__cssModules", {
|
||||
"$style": {
|
||||
root: "x1234"
|
||||
}
|
||||
}]]);
|
||||
|
||||
export { CurrentComponent as default };
|
||||
`.slice(1);
|
||||
const ast = parseAst(code, { sourceType: 'module' });
|
||||
const magicString = new RolldownMagicString(code);
|
||||
unwindCssModuleClassName(ast, magicString);
|
||||
const output = magicString.toString();
|
||||
expect(output).toContain('class: "x1234 extra"');
|
||||
expect(output).toContain('defineComponent({');
|
||||
expect(output).toContain('}), []);');
|
||||
expect(output).not.toContain('$style');
|
||||
});
|
||||
|
||||
it('should keep cssModules when unresolved references remain', () => {
|
||||
const code = `
|
||||
import { a as normalizeClass, b as defineComponent, c as _export_sfc } from './runtime.js';
|
||||
|
||||
const CurrentComponent = /* @__PURE__ */ _export_sfc(defineComponent({
|
||||
__name: "CurrentComponent",
|
||||
setup() {
|
||||
return (e, n) => h("div", {
|
||||
class: normalizeClass([e.$style.root, e.$style[side]])
|
||||
}, null, 2);
|
||||
}
|
||||
}), [["__cssModules", {
|
||||
"$style": {
|
||||
root: "x1234"
|
||||
}
|
||||
}]]);
|
||||
|
||||
export { CurrentComponent as default };
|
||||
`.slice(1);
|
||||
const ast = parseAst(code, { sourceType: 'module' });
|
||||
const magicString = new RolldownMagicString(code);
|
||||
unwindCssModuleClassName(ast, magicString);
|
||||
const output = magicString.toString();
|
||||
expect(output).toContain('e.$style[side]');
|
||||
expect(output).toContain('__cssModules');
|
||||
expect(output).not.toContain('}), []);');
|
||||
});
|
||||
|
||||
it('should inline cssModules references used inside class expressions', () => {
|
||||
const code = `
|
||||
import { a as classHelper, b as defineComponent, c as _export_sfc } from './runtime.js';
|
||||
|
||||
const CurrentComponent = /* @__PURE__ */ _export_sfc(defineComponent({
|
||||
__name: "CurrentComponent",
|
||||
setup() {
|
||||
return (e, n) => h("div", {
|
||||
class: classHelper([e.$style.root, { [e.$style.main]: isActive }])
|
||||
}, null, 2);
|
||||
}
|
||||
}), [["__cssModules", {
|
||||
"$style": {
|
||||
root: "x1234",
|
||||
main: "x5678"
|
||||
}
|
||||
}]]);
|
||||
|
||||
export { CurrentComponent as default };
|
||||
`.slice(1);
|
||||
const ast = parseAst(code, { sourceType: 'module' });
|
||||
const magicString = new RolldownMagicString(code);
|
||||
unwindCssModuleClassName(ast, magicString);
|
||||
const output = magicString.toString();
|
||||
expect(output).toContain('class: classHelper(["x1234", { ["x5678"]: isActive }])');
|
||||
expect(output).toContain('}), []);');
|
||||
expect(output).not.toContain('$style');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user