Как импортировать файл json в ecmascript 6?

163

Как я могу получить доступ к json-файлу в Ecmascript 6? Следующее не работает:

import config from '../config.json'

Это прекрасно работает, если я пытаюсь импортировать файл JavaScript.

Никита Джаджодиа
источник
4
Это не имеет ничего общего с ES6, но с загрузчиком модулей, который вы используете. Сам синтаксис в порядке.
Феликс Клинг
2
Самый чистый способ сделать это - использовать webpackи json-loaderс этим.
Суприта Шанкар
11
ES6 поддерживает импорт JSON со следующим синтаксисом: импорт * как данные из './example.json';
Уильямли

Ответы:

84

Простой обходной путь:

config.js

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

затем...

import config from '../config.js'

не позволяет импортировать существующие файлы .json, но выполняет работу.

Гилберт
источник
172
Это на самом деле не отвечает на вопрос. Вы не можете просто конвертировать ваш package.json в package.js, например. Есть моменты, когда вы хотите действительно импортировать JSON, а не JS.
curiousdannii
23
Совсем не решение, вы экспортируете объект javascript, который имеет тот же синтаксис, что и JSON.
Ма Херес
Обновлен текст вопроса; попытка избежать дальнейших семантических дебатов.
Гилберт
Я добавил "postbuild": "node myscript.js"шаг в мой файл package.json, который использует replace-in-file, чтобы сделать это для меня. 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
«преобразовать его в JS» не является решением для импорта файла JSON. Это больше не файл JSON. Это результат Google № 1 о том, как импортировать JSON, и основной ответ - не импортировать JSON.
Джимбо Джонни
119

В TypeScript или с помощью Babel вы можете импортировать файл json в свой код.

// Babel

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

Ссылка: https://hackernoon.com/import-json-into-typescript-8d465beded79

williamli
источник
13
Просто чтобы добавить к этому (машинописный импорт json), теперь вы можете просто добавить это в свой tsconfig ... {"compilerOptions": {"resolJsonModule": true}}
Matt Coady
4
Какие-нибудь браузеры поддерживают это? Я попробовал это на текущем FF и получил ошибку Loading failed for the module with source "example.json"; в Chrome я получаю сообщение «Не удалось загрузить скрипт модуля: сервер ответил не MIME-типом JavaScript» «application / json». Для скриптов модуля в соответствии со спецификацией HTML требуется строгая проверка типов MIME ».
Coderer
@ Кодер работает на всех моих браузерах. У вас включена поддержка ES6 / ES2015?
Уильямли
2
Мне просто пришло в голову, когда вы говорите «в ES6», вы на самом деле имеете в виду «в TS» - я думал, что вы говорите о коде, испускаемом , tscно на самом деле это не то, что происходит. Я пытаюсь запустить модули ES6 непосредственно в браузере ( <script type="module">), и вышеописанные ошибки - это то, что вы получаете, если запускаете эту importстроку напрямую. Пожалуйста, исправьте меня, если я ошибаюсь, и вы действительно имели в виду, что можно импортировать из JSON в реальной ES6.
Coderer
3
Когда я сказал: «Поддерживают ли это какие-либо браузеры», я не имел в виду «после того, как вы передадите его через Babel». В первой статье, на которую вы ссылаетесь, TS переносит importоператор на узел require()(попробуйте!), А вторая ссылка ничего не говорит об импорте JSON. Проблема здесь не в парсере или модульной системе, а в загрузчике - загрузчик браузера не разрешит импорт для чего-либо другого, кроме Javascript. Изнутри вы всегда должны использовать AJAX-вызов (fetch / XHR) и анализировать результат, даже если ваш набор инструментов построения абстрагирует это.
Coderer
67

К сожалению, ES6 / ES2015 не поддерживает загрузку JSON через синтаксис импорта модуля. Но ...

Есть много способов сделать это. В зависимости от ваших потребностей вы можете посмотреть, как читать файлы в JavaScript (это window.FileReaderможет быть вариант, если вы работаете в браузере) или использовать некоторые другие загрузчики, как описано в других вопросах (при условии, что вы используете NodeJS).

