Code Monkey home page Code Monkey logo

Comments (7)

freddy38510 avatar freddy38510 commented on June 3, 2024 1

Apologize but I do not understand why this would be a problem, because what I'm generating is a static (web)site? Running as a website, surely rendered in browser, must have a window object, isn't it?

SSG is like SSR but at build time. This means that each page is pre-rendered server-side, with the result then written to an html file. When the app runs in browser (client-side), the static markup is hydrated by Vue to make it interactive.

So, when you need to perform conditional logic based on SSR vs. client, you can use process.env.SERVER and/or
process.env.CLIENT

if (process.env.CLIENT) {
  // client-only logic

  import('my-fancy-npm-package').then(package => {
    // notice "default" below, which is the prop with which
    // you can access what your npm imported package exports
    package.default.doSomething()
  })

  // access window global variable
  console.log(window)
}

You can also access the window variable inside Vue client-only lifecycle hooks. For example onMounted or onUpdated will NOT be called during SSR and will only be executed on the client.

Quasar boot files can also be executed only at client or server side:

boot: [
  {
    server: false, // run on client-side only!
    path: '<name>' // references /src/boot/<name>.js
  },
  {
    client: false, // run on server-side only!
    path: '<name>' // references /src/boot/<name>.js
  }
]

If you have components that are difficult to adapt to the server, you can use the Quasar No SSR component to run them client-side only.


About your library, the Rollup external option is used for deps that should remain external to the bundle.

It is fine to make the abort-controller dep external when your library runs at server-side, because nodejs know where to find and import the package (node_modules folder). But at client-side, the dep should be available in the bundle.

So, contrary to what I said, it's not specific to the UMD format. In fact, the issue with this specific package is not strictly about making it external or not. When you compile and bundle your library with its deps, Vite imports the browser.js entry file of the abort-controller package from where the error is thrown when executed at server-side.

From the abort-controller documentation:

If your bundler recognizes browser field of package.json, the imported AbortController is the native one and it doesn't contain shim (even if the native implementation was nothing).

By default Vite will use the browser field first when resolving the abort-controller's entry point.

I don't have much time to look for a suitable solution to this problem, but I hope that from now on you'll have a better understanding of what it's all about.

from quasar-app-extension-ssg.

freddy38510 avatar freddy38510 commented on June 3, 2024

I've just tested throwing an error from IndexPage.vue, using Node.js v21.2.0, and the stack trace is perfectly readable. The same applies when throwing an error from a Quasar boot file.

The error may come from an external library that has already been minified.

Could you try running the quasar ssg generate --debug command ?

As a last resort, please try the quasar ssg dev command.

The minify option is set here.

from quasar-app-extension-ssg.

renyuneyun avatar renyuneyun commented on June 3, 2024

Hi. Sorry for the delay.
Thanks for providing the suggestions. quasar ssg generate --debug did not produce any difference. However, after quasar ssg dev, after opening the address in browser, I got the following error:

22:51:40 [vite] Error when evaluating SSR module /src/layouts/MainLayout.vue: failed to import "@renyuneyun/solid-helper"
|- TypeError: Cannot destructure property 'AbortController' of '(intermediate value)(intermediate value)(intermediate value)' as it is undefined.
    at file:///home/ryey/coding/solid-fixer/node_modules/@renyuneyun/solid-helper/dist/solid-helper.mjs:18300:26
    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at async nodeImport (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:56097:17)
    at async ssrImport (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:55990:24)
    at async eval (/home/ryey/coding/solid-fixer/src/layouts/MainLayout.vue:8:31)
    at async instantiateModule (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:56052:9)

[Vue Router warn]: uncaught error during route navigation:
TypeError: Cannot destructure property 'AbortController' of '(intermediate value)(intermediate value)(intermediate value)' as it is undefined.
    at file:///home/ryey/coding/solid-fixer/node_modules/@renyuneyun/solid-helper/dist/solid-helper.mjs:18300:26
    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at async nodeImport (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:56097:17)
    at async ssrImport (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:55990:24)
    at async eval (/home/ryey/coding/solid-fixer/src/layouts/MainLayout.vue:8:31)
    at async instantiateModule (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:56052:9)

 App • ⚠   Render failed  /
22:51:40 [vite] Error when evaluating SSR module /src/utils/profile-teller.ts: failed to import "@renyuneyun/solid-helper"
|- TypeError: Cannot destructure property 'AbortController' of '(intermediate value)(intermediate value)(intermediate value)' as it is undefined.
    at file:///home/ryey/coding/solid-fixer/node_modules/@renyuneyun/solid-helper/dist/solid-helper.mjs:18300:26
    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at async nodeImport (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:56097:17)
    at async ssrImport (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:55990:24)
    at async eval (/home/ryey/coding/solid-fixer/src/layouts/MainLayout.vue:8:31)
    at async instantiateModule (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:56052:9)

