vanilla-extract-css / vanilla-extract

Zero-runtime Stylesheets-in-TypeScript

Home Page:https://vanilla-extract.style

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

4.x: Uncaught TypeError: e.constructor is not a function

gu-stav opened this issue · comments

Describe the bug

I've been running @vanilla-extract/vite-plugin@3.9.5 for quite some time in a Vue project, however it remains impossible to upgrade to v4 due to the following issue:

  • if a add a file called theme.css.ts an error is thrown during vite build
> vite build

vite v5.1.6 building for production...
✓ 15 modules transformed.
x Build failed in 473ms
error during build:
walkObject@file:///home/projects/vitejs-vite-ogfgnu/node_modules/@vanilla-extract/private/dist/vanilla-extract-private.esm.js:27:19
createThemeContract@file:///home/projects/vitejs-vite-ogfgnu/node_modules/@vanilla-extract/css/dist/vanilla-extract-css.esm.js:295:32
createGlobalTheme@file:///home/projects/vitejs-vite-ogfgnu/node_modules/@vanilla-extract/css/dist/vanilla-extract-css.esm.js:314:38
@file:///home/projects/vitejs-vite-ogfgnu/src/styles/theme.css.ts:11:36
  • if I rename this file to theme.ts the build succeeds, however the browser will then log a similar error once running vite preview
Uncaught TypeError: obj.constructor is not a function
    walkObject vanilla-extract-private.esm.js:27
    createThemeContract vanilla-extract-css.browser.esm.js:280
    createGlobalTheme vanilla-extract-css.browser.esm.js:299
    <anonymous> theme.ts:5

This can be reproduced in the attached stackblitz repo, by renaming the file in src/styles/theme.css.ts to theme.ts and updating the import in src/App.vue.

Reproduction

https://stackblitz.com/edit/vitejs-vite-1q7kbr

System Info

System:
    OS: macOS 14.3.1
    CPU: (12) arm64 Apple M3 Pro
    Memory: 55.58 MB / 18.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.11.0 - ~/.nvm/versions/node/v20.11.0/bin/node
    npm: 10.2.4 - ~/.nvm/versions/node/v20.11.0/bin/npm
    pnpm: 8.14.1 - ~/Library/pnpm/pnpm
  Browsers:
    Chrome: 122.0.6261.129
    Edge: 122.0.2365.92
    Firefox Nightly: 125.0a1
    Safari: 17.3.1

Used Package Manager

npm

Logs

see above

Validations

This is happening because, as defined in the ES6 spec, module namespace objects do not have a constructor function. We use constructor to clone objects inside walkObject.

A simple workaround would be to just define and export an actual object, and not use a namespace import. Namespace imports are generally bad as they are harder to tree-shake, so I would just avoid them completely.

I'm tempted to say we probably wont fix this since it's an uncommon edge case, unless there's a specific reason you have to use a namespace import.

EDIT: Forgot to mention the vite plugin. This has only become an issue in v4 because we switched to using vite-node for building styles, and I guess it handles this case differently to esbuild (what we used to use). There could be a way to get vite-node to work the same way esbuild used to, but I'm not sure.

Thank you for the quick response and your help ✨ I can confirm the suggested workaround works. I'm wondering if it would be sufficient to throw a better error in the future to prevent this?

Thank you for the quick response and your help ✨ I can confirm the suggested workaround works. I'm wondering if it would be sufficient to throw a better error in the future to prevent this?

I think we can actually avoid this error entirely by replacing obj.constructor() with just an empty {}.

The initial implementation of walkObject wasn't actually specific to Objects and used constructor() to deal with this. Later it was constrained to only work on records, and it still works the same right now. So we no longer need to use constructor() and can just start with a plain empty object {}. This means you can use namespace imports if necessary 🎉.