Implementación de módulos ES6, cómo cargar un archivo json

87

Estoy implementando un ejemplo de https://github.com/moroshko/react-autosuggest

El código importante es así:

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

Este código de copiar y pegar del ejemplo (que funciona), tiene un error en mi proyecto:

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

Si saco el prefijo json !:

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

De esta manera no obtuve errores en el momento de la compilación (la importación está lista). Sin embargo, obtuve errores cuando lo ejecuto:

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

Si lo depuro, puedo ver que los suburbios son un objectc, no una matriz, por lo que la función de filtro no está definida.

Sin embargo, en el ejemplo se comentan las sugerencias es una matriz. Si reescribo sugerencias como esta, todo funciona:

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

Entonces ... ¡qué json! prefijo está haciendo en la importación?

¿Por qué no puedo ponerlo en mi código? ¿Alguna configuración de babel?

usuario2670996
fuente
1
Por favor, por favor, vuelva a evaluar la respuesta elegida que realmente quiere que esté usando los módulos ES6. No necesita nada en absoluto, solo un JS que entienda los módulos ES6. stackoverflow.com/a/53878451/124486
Evan Carroll

Respuestas:

156

Primero que nada necesitas instalar json-loader:

npm i json-loader --save-dev

Entonces, hay dos formas de usarlo:

  1. Para evitar agregar json-loaderen cada importuno, puede agregar a webpack.configesta línea:

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

    Luego importa jsonarchivos como este

    import suburbs from '../suburbs.json';
    
  2. Úselo json-loaderdirectamente en su import, como en su ejemplo:

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

Nota: En webpack 2.*lugar de la palabra clave es loadersnecesario utilizar rules.,

también webpack 2.*usa json-loaderpor defecto

Los archivos * .json ahora son compatibles sin json-loader. Aún puede usarlo. No es un cambio rotundo.

v2.1.0-beta.28

Oleksandr T.
fuente
1
Muchas gracias! La documentación para json-loader en realidad mostraba la configuración para webpack v2, así que nada funcionó para mí (¡usando v1!). Entonces, para todos ustedes, use cargadores, ¡no reglas! Además, cambie 'uso' dentro de ese objeto para que sea 'cargador', ¡como esta respuesta!
nbkhope
5
Como mencionó @ alexander-t, ahora puede importar archivos json sin json-loader, pero, si se encuentra con un problema en el que no se reconoce el json-loader, simplemente debe agregar un sufijo '-loader' en la configuración del cargador así:{ test: /\.json$/, loader: 'json-loader' }
cvetanov
¿Por qué el json importado no se copia en outDir si se importa a través de mecanografiado?
Adiós StackExchange
17

json-loader no carga el archivo json si es una matriz, en este caso debe asegurarse de que tenga una clave, por ejemplo

{
    "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 .....
]}
DmitrySemenov
fuente
Bonito, ¡no pensé en eso!
Zachary Dahan
9

Esto solo funciona en 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 };
});
Kiko Seijo
fuente
2

Con json-loaderinstalado, ahora puede simplemente usar:

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

o, aún más simplemente:

import suburbs from '../suburbs';
Déjame pensar en ello
fuente
0

Encontré este hilo cuando no pude cargar un archivo json-filecon ES6 TypeScript 2.6. Seguí recibiendo este error:

TS2307 (TS) No se puede encontrar el módulo 'json-loader! ./ suburbs.json'

Para que funcione, primero tuve que declarar el módulo. Espero que esto le ahorre algunas horas a alguien.

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

...

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

Si intenté omitir loaderde json-loader, obtuve el siguiente error de webpack:

CAMBIO IMPORTANTE: Ya no se permite omitir el sufijo '-loader' cuando se utilizan cargadores. Debe especificar 'json-loader' en lugar de 'json', consulte https://webpack.js.org/guides/migrating/#automatic-loader-module-name-extension-removed

Ogglas
fuente
0

Nodo v8.5.0 +

No necesita el cargador JSON. El nodo proporciona módulos ECMAScript (soporte del módulo ES6) con la --experimental-modulesbandera, puede usarlo así

node --experimental-modules myfile.mjs

Entonces es muy simple

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

Entonces lo tendrás vinculado a la variable myJSON.

Evan Carroll
fuente