nuxt
Version:
[](https://nuxt.com)
180 lines (179 loc) • 5.69 kB
JavaScript
import { getCurrentInstance, hasInjectionContext, reactive } from "vue";
import { createHooks } from "hookable";
import { getContext } from "unctx";
const nuxtAppCtx = /* @__PURE__ */ getContext("nuxt-app");
export const NuxtPluginIndicator = "__nuxt_plugin";
export function createNuxtApp(options) {
let hydratingCount = 0;
const nuxtApp = {
provide: void 0,
globalName: "nuxt",
versions: {
get nuxt() {
return __NUXT_VERSION__;
},
get vue() {
return nuxtApp.vueApp.version;
}
},
payload: reactive({
data: {},
state: {},
_errors: {},
...process.client ? window.__NUXT__ ?? {} : { serverRendered: true }
}),
static: {
data: {}
},
runWithContext: (fn) => callWithNuxt(nuxtApp, fn),
isHydrating: process.client,
deferHydration() {
if (!nuxtApp.isHydrating) {
return () => {
};
}
hydratingCount++;
let called = false;
return () => {
if (called) {
return;
}
called = true;
hydratingCount--;
if (hydratingCount === 0) {
nuxtApp.isHydrating = false;
return nuxtApp.callHook("app:suspense:resolve");
}
};
},
_asyncDataPromises: {},
_asyncData: {},
_payloadRevivers: {},
...options
};
nuxtApp.hooks = createHooks();
nuxtApp.hook = nuxtApp.hooks.hook;
if (process.server) {
async function contextCaller(hooks, args) {
for (const hook of hooks) {
await nuxtApp.runWithContext(() => hook(...args));
}
}
nuxtApp.hooks.callHook = (name, ...args) => nuxtApp.hooks.callHookWith(contextCaller, name, ...args);
}
nuxtApp.callHook = nuxtApp.hooks.callHook;
nuxtApp.provide = (name, value) => {
const $name = "$" + name;
defineGetter(nuxtApp, $name, value);
defineGetter(nuxtApp.vueApp.config.globalProperties, $name, value);
};
defineGetter(nuxtApp.vueApp, "$nuxt", nuxtApp);
defineGetter(nuxtApp.vueApp.config.globalProperties, "$nuxt", nuxtApp);
if (process.server) {
if (nuxtApp.ssrContext) {
nuxtApp.ssrContext.nuxt = nuxtApp;
nuxtApp.ssrContext._payloadReducers = {};
nuxtApp.payload.path = nuxtApp.ssrContext.url;
}
nuxtApp.ssrContext = nuxtApp.ssrContext || {};
if (nuxtApp.ssrContext.payload) {
Object.assign(nuxtApp.payload, nuxtApp.ssrContext.payload);
}
nuxtApp.ssrContext.payload = nuxtApp.payload;
nuxtApp.ssrContext.config = {
public: options.ssrContext.runtimeConfig.public,
app: options.ssrContext.runtimeConfig.app
};
}
if (process.client) {
window.addEventListener("nuxt.preloadError", (event) => {
nuxtApp.callHook("app:chunkError", { error: event.payload });
});
window.useNuxtApp = window.useNuxtApp || useNuxtApp;
const unreg = nuxtApp.hook("app:error", (...args) => {
console.error("[nuxt] error caught during app initialization", ...args);
});
nuxtApp.hook("app:mounted", unreg);
}
const runtimeConfig = process.server ? options.ssrContext.runtimeConfig : reactive(nuxtApp.payload.config);
nuxtApp.provide("config", runtimeConfig);
return nuxtApp;
}
export async function applyPlugin(nuxtApp, plugin) {
if (plugin.hooks) {
nuxtApp.hooks.addHooks(plugin.hooks);
}
if (typeof plugin === "function") {
const { provide } = await nuxtApp.runWithContext(() => plugin(nuxtApp)) || {};
if (provide && typeof provide === "object") {
for (const key in provide) {
nuxtApp.provide(key, provide[key]);
}
}
}
}
export async function applyPlugins(nuxtApp, plugins) {
const parallels = [];
const errors = [];
for (const plugin of plugins) {
const promise = applyPlugin(nuxtApp, plugin);
if (plugin.parallel) {
parallels.push(promise.catch((e) => errors.push(e)));
} else {
await promise;
}
}
await Promise.all(parallels);
if (errors.length) {
throw errors[0];
}
}
/*! @__NO_SIDE_EFFECTS__ */
export function defineNuxtPlugin(plugin) {
if (typeof plugin === "function") {
return plugin;
}
delete plugin.name;
return Object.assign(plugin.setup || (() => {
}), plugin, { [NuxtPluginIndicator]: true });
}
/*! @__NO_SIDE_EFFECTS__ */
export const definePayloadPlugin = defineNuxtPlugin;
export function isNuxtPlugin(plugin) {
return typeof plugin === "function" && NuxtPluginIndicator in plugin;
}
export function callWithNuxt(nuxt, setup, args) {
const fn = () => args ? setup(...args) : setup();
if (process.server) {
return nuxt.vueApp.runWithContext(() => nuxtAppCtx.callAsync(nuxt, fn));
} else {
nuxtAppCtx.set(nuxt);
return nuxt.vueApp.runWithContext(fn);
}
}
/*! @__NO_SIDE_EFFECTS__ */
export function useNuxtApp() {
let nuxtAppInstance;
if (hasInjectionContext()) {
nuxtAppInstance = getCurrentInstance()?.appContext.app.$nuxt;
}
nuxtAppInstance = nuxtAppInstance || nuxtAppCtx.tryUse();
if (!nuxtAppInstance) {
if (process.dev) {
throw new Error("[nuxt] A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function. This is probably not a Nuxt bug. Find out more at `https://nuxt.com/docs/guide/concepts/auto-imports#using-vue-and-nuxt-composables`.");
} else {
throw new Error("[nuxt] instance unavailable");
}
}
return nuxtAppInstance;
}
/*! @__NO_SIDE_EFFECTS__ */
export function useRuntimeConfig() {
return useNuxtApp().$config;
}
function defineGetter(obj, key, val) {
Object.defineProperty(obj, key, { get: () => val });
}
export function defineAppConfig(config) {
return config;
}