I have a directory (/data/
) of files that follow the general format of
export default {
name: 'Github',
url: 'https://www.github.com'
}
That's a simple example, in reality each file is an object containing many keys. I initially had one single JSON file that I imported an used, but the more items that I added, the harder it got to maintain in raw text. So I created the directory structure, and then made an entry point that looks like this:
import * as fs from 'fs'
import * as path from 'path'
const normalizedPath = path.join(__dirname, '..', 'data')
const dataFiles = fs.readdirSync(normalizedPath)
let data = []
dataFiles.forEach((file) => {
let fData = require('../data/'+file)
data.push(fData.default)
})
export default data
And outside of gatsby, this works as expected, I can simply import * as data from './dataInporter'
and then inside of data.default
contains an array of the objects. Unfortunately in Gatsby I get
ERROR in ./utils/dataInporter.js
Module not found: Error: Cannot resolve module 'fs'
Is there any way you can think of to work around this?
_As an aside, there is likely a better way to do what I'm trying to do, I'm open to input on that as well._
In Webpack, fs
doesn't exist and you can't access the file system — the React code you're writing is being shipped to the browser where your computer will be but a distant dream :-). This is super easy to forget — it's happened to me more times than I care to admit.
In 1.0 with GraphQL you'll be able to write GraphQL queries in your components to pull in the data you want from the JSON files. In 0.x, you'll want to preprocess the data and write it out to the /pages
directory as individual JSON files that correspond to pages. Then create a json.js
in the /wrappers
directory (like this one) and there you can take in the data from the JSON files and render pages for each of them.
the React code you're writing is being shipped to the browser where your computer will be but a distant dream
<facepalm />
As soon as I read that I realized the problem. haha Excited for GraphQL! That'll be awesome.
Was this solved? Have the same issue and its driving me cr...!!!
@hausinho make sure you're not importing code that tries to use the fs
or "filesystem" node module as node-specific code can't run in the browser hence the error.
the React code you're writing is being shipped to the browser where your computer will be but a distant dream
So i'm most likely completely off here... I thought the benefit of Gatsby was running your code on the server ... so why wouldn't your node server have access to fs?
@alxvallejo you're a bit off. Gatsby runs on the server, all of the code is generated beforehand and sent to you and then rehydrated on the client. That's one of the gatsby's key features.
With that i'm going to expand on what @KyleAMathews said and use Gatsby files to see if this issue can be cleared for you.
When you modify the gatsby-node.js
file for fetching some content for instance from a .md file or wordpress and then use it to generate to create a page based on that content, what you are instructing gatsby to do is go and fetch the contents and manipulate the filesystem and generate the pages when build process is running. Access to the fs module and others will be available to you in this file as you're working with native node-js. In a nutshell you're working on the server. Instructing it to generate the pages that will be served later, by filesystem manipulation.
On the client side, either with pages/components and so on.
What is happening is that you're running the site's content on a sandbox.
The client/browser doesn't care if you have node-js installed or not. For the browser the content recieved is html/js and will be rehydrated and then presented to you. Access to the fs module in here would be a issue has you're running the code like i said on a sandbox.
Just in case you're getting this, the following fixes it for me:
// gatsby-node.js
exports.onCreateWebpackConfig = ({ actions }) => {
actions.setWebpackConfig({
node: {
fs: 'empty'
}
})
}
Thanks, @lucalanca ! That fixed it for me. :-) (I had to add net: 'empty'
as well).
@lucalanca Thanks so much this helped me a lot was starting to get crazy :)
thanks @lucalanca your solution fixed my issue..
Most helpful comment
Just in case you're getting this, the following fixes it for me: