Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emotion with Deno is Okay, Chakra with Deno results in no style output #2777

Closed
cameronelliott opened this issue Jun 6, 2022 · 9 comments
Closed

Comments

@cameronelliott
Copy link

I get the following valid with styles output:
emotion html <style data-emotion="css 3h4kzc">.css-3h4kzc{color:hotpink;}</style><div class="css-3h4kzc">Some hotpink text.</div>
when I run:
deno run -A --no-check emotion.jsx

on this:

// this example generates valid html with styles in the front
//
// $ deno run -A --no-check emotion.jsx

// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement
/** @jsx jsx */

import { jsx, css } from 'https://esm.sh/@emotion/react@11.9.0'
import { renderToString } from 'https://esm.sh/react-dom@18.1.0/server'

const style = css`
  color: hotpink;
`

const SomeComponent = ({ children }) => (
  <div css={style}>
    Some hotpink text.
    {children}
  </div>
)


let html = renderToString(<SomeComponent />)

console.log('emotion html',html)

BUT, when I run:
deno run -A --no-check chakra.jsx, on the code near the end of the issue...

... I get the following HTML which is missing the styles in front of the Chakra HTML output:

[default styles removed]
["css-pi6lsa" is never defined!!!]
<button type="button" class="chakra-button css-pi6lsa">Button</button><span></span><span hidden="" class="chakra-env"></span>

**If an emotion dev sees the obvious problem, I would be grateful for any suggestions or help. **
Sorry to ask here, but I suspect you are better informed about the possibilities than Chakra or Deno persons

Deno Emotion/Chakra code

// this example generates html MISSING the created styles on the HTML
//
// $ deno run -A --no-check chakra.jsx

// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement
/** @jsx jsx */

import { jsx, css } from 'https://esm.sh/@emotion/react@11.9.0'

import { renderToString } from "https://esm.sh/react-dom@18.1.0/server";

import { Button, ChakraProvider, theme } from "https://esm.sh/@chakra-ui/react";

function App() {
  return (
    <ChakraProvider theme={theme}>
      <Button colorScheme='red'>Button</Button>
    </ChakraProvider>
  )
}


let html = renderToString(<App />);

console.log("chakra html", html);
@Andarist
Copy link
Member

Andarist commented Jun 6, 2022

Well, it is somewhat weird because I would expect that if there is a problem then Emotion shouldn't work with Deno on its own either.

I know what I would check on your place but I have no experience with Deno and I don't know how to quickly debug it so I think that you are a better person to check those things.

I've checked that in theory that your Chakra requests the very same @emotion/react file:
https://esm.sh/v85/@emotion/react@11.9.0/es2022/react.js

I would still try to confirm if that's really the case throughout the app - is there a way to see all of the files included in this compilation?

@cameronelliott
Copy link
Author

As far as I can tell, it is the same:

