Gatsby: [1.0] @import inside of CSS file leads to built production site errors

Created on 2 Jun 2017  Â·  18Comments  Â·  Source: gatsbyjs/gatsby

Using latest gatsby 1.x here. Inside of my layouts/index.js I am importing my main style.css file.

import styles from 'css/style.css'

My style.css imports some modules like this:

@import 'normalize.css';
@import 'basscss';

Everything runs fine in development, but when building and pushing to production I get the error:

style.css:4 Uncaught Error: Cannot find module "-!../../node_modules/css-loader/index.js!./basscss"
    at style.css:4
    at Object../src/css/style.css (style.css:4)
    at t (bootstrap 673de47…:52)
    at Object../node_modules/babel-loader/lib/index.js?{"presets":["/Users/Gosset/Dev/mono2ski/node_modules/babel-preset-react/lib/index.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-preset-es2015/lib/index.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-preset-stage-1/lib/index.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-preset-es2015/lib/index.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-preset-stage-0/lib/index.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-preset-react/lib/index.js"],"plugins":["/Users/Gosset/Dev/mono2ski/node_modules/gatsby/dist/utils/babel-plugin-extract-graphql.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-plugin-add-module-exports/lib/index.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-plugin-add-module-exports/lib/index.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-plugin-add-module-exports/lib/index.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-plugin-transform-object-assign/lib/index.js"],"cacheDirectory":true}!./src/layouts/index.js (index.js:4)
    at t (bootstrap 673de47…:52)
    at index.js?3cb6:3
    at window.webpackJsonp (bootstrap 673de47…:20)
    at layout-component---index-6152920….js:1
(anonymous) @   style.css:4
./src/css/style.css @   style.css:4
t   @   bootstrap 673de47…:52
./node_modules/babel-loader/lib/index.js?{"presets":["/Users/Gosset/Dev/mono2ski/node_modules/babel-preset-react/lib/index.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-preset-es2015/lib/index.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-preset-stage-1/lib/index.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-preset-es2015/lib/index.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-preset-stage-0/lib/index.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-preset-react/lib/index.js"],"plugins":["/Users/Gosset/Dev/mono2ski/node_modules/gatsby/dist/utils/babel-plugin-extract-graphql.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-plugin-add-module-exports/lib/index.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-plugin-add-module-exports/lib/index.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-plugin-add-module-exports/lib/index.js","/Users/Gosset/Dev/mono2ski/node_modules/babel-plugin-transform-object-assign/lib/index.js"],"cacheDirectory":true}!./src/layouts/index.js  @   index.js:4
t   @   bootstrap 673de47…:52
(anonymous) @   index.js?3cb6:3
window.webpackJsonp @   bootstrap 673de47…:20
(anonymous)

Although the CSS is all there in production, it seems to still be trying to import it from my local setup. This error makes clicking any links cause a full page refresh.

Most helpful comment

Hey @gosseti, your solution had been working for me and then stopped as well. This seems to be working for me now:

if (
  process.env.NODE_ENV === `development` ||
  (process.env.NODE_ENV === `production` && process.browser !== true)
) {
  require('../css/main.css')
}

…where main.css is my source stylesheet in the css directory. Within that, I’m using some PostCSS features, but no PostCSS plugins beyond what comes with Gatsby.

The issue was the same as you’d described here https://github.com/gatsbyjs/gatsby/issues/1086#issuecomment-306089833 but now you get client side JS errors (even in production) if you keep the require statement, and if you remove it, you end up with an empty CSS file in public/styles.css (I got tripped up a few times thinking I’d fixed it other ways, but the contents of the public/ don’t seem to get deleted automatically).

With the conditional, you’ll get the stylesheet required by Webpack in development mode, and in production mode when you run gatsby build so the styles actually get compiled, but you won’t have the require causing errors when you visit the index page in the browser.

So this works, but it also seems like it might not be the desired behaviour.

All 18 comments

are you using just the default postcss webpack setup?

I don't use css so am not that familiar with how this stuff works...

Yeah just using the default here. It worked without any additional config needed in 0.x gatsby.

Is the way that CSS is required/imported different in 1.x?

Eh... I can't remember. I think I just copied things over directly. Could you compare the webpack configs and see?

Solved! It seems with 1.x there is no need to require styles inside of your layouts/index.js file for production. It now auto checks the css directory and includes any files you have in there.

In development layouts/index.js you’ll still need to have:

if (process.env.NODE_ENV === `development`) {
  require('css/styles.css')
}

Is this the desired behaviour?

@gosseti Getting this same issue, what was your fix / can I see your src/html.js?

I’m still running into issues and my fix above doesn’t hold up any longer.

Importing css dependencies from from node_modules is a pretty common use case. Where can I look/investigate to figure out how to fix this?

Inside of my layouts/index.js:

require('css/style.css')

Which gives me the error:

