Implémentation des modules ES6, comment charger un fichier json


88

J'implémente un exemple de https://github.com/moroshko/react-autosuggest

Le code important est comme ceci:

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);
}

Ce code de copier-coller de l'exemple (qui fonctionne), a une erreur dans mon projet:

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

Si je retire le préfixe json!:

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

De cette façon, je n'ai pas d'erreur au moment de la compilation (l'importation est terminée). Cependant, j'ai des erreurs lorsque je l'exécute:

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

Si je le débogue, je peux voir que la banlieue est un objectc, pas un tableau donc la fonction de filtre n'est pas définie.

Cependant, dans l'exemple, les suggestions sont commentées sont un tableau. Si je réécris des suggestions comme celle-ci, tout fonctionne:

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

Alors ... quel json! préfixe fait dans l'importation?

Pourquoi est-ce que je ne peux pas le mettre dans mon code? Une configuration babel?


1
S'il vous plaît, veuillez réévaluer la réponse choisie, c'est ce que vous voulez vraiment que vous utilisiez des modules ES6. Vous n'avez besoin de rien du tout, juste d'un JS qui comprend les modules ES6. stackoverflow.com/a/53878451/124486
Evan Carroll

Réponses:


156

Tout d'abord, vous devez installer json-loader:

npm i json-loader --save-dev

Ensuite, il y a deux façons de l'utiliser:

  1. Afin d'éviter d'ajouter json-loaderchacun, importvous pouvez ajouter à webpack.configcette ligne:

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

    Puis importez des jsonfichiers comme celui-ci

    import suburbs from '../suburbs.json';
    
  2. Utilisez json-loaderdirectement dans votre import, comme dans votre exemple:

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

Remarque: Au webpack 2.*lieu de mot-clé loadersbesoin d'utiliser rules.,

webpack 2.*utilise également json-loaderpar défaut

* Les fichiers .json sont désormais pris en charge sans le chargeur json. Vous pouvez toujours l'utiliser. Ce n'est pas un changement radical.

v2.1.0-beta.28


1
Merci beaucoup! La documentation de json-loader montrait en fait les paramètres de webpack v2, donc rien n'a fonctionné pour moi (en utilisant v1!). Donc, pour vous tous, utilisez des chargeurs, pas des règles! De plus, changez «utiliser» à l'intérieur de cet objet pour être «chargeur», tout comme cette réponse!
nbkhope

5
Comme @ alexander-t l'a mentionné, vous pouvez maintenant importer des fichiers json sans le chargeur json, mais, si vous rencontrez un problème où le chargeur json n'est pas reconnu, vous devez simplement ajouter un suffixe '-loader' dans la configuration des chargeurs comme ça:{ test: /\.json$/, loader: 'json-loader' }
cvetanov

Pourquoi le json importé n'est-il pas copié dans outDir s'il est importé via dactylographié?
Au revoir StackExchange

17

json-loader ne charge pas le fichier json s'il s'agit d'un tableau, dans ce cas, vous devez vous assurer qu'il a une clé, par exemple

{
    "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 .....
]}

Gentil, je n'y ai pas pensé!
Zachary Dahan

9

Cela fonctionne uniquement sur 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 };
});


0

J'ai trouvé ce fil lorsque je ne pouvais pas charger un json-fileavec ES6 TypeScript 2.6. J'ai continué à recevoir cette erreur:

TS2307 (TS) Impossible de trouver le module 'json-loader! ./ suburbs.json'

Pour le faire fonctionner, je devais d'abord déclarer le module. J'espère que cela fera gagner quelques heures à quelqu'un.

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

...

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

Si j'ai essayé d'omettre loaderde json-loaderje suis l'erreur suivante de webpack:

BREAKING CHANGE: Il n'est plus autorisé d'omettre le suffixe «-loader» lors de l'utilisation de chargeurs. Vous devez spécifier 'json-loader' au lieu de 'json', voir https://webpack.js.org/guides/migrating/#automatic-loader-module-name-extension-removed


0

Nœud v8.5.0 +

Vous n'avez pas besoin de chargeur JSON. Node fournit des modules ECMAScript (prise en charge du module ES6) avec l' --experimental-modulesindicateur, vous pouvez l'utiliser comme ceci

node --experimental-modules myfile.mjs

Alors c'est très simple

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

Ensuite, vous l'aurez lié à la variable myJSON.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.