garapa1@penguin ~/deno-chakra-mvp (master)> NO_COLOR=1 deno info chakra.jsx | grep emotion/react
Download https://esm.sh/v85/@types/lodash@4.14.182/index
│ │   │ │     │   │ │ │ ├─┬ https://esm.sh/v85/@emotion/react@11.9.0/types/index.d.ts (3.06KB)
│ │   │ │     │   │ │ │ │ ├─┬ https://esm.sh/v85/@emotion/react@11.9.0/types/helper.d.ts (567B)
│ │   │ │     │   │ │ │ │ ├─┬ https://esm.sh/v85/@emotion/react@11.9.0/types/jsx-namespace.d.ts (1.62KB)
│ │   │ │     │   │ │ │ │ │ ├── https://esm.sh/v85/@emotion/react@11.9.0/types/index.d.ts *
│ │   │ │     │   │ │ │ │ ├─┬ https://esm.sh/v85/@emotion/react@11.9.0/types/theming.d.ts (942B)
│ │   │ │     │   │ │ │ │ │ ├── https://esm.sh/v85/@emotion/react@11.9.0/types/helper.d.ts *
│ │   │ │     │   │ │ │ │ │ ├── https://esm.sh/v85/@emotion/react@11.9.0/types/index.d.ts *
│ │   │ │     │   │ │   │ ├── https://esm.sh/v85/@emotion/react@11.9.0/types/index.d.ts *
│ │   │ │     │   │ │   └── https://esm.sh/v85/@emotion/react@11.9.0/types/index.d.ts *
│ │   │ │     │   │ ├── https://esm.sh/v85/@emotion/react@11.9.0/types/index.d.ts *
│ │   │ │     │   ├── https://esm.sh/v85/@emotion/react@11.9.0/types/index.d.ts *
│ │   │ │     │   └── https://esm.sh/v85/@emotion/react@11.9.0/types/index.d.ts *
│ │ │ │ │ ├─┬ https://esm.sh/v85/@emotion/react@11.9.0/deno/react.js (6.33KB)
│ │ │ │ │ │ ├── https://esm.sh/v85/@emotion/react@11.9.0/deno/react.js *
│ │ │ ├── https://esm.sh/v85/@emotion/react@11.9.0/deno/react.js *
├─┬ https://esm.sh/@emotion/react@11.9.0 (109B)
│ ├── https://esm.sh/v85/@emotion/react@11.9.0/types/index.d.ts *
│ ├── https://esm.sh/v85/@emotion/react@11.9.0/deno/react.js *
garapa1@penguin ~/deno-chakra-mvp (master)> 

@cameronelliott
Copy link
Author

But, if I use a different method to report all emotion related packages, I see this:

Download https://esm.sh/v85/@emotion/cache@11.7.1/deno/cache.js
Download https://esm.sh/v85/@emotion/cache@11.7.1/types/index.d.ts
Download https://esm.sh/v85/@emotion/hash@0.8.0/deno/hash.js
Download https://esm.sh/v85/@emotion/is-prop-valid@0.8.8/deno/is-prop-valid.js
Download https://esm.sh/v85/@emotion/is-prop-valid@1.1.2/deno/is-prop-valid.js
Download https://esm.sh/v85/@emotion/memoize@0.7.4/deno/memoize.js
Download https://esm.sh/v85/@emotion/memoize@0.7.5/deno/memoize.js
Download https://esm.sh/v85/@emotion/react@11.9.0/deno/react.js
Download https://esm.sh/v85/@emotion/react@11.9.0/types/helper.d.ts
Download https://esm.sh/v85/@emotion/react@11.9.0/types/index.d.ts
Download https://esm.sh/v85/@emotion/react@11.9.0/types/jsx-namespace.d.ts
Download https://esm.sh/v85/@emotion/react@11.9.0/types/theming.d.ts
Download https://esm.sh/v85/@emotion/serialize@1.0.3/deno/serialize.js
Download https://esm.sh/v85/@emotion/serialize@1.0.3/types/index.d.ts
Download https://esm.sh/v85/@emotion/sheet@1.1.0/deno/sheet.js
Download https://esm.sh/v85/@emotion/styled@11.8.1/deno/styled.js
Download https://esm.sh/v85/@emotion/styled@11.8.1/types/base.d.ts
Download https://esm.sh/v85/@emotion/styled@11.8.1/types/index.d.ts
Download https://esm.sh/v85/@emotion/unitless@0.7.5/deno/unitless.js
Download https://esm.sh/v85/@emotion/utils@1.1.0/deno/utils.js
Download https://esm.sh/v85/@emotion/utils@1.1.0/types/index.d.ts
Download https://esm.sh/v85/@emotion/weak-memoize@0.2.5/deno/weak-memoize.js

Which does have two versions for 'memoize', and 'is-prop-valid',
do you think that should be a concern?
(I can get the tree also)

@Andarist
Copy link
Member

Andarist commented Jun 6, 2022

No, those can be freely duplicated - it shouldn't matter.

As far as I can tell by looking at the minified @emotion/styled:
https://esm.sh/v85/@emotion/styled@11.8.1/deno/styled.js
is that this branch of the code has just been dropped:

