From e45a780714c1ba44807ba6dbce3f2b5209ec0339 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Fri, 25 Feb 2022 12:42:34 +0000 Subject: [PATCH] fix(vite,webpack): disable async entrypoint by default (#3375) * fix(vite): don't use async entry * fix: use async entry when built * refactor: default to sync entry, with option to enable async * refactor: move to experimental.asyncEntry * Update packages/webpack/src/presets/base.ts Co-authored-by: pooya parsa * Update packages/vite/src/vite.ts Co-authored-by: pooya parsa * style: remove double space Co-authored-by: pooya parsa --- packages/nuxt3/src/app/bootstrap.ts | 66 --------------------- packages/nuxt3/src/app/entry.async.ts | 11 ++++ packages/nuxt3/src/app/entry.ts | 69 +++++++++++++++++++--- packages/schema/src/config/build.ts | 1 + packages/schema/src/config/experimental.ts | 7 +++ packages/schema/src/config/index.ts | 2 + packages/vite/src/vite.ts | 2 +- packages/webpack/src/presets/base.ts | 2 +- 8 files changed, 85 insertions(+), 75 deletions(-) delete mode 100644 packages/nuxt3/src/app/bootstrap.ts create mode 100644 packages/nuxt3/src/app/entry.async.ts create mode 100644 packages/schema/src/config/experimental.ts diff --git a/packages/nuxt3/src/app/bootstrap.ts b/packages/nuxt3/src/app/bootstrap.ts deleted file mode 100644 index 03cfd67e23..0000000000 --- a/packages/nuxt3/src/app/bootstrap.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { createSSRApp, createApp, nextTick } from 'vue' -import { createNuxtApp, applyPlugins, normalizePlugins, CreateOptions } from '#app' -import '#build/css' -// @ts-ignore -import _plugins from '#build/plugins' -// @ts-ignore -import RootComponent from '#build/root-component.mjs' -// @ts-ignore -import AppComponent from '#build/app-component.mjs' - -let entry: Function - -const plugins = normalizePlugins(_plugins) - -if (process.server) { - entry = async function createNuxtAppServer (ssrContext: CreateOptions['ssrContext'] = {}) { - const vueApp = createApp(RootComponent) - vueApp.component('App', AppComponent) - - const nuxt = createNuxtApp({ vueApp, ssrContext }) - - await applyPlugins(nuxt, plugins) - - await nuxt.hooks.callHook('app:created', vueApp) - - return vueApp - } -} - -if (process.client) { - // TODO: temporary webpack 5 HMR fix - // https://github.com/webpack-contrib/webpack-hot-middleware/issues/390 - // @ts-ignore - if (process.dev && import.meta.webpackHot) { - // @ts-ignore - import.meta.webpackHot.accept() - } - - entry = async function initApp () { - const isSSR = Boolean(window.__NUXT__?.serverRendered) - const vueApp = isSSR ? createSSRApp(RootComponent) : createApp(RootComponent) - vueApp.component('App', AppComponent) - - const nuxt = createNuxtApp({ vueApp }) - - await applyPlugins(nuxt, plugins) - - await nuxt.hooks.callHook('app:created', vueApp) - await nuxt.hooks.callHook('app:beforeMount', vueApp) - - nuxt.hooks.hookOnce('app:suspense:resolve', () => { - nuxt.isHydrating = false - }) - - vueApp.mount('#__nuxt') - - await nuxt.hooks.callHook('app:mounted', vueApp) - await nextTick() - } - - entry().catch((error) => { - console.error('Error while mounting app:', error) // eslint-disable-line no-console - }) -} - -export default (ctx?: CreateOptions['ssrContext']) => entry(ctx) diff --git a/packages/nuxt3/src/app/entry.async.ts b/packages/nuxt3/src/app/entry.async.ts new file mode 100644 index 0000000000..e4040d92e5 --- /dev/null +++ b/packages/nuxt3/src/app/entry.async.ts @@ -0,0 +1,11 @@ +import { CreateOptions } from '#app' + +const entry = process.server + ? (ctx?: CreateOptions['ssrContext']) => import('#app/entry').then(m => m.default(ctx)) + : () => import('#app/entry').then(m => m.default) + +if (process.client) { + entry() +} + +export default entry diff --git a/packages/nuxt3/src/app/entry.ts b/packages/nuxt3/src/app/entry.ts index 5a19501ae4..03cfd67e23 100644 --- a/packages/nuxt3/src/app/entry.ts +++ b/packages/nuxt3/src/app/entry.ts @@ -1,11 +1,66 @@ -import { CreateOptions } from '#app' +import { createSSRApp, createApp, nextTick } from 'vue' +import { createNuxtApp, applyPlugins, normalizePlugins, CreateOptions } from '#app' +import '#build/css' +// @ts-ignore +import _plugins from '#build/plugins' +// @ts-ignore +import RootComponent from '#build/root-component.mjs' +// @ts-ignore +import AppComponent from '#build/app-component.mjs' -const entry = process.server - ? (ctx?: CreateOptions['ssrContext']) => import('#app/bootstrap').then(m => m.default(ctx)) - : () => import('#app/bootstrap').then(m => m.default) +let entry: Function -if (process.client) { - entry() +const plugins = normalizePlugins(_plugins) + +if (process.server) { + entry = async function createNuxtAppServer (ssrContext: CreateOptions['ssrContext'] = {}) { + const vueApp = createApp(RootComponent) + vueApp.component('App', AppComponent) + + const nuxt = createNuxtApp({ vueApp, ssrContext }) + + await applyPlugins(nuxt, plugins) + + await nuxt.hooks.callHook('app:created', vueApp) + + return vueApp + } } -export default entry +if (process.client) { + // TODO: temporary webpack 5 HMR fix + // https://github.com/webpack-contrib/webpack-hot-middleware/issues/390 + // @ts-ignore + if (process.dev && import.meta.webpackHot) { + // @ts-ignore + import.meta.webpackHot.accept() + } + + entry = async function initApp () { + const isSSR = Boolean(window.__NUXT__?.serverRendered) + const vueApp = isSSR ? createSSRApp(RootComponent) : createApp(RootComponent) + vueApp.component('App', AppComponent) + + const nuxt = createNuxtApp({ vueApp }) + + await applyPlugins(nuxt, plugins) + + await nuxt.hooks.callHook('app:created', vueApp) + await nuxt.hooks.callHook('app:beforeMount', vueApp) + + nuxt.hooks.hookOnce('app:suspense:resolve', () => { + nuxt.isHydrating = false + }) + + vueApp.mount('#__nuxt') + + await nuxt.hooks.callHook('app:mounted', vueApp) + await nextTick() + } + + entry().catch((error) => { + console.error('Error while mounting app:', error) // eslint-disable-line no-console + }) +} + +export default (ctx?: CreateOptions['ssrContext']) => entry(ctx) diff --git a/packages/schema/src/config/build.ts b/packages/schema/src/config/build.ts index 7a84ddecb7..54df8d8f81 100644 --- a/packages/schema/src/config/build.ts +++ b/packages/schema/src/config/build.ts @@ -617,5 +617,6 @@ export default { * Set to true to scan files within symlinks in the build (such as within `pages/`). * @version 2 */ + followSymlinks: false } diff --git a/packages/schema/src/config/experimental.ts b/packages/schema/src/config/experimental.ts new file mode 100644 index 0000000000..41226d9739 --- /dev/null +++ b/packages/schema/src/config/experimental.ts @@ -0,0 +1,7 @@ +export default { + /** + * Set to true to generate an async entrypoint for the Vue bundle (for module federation support). + * @version 3 + */ + asyncEntry: false +} diff --git a/packages/schema/src/config/index.ts b/packages/schema/src/config/index.ts index d7879e6674..bb868be66c 100644 --- a/packages/schema/src/config/index.ts +++ b/packages/schema/src/config/index.ts @@ -12,6 +12,7 @@ import cli from './cli' import generate from './generate' import typescript from './typescript' import nitro from './nitro' +import experimental from './experimental' /* TODO for top level normalizations: (nuxt2) @@ -45,6 +46,7 @@ export default { cli, generate, typescript, + experimental, /** * Configuration that will be passed directly to Vite. diff --git a/packages/vite/src/vite.ts b/packages/vite/src/vite.ts index 4d6232a6a3..f516630889 100644 --- a/packages/vite/src/vite.ts +++ b/packages/vite/src/vite.ts @@ -50,7 +50,7 @@ export async function bundle (nuxt: Nuxt) { // will be filled in client/server configs '#build/plugins': '', '#build': nuxt.options.buildDir, - '/entry.mjs': resolve(nuxt.options.appDir, 'entry'), + '/entry.mjs': resolve(nuxt.options.appDir, nuxt.options.experimental.asyncEntry ? 'entry.async' : 'entry'), 'web-streams-polyfill/ponyfill/es2018': 'unenv/runtime/mock/empty', // Cannot destructure property 'AbortController' of .. 'abort-controller': 'unenv/runtime/mock/empty' diff --git a/packages/webpack/src/presets/base.ts b/packages/webpack/src/presets/base.ts index 80db31be69..8ed00530ef 100644 --- a/packages/webpack/src/presets/base.ts +++ b/packages/webpack/src/presets/base.ts @@ -23,7 +23,7 @@ function baseConfig (ctx: WebpackConfigContext) { ctx.config = { name: ctx.name, - entry: { app: [resolve(options.appDir, 'entry')] }, + entry: { app: [resolve(options.appDir, options.experimental.asyncEntry ? 'entry.async' : 'entry')] }, module: { rules: [] }, plugins: [], externals: [],