perf: tree-shake dependencies from server (#1647)

This commit is contained in:
Daniel Roe 2023-02-06 01:34:50 -08:00 committed by GitHub
parent 357dff2140
commit 6dc38c7d8e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 90 additions and 19 deletions

View file

@ -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,

View file

@ -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)

View file

@ -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 {

View file

@ -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',

View file

@ -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,

View file

@ -16,7 +16,9 @@ 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'), pluginKey: new PluginKey('mention'),
char: '@', char: '@',
async items({ query }) { async items({ query }) {
@ -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)

View file

@ -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
View file

@ -0,0 +1,3 @@
export default class SomeClass {
}

8
mocks/prosemirror.ts Normal file
View 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
View 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 }

View file

@ -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,

View file

@ -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'],