if (!isBrowser && rules !== undefined) {

It means that the esm.sh service has bundled our code for the browser target and not for the server (it probably has this logic as its default).

We can read on their page that they allow customizing the target:

esm.sh supports ?worker mode to load modules as web worker:

BUT I can't see any way to set the target env as server/node/deno

Given that... I have no idea why the non-Chakra versions works because I would have expect for the same thing to happen.

@Andarist
Copy link
Member

Andarist commented Jun 6, 2022

Actually, I've found in their source code that node is a valid target and that you can use it:
https://github.com/esm-dev/esm.sh/blob/469d08eb77020765e91e52a762b3384a120e1215/server/build.go#L345-L346

I've also confirmed that this works:
https://esm.sh/@emotion/styled@11.8.1?target=node

@cameronelliott
Copy link
Author

cameronelliott commented Jun 7, 2022

@Andarist Hey, your help was fantastic. Thank you!

I really hope we can get Chakra+Emotion working with Deno correctly using esm.sh.
(so everyone can use it, and it works reliably for me, too)
(I have no association, it just seems like the way to do Deno+Chakra+Emotion,
but if you know another way I should be trying to do Deno+Chakra+Emotion, please let me know)

I took the node version, hand-fixed a few Node calls, and swapped it in using Deno import maps, and
the output looked correct, including styles.

Do you know why window.document might be defined during esm.sh compilation
thus, causing the styles code block to be removed from the output???

I am trying to nail this down in order to provide a PR/fix.

Oh! one other thing, in the emotion-only, non-Chakra case, @emotion/styled does not get used/pulled in by the Deno loader, so, I don't know how the output happens, but it does. I can provide the module tree log if for some reason you want to see it.

@cameronelliott
Copy link
Author

cameronelliott commented Jun 7, 2022

This is the command esm.sh uses to build it's modules

node /usr/bin/yarn add --check-files --ignore-engines --ignore-platform --ignore-scripts --ignore-workspace-root-check --no-bin-links --no-default-rc --no-lockfile --no-node-version-check --no-progress --non-interactive --silent --registry=https://registry.npmjs.org/ @emotion/styled
warning "@emotion/styled > @emotion/babel-plugin@11.9.2" has unmet peer dependency "@babel/core@^7.0.0".
warning "@emotion/styled > @emotion/babel-plugin > @babel/plugin-syntax-jsx@7.17.12" has unmet peer dependency "@babel/core@^7.0.0-0".
warning " > @emotion/styled@11.8.1" has unmet peer dependency "@emotion/react@^11.0.0-rc.0".
warning Ignored scripts due to flag.

Well, this can very based upon targets, but I'm working it.

@Andarist
Copy link
Member

Andarist commented Jun 7, 2022

I really hope we can get Chakra+Emotion working with Deno correctly using esm.sh.

Doesn't this ?target=node work for you?

I took the node version, hand-fixed a few Node calls, and swapped it in using Deno import maps

Hm, did you have to hand-fix anything in Emotion to make it work? I don't think we are using anything node-specific - I could be wrong though.

Do you know why window.document might be defined during esm.sh compilation thus, causing the styles code block to be removed from the output???

It's not exactly that window.document is defined. It's that the default platform used for bundling in esm.sh is a browser:
https://github.com/esm-dev/esm.sh/blob/469d08eb77020765e91e52a762b3384a120e1215/server/build.go#L328
and based on that esbuild itself resolves to the files defined in package.json#browser (if there are any):
https://github.com/evanw/esbuild/blob/1916318ca7f803253dbdae0942af1c9a6d3a6910/internal/resolver/package_json.go#L340-L352
and it happens so that we are using this field to remove some server-only code and save a few bytes on the bundlesize:

"browser": {
"./dist/emotion-styled.cjs.js": "./dist/emotion-styled.browser.cjs.js",
"./dist/emotion-styled.esm.js": "./dist/emotion-styled.browser.esm.js"
},

@Andarist
Copy link
Member

I believe that the issue has been answered and there isn't anything that we can do to improve the situation further on our side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants