ben-rogerson / twin.macro

🦹‍♂️ Twin blends the magic of Tailwind with the flexibility of css-in-js (emotion, styled-components, solid-styled-components, stitches and goober) at build time.
MIT License
7.93k stars 183 forks source link

Can't resolve 'fs' , 'module' w/{Gatsby + Styled-Components} #327

Closed kelvindecosta closed 3 years ago

kelvindecosta commented 3 years ago

Overview

Hey!

I've been using twin.macro with my Gatsby site for quite some time now. I ran into a bug a few weeks back which I was able to temporarily rectify. I still think the underlying problem is not solved.

Reproduction

Please refer to this sandbox.

The following steps were taken to create this reproduction:

Behavior

Errors ``` error Generating development JavaScript bundle failed Can't resolve 'fs' in '/sandbox/node_modules/babel-plugin-styled-components/lib/visitors' (2 times) Can't resolve 'fs' in '/sandbox/node_modules/cosmiconfig/dist' (2 times) Can't resolve 'fs' in '/sandbox/node_modules/path-type' (2 times) Can't resolve 'fs' in '/sandbox/node_modules/resolve-from' (2 times) Can't resolve 'fs' in '/sandbox/node_modules/resolve/lib' (4 times) Can't resolve 'module' in '/sandbox/node_modules/resolve-from' (2 times) ```

Workaround

Part 1

Changes

Back when I first encountered this, I looked for similar issues and stumbled upon this one. I followed the fix, by modifying the Webpack configuration.

`gatsby-node.js` ```js exports.onCreateWebpackConfig = ({ actions }) => { // Fixes packages that depend on fs/module module actions.setWebpackConfig({ node: { fs: 'empty', module: 'empty', }, }) } ```

Errors

Terminal ``` warn Critical dependency: require function is used in a way in which dependencies cannot be statically extracted warn Critical dependency: the request of a dependency is an expression ```
Browser (Visiting http://localhost:8000) ``` Uncaught TypeError: styled_components_macro__WEBPACK_IMPORTED_MODULE_1__.default.div is not a function ```

Part 2

Changes

I resorted to the following changes, which seem to have gotten rid of the errors. Ideally, I would prefer not to do this.

`src/components/layout.js` ```diff import React from 'react' + import styled from 'styled-components' import tw, { GlobalStyles } from 'twin.macro' - const LayoutWrapper = tw.div`bg-red-500` + const LayoutWrapper = styled.div` + ${tw`bg-red-500`} + ` ```

Errors

I think this bug has a more elegant solution. This is because it still seems to be affecting other pieces of code. For example, using the macro in .mdx files

Problem with MDX files ```mdx import tw from 'twin.macro' export const Red = tw.div`text-red-500` Hello ``` ``` WebpackError: ReferenceError: tw is not defined ```

Comment

Any help with this issue will be greatly appreciated!

Thank you!

ben-rogerson commented 3 years ago

Thanks for the great bug writeup and example - much appreciated.

I found that the example I've made works fine until I try using the same Layout component you've added which I thought was really strange.

Anyway, the errors hint that babel-plugin-macros isn't being loaded properly so I added a custom .babelrc according to the gatsby docs which fixes the errors without having to modify your webpack config:

// .babelrc
{
  "plugins": ["babel-plugin-macros"],
  "presets": [
    [
      "babel-preset-gatsby",
      {
        "targets": {
          "browsers": [">0.25%", "not dead"]
        }
      }
    ]
  ]
}

I'm not sure what the root cause of this is yet - it's a little puzzling. I tested the output of twins alongside the styled-components imports that are swapped in and it worked fine 🤷‍♂️

The "babel-preset-gatsby" preset includes "babel-plugin-macros" but it also must be defined here to work, so I'm beginning to think the babel config is being changed somewhere.

kelvindecosta commented 3 years ago

Thank you for the detailed response! I will follow your approach and create a .babelrc file.

I forgot to mention something very interesting.

I modified the original reproduction:

The errors no longer appear!

I suspect this has something to do with how the tw macro is imported alongside named exports from "twin.macro".

Thanks again!

kelvindecosta commented 3 years ago

This is very interesting... After adding the .babelrc configuration in your comment, I was able to completely rectify the bug!

I was having another unrelated issue with .mdx files Updates were not triggering hot reload. After adding .babelrc, the browser's console no longer displays "App is updated", but rather throws warnings that a full reload is required.

I had no Babel configuration initially. I think you're right about the it being changed elsewhere. Maybe there is something wrong with Gatsby's defaults?

kelvindecosta commented 3 years ago

Hey @ben-rogerson

I tried adding babel-plugin-twin to my Gatsby site. I used the .babelrc configuration in your comment, and prepended babel-plugin-twin before babel-plugin-macros. I get the following error message:

Uncaught ReferenceError: tw is not defined

I did a little research and I think Gatsby expands babel-plugin-macros after it extracts queries. This could mean that the tw macro is not available until some steps are completed. Maybe this is why the babel config seems to get changed?

ben-rogerson commented 3 years ago

I'll have a closer look into this - there could be a bug with babel-plugin-twin + gatsby here

ajmalafif commented 3 years ago

hey @kelvindecosta did you solve the issue you have with .mdx file or is that still going on? Curious how did you solve because I am on Gatsby + emotion (but not TS) and twin.macro works everywhere but .mdx file.

kelvindecosta commented 3 years ago

Hey @ajmalafif

Unfortunately the issue with .mdx files still persists.

I'm not sure whether it's an issue with twin.macro or mdx. The gatsby-plugin-mdx plugin has/had a few issues with import resolution.

I'll update you if the issue gets resolved!

ajmalafif commented 3 years ago

@kelvindecosta i stumbled upon this: https://www.gatsbyjs.com/plugins/gatsby-plugin-mdx/?=mdx#shouldblocknodefromtransformation

Not sure how to use it, but could this be a potential solution to use twin.macro in .mdx?

or maybe through wrapper from MDX? https://mdxjs.com/guides/wrapper-customization

mihaildu commented 3 years ago

Hey guys, I ran into a similar issue when using GlobalStyles in the same way described above. It seems that babel-plugin-macros relies on older version of webpack (< 5) to polyfill some packages when running in the browser (such as fs or path). However, gatsby is using webpack version 5 which doesn't polyfill them anymore.

The errors I was getting are similar to

failed Re-building development bundle - 0.503s
ERROR in ./node_modules/babel-plugin-macros/dist/index.js 9:10-25
Module not found: Error: Can't resolve 'path' in '.../node_modules/babel-plugin-macros/dist'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

My solution was to include the global styles in gatsby-browser.js

// gatsby-browser.js
import "tailwindcss/dist/base.min.css"

This would work and get rid of the errors. I tried the .babelrc described above and it works as well!

Edit: I assume babel-preset-gatsby deals with the polyfills as well, but haven't investigated if it does or why it's not applied.

ajmalafif commented 3 years ago

@mihaildu hey thanks for sharing. Curious if your setup is for TypeScript or including .babelrc just works for your setup?

mihaildu commented 3 years ago

I'm using plain JavaScript and yes, just adding the .babelrc works for me.

mihaildu commented 3 years ago

One last thing, I noticed GlobalStyles works too, but only if applied in gatsby-browser.js file, if using the wrapPageElement export like so

// gatsby-browser.js
import React from 'react';
import { GlobalStyles } from 'twin.macro';
...
export const wrapPageElement = ({ element, props }) => (
  <>
    <GlobalStyles />
    <Layout {...props}>{element}</Layout>
  </>
);
ben-rogerson commented 3 years ago

Closing for now, feel free to reopen if there's still an issue here.