¿Cómo importar un archivo json en ecmascript 6?

163

¿Cómo puedo acceder a un archivo json en Ecmascript 6? Lo siguiente no funciona:

import config from '../config.json'

Esto funciona bien si intento importar un archivo JavaScript.

Nikita Jajodia
fuente
44
Esto no tiene nada que ver con ES6 sino con el cargador de módulos que está utilizando. La sintaxis en sí está bien.
Felix Kling
2
La forma más limpia de hacer esto es usarlo webpacky json-loadercon él.
suprita shankar
11
ES6 admite la importación de JSON con la siguiente sintaxis: import * como datos de './example.json';
williamli

Respuestas:

84

Una solución simple:

config.js

export default
{
  // my json here...
}

luego...

import config from '../config.js'

no permite la importación de archivos .json existentes, pero hace un trabajo.

Gilbert
fuente
172
Esto en realidad no responde la pregunta. No puede simplemente convertir su package.json en package.js, por ejemplo. Hay momentos en los que realmente quieres importar JSON, no JS.
curiousdannii
23
No es una solución en absoluto, está exportando un objeto javascript que tiene la misma sintaxis que JSON.
Ma Jerez
Se actualizó el texto del problema; intento de evitar más debates semánticos.
Gilbert
Agregué un "postbuild": "node myscript.js"paso en mi archivo package.json que usa replace-in-file para hacer esto por mí. myscript.js ­ const replace = require('replace-in-file'); const options = { files: '_demo/typedocs/navexReact.td.js', from: /{/, to: 'export default {', }; const convertJsonOutputToJsModule = async () => { try { const changes = await replace(options) console.log('Converted json to module in files:', changes.join(', ')); } catch (error) { console.error('Error occurred:', error); } } convertJsonOutputToJsModule()
StJohn3D
1
"convertirlo a JS" no es una solución sobre cómo importar un archivo JSON. Ese ya no es el archivo JSON. Este es un resultado # 1 de Google para importar JSON, y la respuesta principal es no importar JSON.
Jimbo Jonny
119

En TypeScript o usando Babel, puede importar archivos json en su código.

// Babel

import * as data from './example.json';
const word = data.name;
console.log(word); // output 'testing'

Referencia: https://hackernoon.com/import-json-into-typescript-8d465beded79

williamli
fuente
13
Solo para agregar a esto (importación de json mecanografiado) ahora puede simplemente agregar esto a su tsconfig ... {"compilerOptions": {"resolveJsonModule": true}}
Matt Coady
44
¿Hay algún navegador compatible con esto? Intenté esto en FF actual y obtengo el error Loading failed for the module with source "example.json"; en Chrome aparece "No se pudo cargar el script del módulo: el servidor respondió con un tipo MIME que no es JavaScript de" aplicación / json ". La verificación estricta del tipo MIME se aplica para los scripts del módulo según las especificaciones HTML".
Coderer
@Coderer funciona en todos mis navegadores. ¿Tiene habilitado el soporte ES6 / ES2015?
williamli
2
Se me acaba de ocurrir que cuando dices "en ES6" en realidad te refieres a "en TS". Pensé que estabas hablando del código emitido por, tscpero eso no es realmente lo que está sucediendo. Estoy tratando de ejecutar módulos ES6 de forma nativa en el navegador ( <script type="module">) y los errores anteriores son los que obtienes si ejecutas esa importlínea directamente. Corríjame si me equivoco y de hecho quiere decir que es posible importar desde JSON en ES6 real.
Coderer
3
Cuando dije "¿Hay algún navegador que admita esto?", No quise decir "después de que lo traspilas a través de Babel". El primer artículo que vinculó tiene TS transpilando la importdeclaración a un nodo require()(¡pruébelo!), Y el segundo enlace no dice nada sobre las importaciones JSON. El problema aquí no es con el analizador o el sistema de módulos, es el cargador : el cargador del navegador no resolverá la importación de nada que no sea Javascript. Bajo el capó, siempre debe usar una llamada AJAX (fetch / XHR) y analizar el resultado, incluso si su cadena de herramientas de compilación lo abstrae.
Coderer
67

Lamentablemente, ES6 / ES2015 no admite la carga de JSON a través de la sintaxis de importación del módulo. Pero ...

Hay muchas formas de hacerlo. Dependiendo de sus necesidades, puede investigar cómo leer archivos en JavaScript ( window.FileReaderpodría ser una opción si se está ejecutando en el navegador) o usar algunos otros cargadores como se describe en otras preguntas (suponiendo que esté usando NodeJS).

La forma más simple de la OMI es simplemente colocar el JSON como un objeto JS en un módulo ES6 y exportarlo. De esa manera, puede importarlo donde lo necesite.

También vale la pena señalar si está utilizando Webpack, la importación de archivos JSON funcionará de forma predeterminada (desde entonces webpack >= v2.0.0).

import config from '../config.json';
Simone
fuente
55
No hay necesidad de ponerlo en una cadena. Se llama JSON, no JSSN, después de todo.
un mejor oliver
44
Además, torazaburo explicó en una respuesta eliminada anteriormente: No hay un "sistema de módulos" ES6; Hay una API implementada por un cargador en particular. Cualquier cargador puede hacer lo que quiera, incluida la compatibilidad con la importación de archivos JSON. Por ejemplo, un cargador podría optar por admitir importación foo desde './directory como significado para importar directorio / index.js
CodingIntrigue
55
de hecho, ES6 / ES2015 admiten cargar JSON mediante la sintaxis de importación: import * como datos de './example.json';
williamli
+1 para el recordatorio de que webpack lo hace automáticamente. Sin embargo, tenga cuidado, si tiene "test: /.js/" webpack intentará compilar su archivo json como JavaScript. #fallar. Para solucionarlo, cámbielo para decir "prueba: /.js$/"
Rap
webpack se basa en nodejs, ¿no es así?
Ayyash
20

Estoy usando babel + browserify y tengo un archivo JSON en un directorio ./i18n/locale-en.json con espacio de nombres de traducción (para usar con ngTranslate).

Sin tener que exportar nada del archivo JSON (que por cierto no es posible), podría realizar una importación predeterminada de su contenido con esta sintaxis:

import translationsJSON from './i18n/locale-en';
Francisco Neto
fuente
13

Si está utilizando el nodo, puede:

const fs = require('fs');

const { config } = JSON.parse(fs.readFileSync('../config.json', 'utf8')) // May be incorrect, haven't used fs in a long time

O

const evaluation = require('../config.json');
// evaluation will then contain all props, so evaluation.config
// or you could use:
const { config } = require('../config.json');

Más:

// config.js
{
// json object here
}

// script.js

import { config } from '../config.js';

O

import * from '../config.json'
Usuario anónimo 2903
fuente
9

Dependiendo de las herramientas de compilación y la estructura de datos dentro del archivo JSON, puede requerir importar el archivo default.

import { default as config } from '../config.json';

por ejemplo, uso dentro de Next.js

Pat Migliaccio
fuente
Una nota adicional para TypeScript es asegurarse de que resolveJsonModuleestá trueen usted tsconfig.json.
Pat Migliaccio
1
funcionó a la perfección! Al importar json y almacenarlo en una variable, esta solución funciona.
JP Bala Krishna
1

Un poco tarde, pero me encontré con el mismo problema al intentar proporcionar análisis para mi aplicación web que implicaba enviar la versión de la aplicación basada en la versión package.json.

La configuración es la siguiente: React + Redux, Webpack 3.5.6

El json-loader no está haciendo mucho desde Webpack 2+, así que después de jugar un poco, terminé quitándolo.

La solución que realmente funcionó para mí, fue simplemente usar fetch. Si bien esto probablemente impondrá algunos cambios de código para adaptarse al enfoque asíncrono, funcionó perfectamente, especialmente dado el hecho de que fetch ofrecerá decodificación json sobre la marcha.

Asi que aqui esta:

  fetch('../../package.json')
  .then(resp => resp.json())
  .then((packageJson) => {
    console.log(packageJson.version);
  });

Tenga en cuenta que, dado que estamos hablando de package.json específicamente aquí, el archivo generalmente no vendrá incluido en su compilación de producción (o incluso dev para el caso), por lo que tendrá que usar CopyWebpackPlugin para tener acceso a cuando se usa fetch.

Avram Tudor
fuente
Hipocresía. Fetch no admite archivos locales ... Puede que estés usando polyfill o algo así.
Sapy
Meses @sapy respuesta tardía, pero la API fetch la mayoría absoluta hace de carga apoyo de caminos sin especificar el nombre de host del servidor, así como la carga de rutas relativas. Lo que está pensando es cargar desde file:///URL, que no es lo que está ocurriendo aquí.
Jamie Ridding
1

En un navegador con búsqueda (básicamente todos ahora):

Por el momento, no podemos importarchivos con un tipo MIME JSON, solo archivos con un tipo MIME JavaScript. Podría ser una característica agregada en el futuro ( discusión oficial ).

fetch('./file.json')
  .then(response => response.json())
  .then(obj => console.log(obj))

En Node.js v13.2 +:

Actualmente requiere la --experimental-json-modulesbandera , de lo contrario no es compatible por defecto.

Intenta correr

node --input-type module --experimental-json-modules --eval "import obj from './file.json'; console.log(obj)"

y vea el contenido obj que sale a la consola.

trusktr
fuente