22:51:40 [vite] Error when evaluating SSR module /src/components/ProfileStatus.vue: failed to import "/src/utils/profile-teller.ts"
|- TypeError: Cannot destructure property 'AbortController' of '(intermediate value)(intermediate value)(intermediate value)' as it is undefined.
    at file:///home/ryey/coding/solid-fixer/node_modules/@renyuneyun/solid-helper/dist/solid-helper.mjs:18300:26
    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at async nodeImport (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:56097:17)
    at async ssrImport (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:55990:24)
    at async eval (/home/ryey/coding/solid-fixer/src/layouts/MainLayout.vue:8:31)
    at async instantiateModule (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:56052:9)

22:51:40 [vite] Error when evaluating SSR module /src/pages/IndexPage.vue: failed to import "/src/components/ProfileStatus.vue"
|- TypeError: Cannot destructure property 'AbortController' of '(intermediate value)(intermediate value)(intermediate value)' as it is undefined.
    at file:///home/ryey/coding/solid-fixer/node_modules/@renyuneyun/solid-helper/dist/solid-helper.mjs:18300:26
    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at async nodeImport (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:56097:17)
    at async ssrImport (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:55990:24)
    at async eval (/home/ryey/coding/solid-fixer/src/layouts/MainLayout.vue:8:31)
    at async instantiateModule (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:56052:9)

