perf: tree-shake dependencies from server (#1647)
This commit is contained in:
parent
357dff2140
commit
6dc38c7d8e
@ -35,6 +35,8 @@ const previewImage = ref('')
|
|||||||
const imageSrc = computed<string>(() => previewImage.value || defaultImage.value)
|
const imageSrc = computed<string>(() => previewImage.value || defaultImage.value)
|
||||||
|
|
||||||
const pickImage = async () => {
|
const pickImage = async () => {
|
||||||
|
if (process.server)
|
||||||
|
return
|
||||||
const image = await fileOpen({
|
const image = await fileOpen({
|
||||||
description: 'Image',
|
description: 'Image',
|
||||||
mimeTypes: props.allowedFileTypes,
|
mimeTypes: props.allowedFileTypes,
|
||||||
|
@ -21,7 +21,7 @@ const { modelValue } = defineModel<{
|
|||||||
const target = ref()
|
const target = ref()
|
||||||
|
|
||||||
const animateTimeout = useTimeout(10)
|
const animateTimeout = useTimeout(10)
|
||||||
const reduceMotion = useReducedMotion()
|
const reduceMotion = process.server ? ref(false) : useReducedMotion()
|
||||||
|
|
||||||
const canAnimate = computed(() => !reduceMotion.value && animateTimeout.value)
|
const canAnimate = computed(() => !reduceMotion.value && animateTimeout.value)
|
||||||
|
|
||||||
|
@ -12,6 +12,9 @@ const { items, command } = defineProps<{
|
|||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emojis = computed(() => {
|
const emojis = computed(() => {
|
||||||
|
if (process.server)
|
||||||
|
return []
|
||||||
|
|
||||||
return items.map((item: CustomEmoji | Emoji) => {
|
return items.map((item: CustomEmoji | Emoji) => {
|
||||||
if (isCustomEmoji(item)) {
|
if (isCustomEmoji(item)) {
|
||||||
return {
|
return {
|
||||||
|
@ -150,6 +150,8 @@ export function useUploadMediaAttachment(draftRef: Ref<Draft>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function pickAttachments() {
|
async function pickAttachments() {
|
||||||
|
if (process.server)
|
||||||
|
return
|
||||||
const mimeTypes = currentInstance.value!.configuration?.mediaAttachments.supportedMimeTypes
|
const mimeTypes = currentInstance.value!.configuration?.mediaAttachments.supportedMimeTypes
|
||||||
const files = await fileOpen({
|
const files = await fileOpen({
|
||||||
description: 'Attachments',
|
description: 'Attachments',
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { Editor } from '@tiptap/vue-3'
|
||||||
import { Extension, useEditor } from '@tiptap/vue-3'
|
import { Extension, useEditor } from '@tiptap/vue-3'
|
||||||
import Placeholder from '@tiptap/extension-placeholder'
|
import Placeholder from '@tiptap/extension-placeholder'
|
||||||
import Document from '@tiptap/extension-document'
|
import Document from '@tiptap/extension-document'
|
||||||
@ -27,6 +28,9 @@ export interface UseTiptapOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function useTiptap(options: UseTiptapOptions) {
|
export function useTiptap(options: UseTiptapOptions) {
|
||||||
|
if (process.server)
|
||||||
|
return { editor: ref<Editor | undefined>() }
|
||||||
|
|
||||||
const {
|
const {
|
||||||
autofocus,
|
autofocus,
|
||||||
content,
|
content,
|
||||||
|
@ -16,18 +16,20 @@ export { Emoji }
|
|||||||
export type CustomEmoji = (mastodon.v1.CustomEmoji & { custom: true })
|
export type CustomEmoji = (mastodon.v1.CustomEmoji & { custom: true })
|
||||||
export const isCustomEmoji = (emoji: CustomEmoji | Emoji): emoji is CustomEmoji => !!(emoji as CustomEmoji).custom
|
export const isCustomEmoji = (emoji: CustomEmoji | Emoji): emoji is CustomEmoji => !!(emoji as CustomEmoji).custom
|
||||||
|
|
||||||
export const TiptapMentionSuggestion: Partial<SuggestionOptions> = {
|
export const TiptapMentionSuggestion: Partial<SuggestionOptions> = process.server
|
||||||
pluginKey: new PluginKey('mention'),
|
? {}
|
||||||
char: '@',
|
: {
|
||||||
async items({ query }) {
|
pluginKey: new PluginKey('mention'),
|
||||||
if (query.length === 0)
|
char: '@',
|
||||||
return []
|
async items({ query }) {
|
||||||
|
if (query.length === 0)
|
||||||
|
return []
|
||||||
|
|
||||||
const results = await useMastoClient().v2.search({ q: query, type: 'accounts', limit: 25, resolve: true })
|
const results = await useMastoClient().v2.search({ q: query, type: 'accounts', limit: 25, resolve: true })
|
||||||
return results.accounts
|
return results.accounts
|
||||||
},
|
},
|
||||||
render: createSuggestionRenderer(TiptapMentionList),
|
render: createSuggestionRenderer(TiptapMentionList),
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TiptapHashtagSuggestion: Partial<SuggestionOptions> = {
|
export const TiptapHashtagSuggestion: Partial<SuggestionOptions> = {
|
||||||
pluginKey: new PluginKey('hashtag'),
|
pluginKey: new PluginKey('hashtag'),
|
||||||
@ -52,7 +54,7 @@ export const TiptapEmojiSuggestion: Partial<SuggestionOptions> = {
|
|||||||
pluginKey: new PluginKey('emoji'),
|
pluginKey: new PluginKey('emoji'),
|
||||||
char: ':',
|
char: ':',
|
||||||
async items({ query }): Promise<(CustomEmoji | Emoji)[]> {
|
async items({ query }): Promise<(CustomEmoji | Emoji)[]> {
|
||||||
if (query.length === 0)
|
if (process.server || query.length === 0)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if (currentCustomEmojis.value.emojis.length === 0)
|
if (currentCustomEmojis.value.emojis.length === 0)
|
||||||
|
@ -19,7 +19,7 @@ import { useAsyncIDBKeyval } from '~/composables/idb'
|
|||||||
|
|
||||||
const mock = process.mock
|
const mock = process.mock
|
||||||
|
|
||||||
const initializeUsers = async (): Promise<Ref<UserLogin[]> | RemovableRef<UserLogin[]>> => {
|
const initializeUsers = (): Promise<Ref<UserLogin[]> | RemovableRef<UserLogin[]>> | Ref<UserLogin[]> | RemovableRef<UserLogin[]> => {
|
||||||
let defaultUsers = mock ? [mock.user] : []
|
let defaultUsers = mock ? [mock.user] : []
|
||||||
|
|
||||||
// Backward compatibility with localStorage
|
// Backward compatibility with localStorage
|
||||||
@ -34,7 +34,7 @@ const initializeUsers = async (): Promise<Ref<UserLogin[]> | RemovableRef<UserLo
|
|||||||
|
|
||||||
const users = process.server
|
const users = process.server
|
||||||
? ref<UserLogin[]>(defaultUsers)
|
? ref<UserLogin[]>(defaultUsers)
|
||||||
: await useAsyncIDBKeyval<UserLogin[]>(STORAGE_KEY_USERS, defaultUsers, { deep: true })
|
: useAsyncIDBKeyval<UserLogin[]>(STORAGE_KEY_USERS, defaultUsers, { deep: true })
|
||||||
|
|
||||||
if (removeUsersOnLocalStorage)
|
if (removeUsersOnLocalStorage)
|
||||||
globalThis.localStorage.removeItem(STORAGE_KEY_USERS)
|
globalThis.localStorage.removeItem(STORAGE_KEY_USERS)
|
||||||
@ -42,7 +42,7 @@ const initializeUsers = async (): Promise<Ref<UserLogin[]> | RemovableRef<UserLo
|
|||||||
return users
|
return users
|
||||||
}
|
}
|
||||||
|
|
||||||
const users = await initializeUsers()
|
const users = process.server ? initializeUsers() as Ref<UserLogin[]> | RemovableRef<UserLogin[]> : await initializeUsers()
|
||||||
const nodes = useLocalStorage<Record<string, any>>(STORAGE_KEY_NODES, {}, { deep: true })
|
const nodes = useLocalStorage<Record<string, any>>(STORAGE_KEY_NODES, {}, { deep: true })
|
||||||
const currentUserHandle = useLocalStorage<string>(STORAGE_KEY_CURRENT_USER_HANDLE, mock ? mock.user.account.id : '')
|
const currentUserHandle = useLocalStorage<string>(STORAGE_KEY_CURRENT_USER_HANDLE, mock ? mock.user.account.id : '')
|
||||||
export const instanceStorage = useLocalStorage<Record<string, mastodon.v1.Instance>>(STORAGE_KEY_SERVERS, mock ? mock.server : {}, { deep: true })
|
export const instanceStorage = useLocalStorage<Record<string, mastodon.v1.Instance>>(STORAGE_KEY_SERVERS, mock ? mock.server : {}, { deep: true })
|
||||||
|
3
mocks/class.ts
Normal file
3
mocks/class.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default class SomeClass {
|
||||||
|
|
||||||
|
}
|
8
mocks/prosemirror.ts
Normal file
8
mocks/prosemirror.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import proxy from 'unenv/runtime/mock/proxy'
|
||||||
|
|
||||||
|
export const Plugin = proxy
|
||||||
|
export const PluginKey = proxy
|
||||||
|
export const Decoration = proxy
|
||||||
|
export const DecorationSet = proxy
|
||||||
|
|
||||||
|
export { proxy as default }
|
17
mocks/tiptap.ts
Normal file
17
mocks/tiptap.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import proxy from 'unenv/runtime/mock/proxy'
|
||||||
|
|
||||||
|
export const Extension = proxy
|
||||||
|
export const useEditor = proxy
|
||||||
|
export const EditorContent = proxy
|
||||||
|
export const NodeViewContent = proxy
|
||||||
|
export const NodeViewWrapper = proxy
|
||||||
|
export const nodeViewProps = proxy
|
||||||
|
export const Node = proxy
|
||||||
|
export const mergeAttributes = proxy
|
||||||
|
export const nodeInputRule = proxy
|
||||||
|
export const nodePasteRule = proxy
|
||||||
|
export const VueNodeViewRenderer = proxy
|
||||||
|
export const findChildren = proxy
|
||||||
|
export const VueRenderer = proxy
|
||||||
|
|
||||||
|
export { proxy as default }
|
@ -128,10 +128,10 @@ export default defineNuxtConfig({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
build: {
|
|
||||||
transpile: ['masto'],
|
|
||||||
},
|
|
||||||
nitro: {
|
nitro: {
|
||||||
|
alias: {
|
||||||
|
'isomorphic-ws': 'unenv/runtime/mock/proxy',
|
||||||
|
},
|
||||||
esbuild: {
|
esbuild: {
|
||||||
options: {
|
options: {
|
||||||
target: 'esnext',
|
target: 'esnext',
|
||||||
@ -143,12 +143,37 @@ export default defineNuxtConfig({
|
|||||||
ignore: ['/settings'],
|
ignore: ['/settings'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
sourcemap: !isDevelopment,
|
||||||
hooks: {
|
hooks: {
|
||||||
'nitro:config': function (config) {
|
'nitro:config': function (config) {
|
||||||
const nuxt = useNuxt()
|
const nuxt = useNuxt()
|
||||||
config.virtual = config.virtual || {}
|
config.virtual = config.virtual || {}
|
||||||
config.virtual['#storage-config'] = `export const driver = ${JSON.stringify(nuxt.options.appConfig.storage.driver)}`
|
config.virtual['#storage-config'] = `export const driver = ${JSON.stringify(nuxt.options.appConfig.storage.driver)}`
|
||||||
},
|
},
|
||||||
|
'vite:extendConfig': function (config, { isServer }) {
|
||||||
|
if (isServer) {
|
||||||
|
const alias = config.resolve!.alias as Record<string, string>
|
||||||
|
for (const dep of ['eventemitter3', 'isomorphic-ws'])
|
||||||
|
alias[dep] = resolve('./mocks/class')
|
||||||
|
for (const dep of ['shiki-es', 'fuse.js'])
|
||||||
|
alias[dep] = 'unenv/runtime/mock/proxy'
|
||||||
|
const resolver = createResolver(import.meta.url)
|
||||||
|
|
||||||
|
config.plugins!.unshift({
|
||||||
|
name: 'mock',
|
||||||
|
enforce: 'pre',
|
||||||
|
resolveId(id) {
|
||||||
|
if (id.match(/(^|\/)(@tiptap)\//))
|
||||||
|
return resolver.resolve('./mocks/tiptap.ts')
|
||||||
|
if (id.match(/(^|\/)(prosemirror)/))
|
||||||
|
return resolver.resolve('./mocks/prosemirror.ts')
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const noExternal = config.ssr!.noExternal as string[]
|
||||||
|
noExternal.push('masto', '@fnando/sparkline', 'vue-i18n', '@mastojs/ponyfills')
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
app: {
|
app: {
|
||||||
keepalive: true,
|
keepalive: true,
|
||||||
|
@ -12,6 +12,9 @@ useHeadFixed({
|
|||||||
const loggedInUsers = useUsers()
|
const loggedInUsers = useUsers()
|
||||||
|
|
||||||
async function exportTokens() {
|
async function exportTokens() {
|
||||||
|
if (process.server)
|
||||||
|
return
|
||||||
|
|
||||||
if (!confirm('Please aware that the tokens represent the **full access** to your accounts, and should be treated as sensitive information. Are you sure you want to export the tokens?'))
|
if (!confirm('Please aware that the tokens represent the **full access** to your accounts, and should be treated as sensitive information. Are you sure you want to export the tokens?'))
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -28,6 +31,8 @@ async function exportTokens() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function importTokens() {
|
async function importTokens() {
|
||||||
|
if (process.server)
|
||||||
|
return
|
||||||
const file = await fileOpen({
|
const file = await fileOpen({
|
||||||
description: 'Token File',
|
description: 'Token File',
|
||||||
mimeTypes: ['application/json'],
|
mimeTypes: ['application/json'],
|
||||||
|
Loading…
Reference in New Issue
Block a user