Самый простой способ IMO - это просто поместить JSON как объект JS в модуль ES6 и экспортировать его. Таким образом, вы можете просто импортировать его туда, где вам это нужно.

Также стоит отметить, что если вы используете Webpack, импорт файлов JSON будет работать по умолчанию (поскольку webpack >= v2.0.0).

import config from '../config.json';
Симона
источник
5
Там нет необходимости помещать его в строку. Это называется JSON, а не JSSN, в конце концов.
лучший Оливер
4
Также Торазабуро объяснил в ранее удаленном ответе: нет ES6 «модульная система»; есть API, который реализуется определенным загрузчиком. Любой загрузчик может делать все, что захочет, включая поддержку импорта файлов JSON. Например, загрузчик может выбрать поддержку импорта foo из './directory как значение для импорта directory / index.js
CodingIntrigue
5
фактически ES6 / ES2015 поддерживает загрузку JSON с помощью синтаксиса импорта: импорт * как данные из './example.json';
Уильямли
+1 за напоминание, что webpack делает это автоматически. Осторожно, если у вас есть пакет «test: /.js/», он попытается скомпилировать ваш файл json как JavaScript. #потерпеть поражение. Чтобы исправить это, измените его на «test: /.js$/»
Rap
Webpack основан на nodejs, не так ли?
Ayyash
20

Я использую babel + browserify, и у меня есть файл JSON в каталоге ./i18n/locale-en.json с пространством имен переводов (для использования с ngTranslate).

Без необходимости экспортировать что-либо из файла JSON (что, кстати, невозможно), я мог бы сделать импорт его содержимого по умолчанию с помощью следующего синтаксиса:

import translationsJSON from './i18n/locale-en';
Франциско Нето
источник
13

Если вы используете узел, вы можете:

const fs = require('fs');

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

ИЛИ

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

Else:

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

// script.js

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

ИЛИ

import * from '../config.json'
Анонимный Посетитель 2903
источник
9

В зависимости от инструментов сборки и структуры данных в файле JSON может потребоваться импорт default.

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

например, использование в Next.js

Пэт Мильяччио
источник
Добавлено примечание для TypeScript, чтобы убедиться, resolveJsonModuleчто trueв вас tsconfig.json.
Пэт Мильяччио
1
работал отлично! При импорте json и сохранении его в переменной это решение работает.
JP Бала Кришна
1

Немного поздно, но я наткнулся на ту же проблему, пытаясь предоставить аналитику для моего веб-приложения, которая включала отправку версии приложения на основе версии package.json.

Конфигурация выглядит следующим образом: React + Redux, Webpack 3.5.6

Начиная с Webpack 2+, json-загрузчик мало что делает, поэтому, поигравшись с ним, я удалил его.

Решение, которое действительно работало для меня, было просто использовать fetch. Хотя это, скорее всего, приведет к некоторым изменениям кода для адаптации к асинхронному подходу, он работает отлично, особенно с учетом того факта, что fetch будет предлагать декодирование json на лету.

Итак, вот оно:

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

Имейте в виду, что, поскольку речь идет именно о package.json, этот файл обычно не входит в комплект вашей производственной сборки (или даже в этом отношении dev), поэтому вам придется использовать CopyWebpackPlugin для доступа к это при использовании fetch.

Аврам Тюдор
источник
Не могу. Fetch не поддерживает локальный файл ... Возможно, вы используете polyfill или что-то еще.
Сапи
@sapy месяцев поздно ответить, но принести API большинство абсолютно делает поддерживает загрузку из путей без указания имени хоста сервера, а также загрузку с относительными путями. То, о чем вы думаете, это загрузка с file:///URL, а не то, что здесь происходит.
Джейми Риддинг
1

В браузере с fetch (в основном все они сейчас):

В настоящее время мы не можем importфайлы с MIME-типом JSON, только файлы с MIME-типом JavaScript. Это может быть добавлено в будущем ( официальное обсуждение ).

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

В Node.js v13.2 +:

В настоящее время требуется --experimental-json-modulesфлаг , в противном случае он не поддерживается по умолчанию.

Попробуйте запустить

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

и увидеть содержимое obj, выведенное на консоль.

trusktr
источник