file:///home/ryey/coding/solid-fixer/node_modules/@renyuneyun/solid-helper/dist/solid-helper.mjs:18300
const { AbortController: T9, AbortSignal: VW } = typeof self < "u" ? self : typeof window < "u" ? window : (
                         ^

TypeError: Cannot destructure property 'AbortController' of '(intermediate value)(intermediate value)(intermediate value)' as it is undefined.
    at file:///home/ryey/coding/solid-fixer/node_modules/@renyuneyun/solid-helper/dist/solid-helper.mjs:18300:26
    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at async nodeImport (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:56097:17)
    at async ssrImport (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:55990:24)
    at async eval (/home/ryey/coding/solid-fixer/src/layouts/MainLayout.vue:8:31)
    at async instantiateModule (file:///home/ryey/coding/solid-fixer/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:56052:9)

Node.js v21.2.0

That @renyuneyun/solid-helper library is mine, so I can try to debug more. However, I have no idea where this AbortController is from, so that could take some while.

Anyway, this looks different from the previous error, as one is for the missing property get while the other is for object destruction?

from quasar-app-extension-ssg.

freddy38510 avatar freddy38510 commented on June 3, 2024

I tried to add abort-controller package to the Rollup external option in the vite config file of your @renyuneyun/solid-helper package, and it fixes the issue.

But making the abort-controller package external could break the library when used in umd format.
To solve this problem, you can create two vite.config.ts files, one for the esm format and a second for the umd format.

Apart from this issue, you'll come across other errors linked to the use of web functionalities not available on nodejs. Such as the window global variable.
Perhaps you should read this: https://quasar.dev/quasar-cli-vite/developing-ssr/writing-universal-code

from quasar-app-extension-ssg.

renyuneyun avatar renyuneyun commented on June 3, 2024

Thanks for the information. Indeed I'm aware of the difference between frontend and backend (node), and am trying my best to not running into problems related to that (i.e. I'm trying to write a front-end application as website only); however, due to my limited experience with JS, my practice may very likely miss things.

I managed to solve the abort-controller issue and related ones (e.g. process.nextTick not found), as can be found in the updated vite config (in dev branch). But am stuck at two issues, in separate sections below.

window missing

Immediately after fixing the previous issues, I encountered issues related to window global variable when running quasar ssg generate --debug (I can confirm normal quasar build works):

 App •  DONE  • SSR Server compiled with success • 5941ms

 App •  WAIT  • Initializing route(s) in progress...
 App •  INFO  • The crawler feature will attempt to find dynamic routes
 App •  DONE  • 2 route(s) initialized with success • 3ms

 App •  WAIT  • Generating Pages in progress...

 App • ⚠   Failed to pre-render: "/"  ReferenceError: window is not defined
    at setup (/home/ryey/coding/solid-fixer/src/pages/IndexPage.vue:17:1)
    at _sfc_main.setup (/home/ryey/coding/solid-fixer/src/pages/IndexPage.vue:20:17)
    at callWithErrorHandling (/home/ryey/coding/solid-fixer/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:18:18)
    at setupStatefulComponent (/home/ryey/coding/solid-fixer/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:5890:25)
    at setupComponent (/home/ryey/coding/solid-fixer/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:5877:36)
    at renderComponentVNode (/home/ryey/coding/solid-fixer/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:354:15)
    at renderVNode (/home/ryey/coding/solid-fixer/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:483:14)
    at renderComponentSubTree (/home/ryey/coding/solid-fixer/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:438:7)
    at renderComponentVNode (/home/ryey/coding/solid-fixer/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:371:12)
    at renderVNode (/home/ryey/coding/solid-fixer/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:483:14)

Such as the window global variable.

Apologize but I do not understand why this would be a problem, because what I'm generating is a static (web)site? Running as a website, surely rendered in browser, must have a window object, isn't it?

Circular object

After removing all the relevant code using window (i.e. those creating const referencing window), I got the following error (still from quasar ssg generate --debug):

 App •  WAIT  • Generating Pages in progress...

 App • ⚠   Failed to pre-render: "/"  TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Object'
    --- property 'events' closes the circle
    at JSON.stringify (<anonymous>)
    at serialize (/home/ryey/coding/solid-fixer/node_modules/serialize-javascript/index.js:195:20)
    at renderStoreState (/home/ryey/coding/solid-fixer/node_modules/quasar-app-extension-ssg/src/vite/ssg-create-render-fn.js:77:19)
    at PagesGenerator.render (/home/ryey/coding/solid-fixer/node_modules/quasar-app-extension-ssg/src/vite/ssg-create-render-fn.js:120:37)
    at async #renderPage (/home/ryey/coding/solid-fixer/node_modules/quasar-app-extension-ssg/src/vite/PagesGenerator.js:288:14)
    at async PagesGenerator.generatePage (/home/ryey/coding/solid-fixer/node_modules/quasar-app-extension-ssg/src/vite/PagesGenerator.js:240:16)
    at async PagesGenerator.<anonymous> (/home/ryey/coding/solid-fixer/node_modules/quasar-app-extension-ssg/src/vite/PagesGenerator.js:75:38)

This time I have no little idea. Running npm run build:ssg also leads to this (instead of the very original error in the title).
Could this be somehow related to the dependency that I modified (i.e. @renyuneyun/solid-helper)?
After further investigation (by commenting and uncommenting parts of the code), I found this is related to a Pinia store: whenever I refer to the session store, this error emerges. Later I found out that if a) I copy all relevant code from the library (my other library) to this project, and b) I install the dependency @inrupt/solid-client-authn-browser, this error do not emerge, and the project builds successfully. However, if either of these does not meet, it happens. (After further modifications, only explicitly installing the dependency is necessary. I'm not entirely sure why, but this could be caused by the fact that I removed the same dependency from another library. More information in #379.)
It seems to be an issue related to js library packaging in the end...
But hope the error message from quasar-app-extension-ssg be more readable.

About UMD and external

This is probably not an immediate issue, but may affect in the future, so I'm still asking in case there is a quick answer. Please ignore this part if that's not the case.

But making the abort-controller package external could break the library when used in umd format.
To solve this problem, you can create two vite.config.ts files, one for the esm format and a second for the umd format.

Thanks for this suggestion. If you have time, could you point out some resources explaining / mentioning this issue? I tried to search things like umd external vite, but did not find any useful information.

from quasar-app-extension-ssg.

renyuneyun avatar renyuneyun commented on June 3, 2024

Thanks very much for the patient and detailed explanation. That now makes a lot of sense.
So SSR "executes" the scripts (e.g. a Vue component which contains root-level references to window such as <script>const a = window.location</script>) at building/generation time, during when the environment is a node environment, which does not have window. And SSG by this extension uses the same first step as SSR, but saves the generated page. That is where the error appeared.
I was not aware of this and did not grasp this idea from the relevant words in the documents back then. I thought the building was just converting/transcompiling the Vue component as a pure JS file, but not executing it.
Thanks a lot for the clarification.

And thanks for the information about abort-controller. I'll do further tests to verify my code, and, if something goes wrong, try to find a solution.

from quasar-app-extension-ssg.

freddy38510 avatar freddy38510 commented on June 3, 2024

That's right. You can read the documentation on SSR and SSG directly on the Vue website, it contains better explanations than mine.

I've got some rewritten documentation in the pipeline and a few features, but I'm running out of time these days to deliver them properly.

Thanks for the feedback, it's always very useful !

from quasar-app-extension-ssg.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.