Implementazione dei moduli ES6, come caricare un file json


87

Sto implementando un esempio da https://github.com/moroshko/react-autosuggest

Il codice importante è così:

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

Questo codice copia-incolla dell'esempio (che funziona) ha un errore nel mio progetto:

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

Se tolgo il prefisso json !:

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

In questo modo non ho ricevuto errori in fase di compilazione (l'importazione è terminata). Tuttavia ho ricevuto errori quando lo eseguo:

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

Se eseguo il debug, posso vedere che suburbs è un objectc, non un array, quindi la funzione di filtro non è definita.

Tuttavia, nell'esempio i suggerimenti commentati sono un array. Se riscrivo suggerimenti come questo, tutto funziona:

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

Allora ... che json! prefisso sta facendo nell'importazione?

Perché non riesco a inserirlo nel mio codice? Qualche configurazione di Babele?


1
Per favore, per favore, per favore rivaluta la risposta scelta che in realtà vuoi che tu stia usando i moduli ES6. Non hai bisogno di nulla, solo un JS che capisca i moduli ES6. stackoverflow.com/a/53878451/124486
Evan Carroll

Risposte:


156

Prima di tutto devi installare json-loader:

npm i json-loader --save-dev

Quindi, ci sono due modi per usarlo:

  1. Per evitare di aggiungere json-loaderciascuno importdi essi puoi aggiungere a webpack.configquesta riga:

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

    Quindi importa jsonfile come questo

    import suburbs from '../suburbs.json';
    
  2. Usa json-loaderdirettamente nel tuo import, come nel tuo esempio:

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

Nota: In webpack 2.*posto di parola chiave loadersnecessità di utilizzo rules,.

webpack 2.*utilizza anche json-loaderper impostazione predefinita

I file * .json sono ora supportati senza il json-loader. Puoi ancora usarlo. Non è un cambiamento radicale.

v2.1.0-beta.28


1
Grazie mille! La documentazione per json-loader mostrava effettivamente le impostazioni per webpack v2, quindi niente ha funzionato per me (usando v1!). Quindi, per tutti voi là fuori, usate caricatori, non regole! Inoltre, cambia 'use' all'interno di quell'oggetto in 'loader', proprio come questa risposta!
nbkhope

5
Come menzionato da @ alexander-t, ora puoi importare file json senza json-loader, ma, se incontri un problema in cui il json-loader non viene riconosciuto, dovresti semplicemente aggiungere un suffisso '-loader' nella configurazione del caricatore in questo modo:{ test: /\.json$/, loader: 'json-loader' }
cvetanov

Perché il json importato non viene copiato in outDir se viene importato tramite dattiloscritto?
Arrivederci StackExchange

17

json-loader non carica il file json se è array, in questo caso devi assicurarti che abbia una chiave, ad esempio

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

Bello, non ci ho pensato!
Zachary Dahan

9

Funziona solo su 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 };
});

2

Con json-loaderinstallato, ora puoi semplicemente usare:

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

o, ancora più semplicemente:

import suburbs from '../suburbs';

0

Ho trovato questo thread quando non sono riuscito a caricare un file json-filecon ES6 TypeScript 2.6. Ho continuato a ricevere questo errore:

TS2307 (TS) Impossibile trovare il modulo "json-loader! ./ suburbs.json"

Per farlo funzionare ho dovuto prima dichiarare il modulo. Spero che questo farà risparmiare qualche ora a qualcuno.

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

...

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

Se ho provato a omettere loaderda json-loaderho ricevuto il seguente errore da webpack:

MODIFICA DI BREAKING: Non è più consentito omettere il suffisso "-loader" quando si utilizzano i caricatori. Devi specificare "json-loader" invece di "json", vedi https://webpack.js.org/guides/migrating/#automatic-loader-module-name-extension-removed


0

Nodo v8.5.0 +

Non hai bisogno del caricatore JSON. Node fornisce i moduli ECMAScript (supporto modulo ES6) con il --experimental-modulesflag, puoi usarlo in questo modo

node --experimental-modules myfile.mjs

Allora è molto semplice

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

Quindi lo legherai alla variabile myJSON.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.