Uncaught Error: Cannot find module "-!../../node_modules/css-loader/index.js!./normalize-css"

Inside of my style.css I’m just doing a regular @import 'normalize-css';.

This is probably due to the postcss import plugin. waht does @import 'normalize-css' resolve too? imports throughout webpack tend to resolve the same ways js files do. the above would look for a module called normalize-css however i'm not sure what file though it is supposed to resolve too in the case of css, normally it'd look for normalize-css/index.js which doesn't make a ton of sense in the css case obviously.

TBH the problem may just be that we are doing the postcss import plugin instead of just relying on the normal behavior.

@import 'normalize-css/normalize.css'; inside of my style.css or layout.js resolves to:

"-!../../node_modules/css-loader/index.js!./normalize-css/normalize.css"

This worked without trouble in gatsby 0.x so I’m wondering what changed.

It works without trouble in development though.

This worked without trouble in gatsby 0.x so I’m wondering what changed.

I mean a lot has changed :) Most of the webpack setup should be the same but its hard to know with so many moving pieces! If you can put together a little repro that illustrates the issue that may be the best way to help us figure out what's going on, thanks!

Hey @gosseti, your solution had been working for me and then stopped as well. This seems to be working for me now:

if (
  process.env.NODE_ENV === `development` ||
  (process.env.NODE_ENV === `production` && process.browser !== true)
) {
  require('../css/main.css')
}

…where main.css is my source stylesheet in the css directory. Within that, I’m using some PostCSS features, but no PostCSS plugins beyond what comes with Gatsby.

The issue was the same as you’d described here https://github.com/gatsbyjs/gatsby/issues/1086#issuecomment-306089833 but now you get client side JS errors (even in production) if you keep the require statement, and if you remove it, you end up with an empty CSS file in public/styles.css (I got tripped up a few times thinking I’d fixed it other ways, but the contents of the public/ don’t seem to get deleted automatically).

With the conditional, you’ll get the stylesheet required by Webpack in development mode, and in production mode when you run gatsby build so the styles actually get compiled, but you won’t have the require causing errors when you visit the index page in the browser.

So this works, but it also seems like it might not be the desired behaviour.

Oh fantastic @kennethormandy! I’ve just given this a go and it works for me!

I had the same issue cause of basscss. I had to import it like this:
@import 'basscss/css/basscss.css';
Can be related to https://github.com/basscss/basscss/issues/213

I am also getting this issue - importing a CSS file from layouts/index.js is fine when running gatsby develop, but I'm getting 'cannot find module' errors for the imported CSS file after running gatsby build.

Whilst the workaround suggested by @kennethormandy works, I suspect there may be an issue with the webpack config for production builds?

gatsby-console-error

@bishsbytes

Use the plugin gatsby-plugin-postcss-sass and install postcss-import.
An example gatsby-config.js:

module.exports = {
  plugins: [
    {
      resolve: 'gatsby-plugin-postcss-sass',
      options: {
        postCssPlugins: [
          require('postcss-import')()
        ]
      }
    }
  ]
}

Then rename your style entry w/ extension .scss and import it within your layout/index.js accordingly.

An example layouts/index.js in a gatsby example that has this working.

Just following up on this getting closed—I’m not sure exactly where this was fixed, but after upgrading to [email protected],I was able to remove the quick fix I posted about from my site. Thanks @KyleAMathews!

Update I think I spoke too soon on this, I’m still getting Cannot find module "../css/styles.css" as an error. Is anyone else able to confirm that the latest Gatsby has fixed this issue for them.

I’ve reverted to using the workaround I mentioned before https://github.com/gatsbyjs/gatsby/issues/1086#issuecomment-324605081 in the meantime. Thanks!

@kennethormandy still have the same issue with gatsby 1.9.158, but your workaround works fine

It looks like the issue is to do with the CSS processing that's happening in the 'build-javascript' step of the webpack config.

Based on the comments in the code, the CSS loader used to return null:

https://github.com/gatsbyjs/gatsby/blob/3ab063feb7997d1c03809cd5ff4d754522df1ac7/packages/gatsby/src/utils/webpack.config.js#L494-L508

However, it now seems to use the Extract Text Plugin with just the CSS loader set to run. This obviously means that if you're using any PostCSS syntax in your CSS (e.g. relative imports), an error will be thrown.

I've tested both making the loader null, and also adding in the PostCSS loader (with the same config as the 'build-css' stage) and both result in successful builds.

Given the code comments, there is obviously some history behind the decision to put a CSS loader back in - so not sure which of the two options is most appropriate here?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brandonmp picture brandonmp  Â·  3Comments

benstr picture benstr  Â·  3Comments

KyleAMathews picture KyleAMathews  Â·  3Comments

ferMartz picture ferMartz  Â·  3Comments

totsteps picture totsteps  Â·  3Comments