Home > Software design >  Error when attempting to import JSON into a React component: "You may need an appropriate loade
Error when attempting to import JSON into a React component: "You may need an appropriate loade

Time:11-15

I'm experimenting with Webpack and React, trying out new loaders to see how they work. Here's my webpack.config.js:

const webpack = require('webpack')
const path = require('path')

module.exports = {
  entry: "./src/index.js",
  mode: "development",
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        loader: "babel-loader",
        options: { presets: ["@babel/env"] }
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"]
      },
      {
        test: /\.txt$/,
        use: 'raw-loader',
      },
      {
        test: /\.json$/,
        use: 'json-loader',
      }
    ],
  },
  resolve: {
    extensions: ["*", ".js", ".jsx"],
  },
  output: {
    path: path.resolve(__dirname, "dist/"),
    publicPath: "/dist/",
    filename: "bundle.js",
  },
  plugins: [new webpack.HotModuleReplacementPlugin()],
  devServer: {
    contentBase: path.join(__dirname, "public/"),
    port: 3000,
    hotOnly: true,
    publicPath: "http://localhost:3000/dist/",
  }
}

As you can see, json-loader is included in the 'rules' section.

I have "json-loader": "^0.5.7" installed under the 'dependencies' section of my package.json, and have run yarn install to make sure it's included in my node_modules directory.

I have a simple 'foo.json' file in my /src directory which looks like this:

{
    "foo": "bar",
    "bazz": {
        "buzz": [1, 2, 3, 4, 5]
    }
}

And I am importing this JSON into a React component:

import React from "react";
import "./App.css";
import text from './foo.txt';
import myJson from './foo.json'

const App = () => {
  const buzz = myJson.bazz.buzz;

  return (
    <div className="App">
      <h1> Hello, World! </h1>
      {
        text.split("\n").map((item) => <p>{item}</p> )
      }
      <ul>
      { buzz.map((item) => <li>{item}</li> )}
      </ul>
    </div>
  );
}

export default App;

However, when I run yarn run build, I get the following error:

ERROR in ./src/foo.json
Module parse failed: Unexpected token m in JSON at position 0 while parsing near 'module.exports = {"f...'
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token m in JSON at position 0 while parsing near 'module.exports = {"f...'
    at JSON.parse (<anonymous>)
    at parseJson (/Users/richiethomas/Desktop/Workspace/InvestmentTime/new-react-app/node_modules/json-parse-better-errors/index.js:7:17)
    at JsonParser.parse (/Users/richiethomas/Desktop/Workspace/InvestmentTime/new-react-app/node_modules/webpack/lib/JsonParser.js:16:16)
    at /Users/richiethomas/Desktop/Workspace/InvestmentTime/new-react-app/node_modules/webpack/lib/NormalModule.js:445:32
    at /Users/richiethomas/Desktop/Workspace/InvestmentTime/new-react-app/node_modules/webpack/lib/NormalModule.js:327:12
    at /Users/richiethomas/Desktop/Workspace/InvestmentTime/new-react-app/node_modules/loader-runner/lib/LoaderRunner.js:373:3
    at iterateNormalLoaders (/Users/richiethomas/Desktop/Workspace/InvestmentTime/new-react-app/node_modules/loader-runner/lib/LoaderRunner.js:214:10)
    at iterateNormalLoaders (/Users/richiethomas/Desktop/Workspace/InvestmentTime/new-react-app/node_modules/loader-runner/lib/LoaderRunner.js:221:10)
    at /Users/richiethomas/Desktop/Workspace/InvestmentTime/new-react-app/node_modules/loader-runner/lib/LoaderRunner.js:236:3
    at runSyncOrAsync (/Users/richiethomas/Desktop/Workspace/InvestmentTime/new-react-app/node_modules/loader-runner/lib/LoaderRunner.js:130:11)
    at iterateNormalLoaders (/Users/richiethomas/Desktop/Workspace/InvestmentTime/new-react-app/node_modules/loader-runner/lib/LoaderRunner.js:232:2)
    at Array.<anonymous> (/Users/richiethomas/Desktop/Workspace/InvestmentTime/new-react-app/node_modules/loader-runner/lib/LoaderRunner.js:205:4)
    at Storage.finished (/Users/richiethomas/Desktop/Workspace/InvestmentTime/new-react-app/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:55:16)
    at /Users/richiethomas/Desktop/Workspace/InvestmentTime/new-react-app/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:91:9
    at /Users/richiethomas/Desktop/Workspace/InvestmentTime/new-react-app/node_modules/graceful-fs/graceful-fs.js:123:16
    at FSReqCallback.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:63:3)
 @ ./src/App.js 4:0-32 7:13-19
 @ ./src/index.js

It says I need an appropriate loader to handle this type, but isn't that what json-loader is supposed to do? Do I have a setup or syntax error somewhere?

I have raw-loader installed and I'm able to import and render the text from foo.txt successfully, so I'm confused why json-loader isn't similarly straightforward for me.

Thanks.

EDIT:

I also get this same error when I use const myJson = require('./foo.json'); instead of import myJson from './foo.json'.

Also interestingly, when I remove json-loader from my Webpack config, both require and import work as expected.

So, my immediate problem of getting the JSON to load is solved, but I'd still like to know why json-loader wasn't working the way I expected it to.

EDIT #2: From the docs, I do see that there is special require syntax for inline-importing a JSON file via json-loader:

const json = require('json-loader!./file.json');

I tried the following, but it also didn't work:

const myJson = require('json-loader!./foo.json');

CodePudding user response:

From the error message posted

Module parse failed: Unexpected token m in JSON at position 0 while parsing near 'module.exports = {"f...'
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token m in JSON at position 0 while parsing near 'module.exports = {"f...'

It looks like the most important part has been truncated a bit.

Note that the first token according to webpack's parser of the posted file is a CommonJS export.

Many webpack loaders are string to string transforms. One after another. The default webpack JSON handling is to convert the file into a CommonJS/ESM as a string. json-loader is probably expecting raw JSON, and is instead getting the string form of a CommonJS module of the same.

https://webpack.js.org/migrate/4/#json-and-loaders suggests removing the JSON loader unless you have special file endings for JSON files.

  • Related