2025-05-11

function ViteSSG(App, routerOptions, fn, options = {}) {
  const {
    transformState,
    registerComponents = true,
    useHead: useHead2 = true,
    rootContainer = "#app"
  } = options;
  const isClient = typeof window !== "undefined";
  async function createApp$1(client = false, routePath) {
    var _a;
    const app = client ? createApp(App) : createSSRApp(App);
    let head;
    if (useHead2) {
      head = createHead();
      app.use(head);
    }
    const router = createRouter(__spreadValues({
      history: client ? createWebHistory(routerOptions.base) : createMemoryHistory(routerOptions.base)
    }, routerOptions));
    const { routes: routes2 } = routerOptions;
    if (registerComponents)
      app.component("ClientOnly", ClientOnly);
    const appRenderCallbacks = [];
    const onSSRAppRendered = client ? () => {
    } : (cb) => appRenderCallbacks.push(cb);
    const triggerOnSSRAppRendered = () => {
      return Promise.all(appRenderCallbacks.map((cb) => cb()));
    };
    const context = {
      app,
      head,
      isClient,
      router,
      routes: routes2,
      onSSRAppRendered,
      triggerOnSSRAppRendered,
      initialState: {},
      transformState,
      routePath
    };
    if (client) {
      await documentReady();
      context.initialState = (transformState == null ? void 0 : transformState(window.__INITIAL_STATE__ || {})) || deserializeState(window.__INITIAL_STATE__);
    }
    await (fn == null ? void 0 : fn(context));
    app.use(router);
    let entryRoutePath;
    let isFirstRoute = true;
    router.beforeEach((to, from, next) => {
      if (isFirstRoute || entryRoutePath && entryRoutePath === to.path) {
        isFirstRoute = false;
        entryRoutePath = to.path;
        to.meta.state = context.initialState;
      }
      next();
    });
    if (!client) {
      const route = (_a = context.routePath) != null ? _a : "/";
      router.push(route);
      await router.isReady();
      context.initialState = router.currentRoute.value.meta.state || {};
    }
    const initialState = context.initialState;
    return __spreadProps(__spreadValues({}, context), {
      initialState
    });
  }
  if (isClient) {
    (async () => {
      const { app, router } = await createApp$1(true);
      await router.isReady();
      app.mount(rootContainer, true);
    })();
  }
  return createApp$1;
}

used to create a server-side generated (SSG) or client-side rendered (CSR) application using Vue.js. It is designed to work with the Vite build tool and provides a streamlined way to handle both server-side and client-side rendering. Below is a breakdown of the function and its components:


Function Overview

ViteSSG is a utility function that simplifies the creation of Vue.js applications with support for server-side generation (SSG) and client-side hydration. It integrates with Vue Router and optionally uses @vueuse/head for managing the document head.


Parameters

  1. App:
    The root Vue component of the application.

  2. routerOptions:
    Configuration options for Vue Router, such as routes and base paths.

  3. fn:
    An optional callback function that allows you to customize the app context during initialization.

  4. options (default: {}):
    Additional configuration options:

    • transformState: A function to transform the initial state (e.g., for serialization/deserialization).
    • registerComponents: Whether to register global components like ClientOnly (default: true).
    • useHead: Whether to use @vueuse/head for managing the document head (default: true).
    • rootContainer: The DOM element where the app will be mounted (default: "#app").

Key Features

  1. Client-Side vs. Server-Side:
    The function detects whether it is running on the client (window is defined) or the server and adjusts the app creation process accordingly.

  2. Vue Router Integration:

    • Uses createWebHistory for client-side navigation.
    • Uses createMemoryHistory for server-side rendering.
  3. State Management:

    • On the client, it retrieves the initial state from window.__INITIAL_STATE__ and optionally transforms it using transformState.
    • On the server, it initializes the state and attaches it to the route's metadata.
  4. Head Management:
    If useHead is enabled, the function integrates @vueuse/head for managing meta tags, titles, and other head elements.

  5. Global Component Registration:
    Registers a ClientOnly component globally if registerComponents is enabled. This is useful for components that should only render on the client.

  6. Lifecycle Hooks:

    • onSSRAppRendered: A hook for performing actions after the server-side app is rendered.
    • triggerOnSSRAppRendered: Triggers all registered onSSRAppRendered callbacks.
  7. Automatic Mounting:
    On the client, the app is automatically mounted to the specified rootContainer after the router is ready.


How It Works

  1. App Creation:
    The createApp$1 function is responsible for creating the Vue app instance. It handles both client-side and server-side scenarios.

  2. Router Setup:
    The router is configured with either createWebHistory (client) or createMemoryHistory (server). Routes are passed via routerOptions.

  3. State Initialization:

    • On the client, the initial state is deserialized from window.__INITIAL_STATE__.
    • On the server, the initial state is attached to the route's metadata.
  4. App Mounting:

    • On the client, the app is mounted to the DOM after the router is ready.
    • On the server, the app is prepared for rendering but not mounted.
  5. Callback Execution:
    The optional fn callback is executed with the app context, allowing for further customization.


Return Value

The function returns the createApp$1 function, which can be used to create the app instance. On the client, it also automatically mounts the app.


Usage Example

Here’s an example of how you might use ViteSSG:

import { ViteSSG } from 'vite-ssg';
import App from './App.vue';
import routes from './routes';

export const createApp = ViteSSG(
  App,
  { routes },
  (context) => {
    // Custom logic during app creation
    console.log('App context:', context);
  },
  {
    transformState: (state) => JSON.parse(state),
    useHead: true,
  }
);

Key Libraries Used

  1. Vue.js:
    Core framework for building the application.

  2. Vue Router:
    Handles routing and navigation.

  3. @vueuse/head:
    Manages the document head (optional).

  4. Vite:
    A fast build tool optimized for modern web development.


Notes

  • The function is designed to work seamlessly with Vite's ecosystem.
  • It provides a unified API for handling both client-side and server-side rendering.
  • The transformState option is particularly useful for serializing/deserializing state when transferring it between the server and client.

This function is ideal for building modern Vue.js applications that require server-side rendering or static site generation.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容