ES6 modules implementation, how to load a json file

JavascriptJsonReactjsWebpack

Javascript Problem Overview


I'm implementing an example from https://github.com/moroshko/react-autosuggest

Important code is like this:

import React, { Component } from 'react';
import suburbs from 'json!../suburbs.json';

function getSuggestions(input, callback) {
  const suggestions = suburbs
    .filter(suburbObj => suburbMatchRegex.test(suburbObj.suburb))
    .sort((suburbObj1, suburbObj2) =>
      suburbObj1.suburb.toLowerCase().indexOf(lowercasedInput) -
      suburbObj2.suburb.toLowerCase().indexOf(lowercasedInput)
    )
    .slice(0, 7)
    .map(suburbObj => suburbObj.suburb);

  // 'suggestions' will be an array of strings, e.g.:
  //   ['Mentone', 'Mill Park', 'Mordialloc']

  setTimeout(() => callback(null, suggestions), 300);
}

This copy-paste code from the example (that works), has an error in my project:

Error: Cannot resolve module 'json' in /home/juanda/redux-pruebas/components

If I take out the prefix json!:

import suburbs from '../suburbs.json';

This way I got not errors at compile time (import is done). However I got errors when I execute it:

Uncaught TypeError: _jsonfilesSuburbsJson2.default.filter is not a function

If I debug it I can see suburbs is an objectc, not an array so filter function is not defined.

However in the example is commented suggestions is an array. If I rewrite suggestions like this, everything works:

  const suggestions = suburbs
  var suggestions = [ {
    'suburb': 'Abbeyard',
    'postcode': '3737'
  }, {
    'suburb': 'Abbotsford',
    'postcode': '3067'
  }, {
    'suburb': 'Aberfeldie',
    'postcode': '3040'
  } ].filter(suburbObj => suburbMatchRegex.test(suburbObj.suburb))

So... what json! prefix is doing in the import?

Why can't I put it in my code? Some babel configuration?

Javascript Solutions


Solution 1 - Javascript

First of all you need to install json-loader:

npm i json-loader --save-dev

Then, there are two ways how you can use it:

  1. In order to avoid adding json-loader in each import you can add to webpack.config this line:

     loaders: [
       { test: /\.json$/, loader: 'json-loader' },
       // other loaders 
     ]
    

    Then import json files like this

     import suburbs from '../suburbs.json';
    
  2. Use json-loader directly in your import, as in your example:

     import suburbs from 'json!../suburbs.json';
    

Note: In webpack 2.* instead of keyword loaders need to use rules.,

also webpack 2.* uses json-loader by default

> *.json files are now supported without the json-loader. You may still use it. It's not a breaking change. > > v2.1.0-beta.28

Solution 2 - Javascript

json-loader doesn't load json file if it's array, in this case you need to make sure it has a key, for example

{
    "items": [
    {
      "url": "https://api.github.com/repos/vmg/redcarpet/issues/598",
      "repository_url": "https://api.github.com/repos/vmg/redcarpet",
      "labels_url": "https://api.github.com/repos/vmg/redcarpet/issues/598/labels{/name}",
      "comments_url": "https://api.github.com/repos/vmg/redcarpet/issues/598/comments",
      "events_url": "https://api.github.com/repos/vmg/redcarpet/issues/598/events",
      "html_url": "https://github.com/vmg/redcarpet/issues/598",
      "id": 199425790,
      "number": 598,
      "title": "Just a heads up (LINE SEPARATOR character issue)",
    },
    ..... other items in array .....
]}

Solution 3 - Javascript

This just works on React & React Native

const data = require('./data/photos.json');

console.log('[-- typeof data --]', typeof data); // object


const fotos = data.xs.map(item => {
	return { uri: item };
});

Solution 4 - Javascript

With json-loader installed, now you can simply use:

import suburbs from '../suburbs.json';

or, even more simply:

import suburbs from '../suburbs';

Solution 5 - Javascript

Found this thread when I couldn't load a json-file with ES6 TypeScript 2.6. I kept getting this error:

> TS2307 (TS) Cannot find module 'json-loader!./suburbs.json'

To get it working I had to declare the module first. I hope this will save a few hours for someone.

declare module "json-loader!*" {
  let json: any;
  export default json;
}

...

import suburbs from 'json-loader!./suburbs.json';

If I tried to omit loader from json-loader I got the following error from webpack:

> BREAKING CHANGE: It's no longer allowed to omit the '-loader' suffix > when using loaders. > You need to specify 'json-loader' instead of 'json', > see https://webpack.js.org/guides/migrating/#automatic-loader-module-name-extension-removed

Solution 6 - Javascript

Node v8.5.0+

You don't need JSON loader. Node provides ECMAScript Modules (ES6 Module support) with the --experimental-modules flag, you can use it like this

node --experimental-modules myfile.mjs

Then it's very simple

import myJSON from './myJsonFile.json';
console.log(myJSON);

Then you'll have it bound to the variable myJSON.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2670996View Question on Stackoverflow
Solution 1 - JavascriptOleksandr T.View Answer on Stackoverflow
Solution 2 - JavascriptDmitrySemenovView Answer on Stackoverflow
Solution 3 - JavascriptKiko SeijoView Answer on Stackoverflow
Solution 4 - JavascriptLet Me Tink About ItView Answer on Stackoverflow
Solution 5 - JavascriptOgglasView Answer on Stackoverflow
Solution 6 - JavascriptEvan CarrollView Answer on Stackoverflow