useClientEffect => import buffer polyfill (which attaches itself to window) == preview/build: "self is not defined" in entry.express.mjs
Qwik Version
0.9.0
Operating System (or Browser)
Windows with Brave/Chromium
Node Version (if applicable)
v16.16.0
Which component is affected?
Qwik Rollup / Vite plugin
Expected Behaviour
Expected the polyfill to only ever import & run on client-side, so it can successfully attach itself to the window object, e.g. const bufData = window.buffer.Buffer(someData)
Works in dev but not in preview/production. Using an older buffer polyfill for browser. Supposed to attach to the window object.
Importing using useClientEffect, and then some of my handle functions will call it.
useClientEffect$(() => {
// also tried wrapping import in `if (typeof window !== "undefined")` as an extra check
import("~/libs/wzrdin_buffer_polyfill.js");
// should now be available on window object
});
Actual Behaviour
After npm run build and npm run build.server,
npm run serve results in:
> serve
> node server/entry.express
ReferenceError: self is not defined
at file:///C:/.../server/entry.express.mjs:2238:1
at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:385:24)
at async importModuleDynamicallyWrapper (node:internal/vm/module:437:15
Additional Information
Buffer polyfill comes from a now dead link, available on wayback: https://web.archive.org/web/20200505012145/https://wzrd.in/standalone/buffer
I have not tried other browser buffer implementations. I've used this polyfill in the past on a project and so was going to use it again, and it works fine in dev mode but it won't work in preview or build (self is not defined).
My entry.express.mjs file ends up with basically a copy of the polyfill, which is where we get self is not defined, even though the import should only happen on the client. I do see the minified polyfill in one of my build client files; seems like it has its own file as I would expect.
Maybe it's in the server file because it is referenced inside event handler functions, even though those event handler functions only run on the client. Again, works fine in dev mode, just not working after building the server.
Just to state more clearly:
The import happens inside a useClientEffect, and the usage occurs inside a handleSubmit function (attached to a form). And the handleSubmit function can never run on the server, so the server should not need to include the script that is imported in the useClientEffect.
We have changed how bundling works for server in the latest release, we should not be inlining dyanmic imports in ssr mode, so I think this issue should be closed! make sure to update to 0.12.1!