Jak zaimportować plik JSON w ecmascript 6?

162

Jak mogę uzyskać dostęp do pliku JSON w Ecmascript 6? Poniższe nie działa:

import config from '../config.json'

Działa to dobrze, jeśli spróbuję zaimportować plik JavaScript.

Nikita Jajodia
źródło
4
Nie ma to nic wspólnego z ES6, ale z używanym programem ładującym moduły. Sama składnia jest w porządku.
Felix Kling
2
Najczystszym sposobem na to jest użycie webpacki json-loaderprzy jego pomocy.
suprita shankar
11
ES6 obsługuje importowanie JSON z następującą składnią: import * jako dane z './example.json';
williamli

Odpowiedzi:

84

Proste obejście:

config.js

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

następnie...

import config from '../config.js'

nie pozwala na import istniejących plików .json, ale wykonuje swoje zadanie.

Gilbert
źródło
170
To właściwie nie odpowiada na pytanie. Nie możesz na przykład po prostu przekonwertować pliku package.json na package.js. Są chwile, kiedy naprawdę chcesz zaimportować JSON, a nie JS.
curiousdannii
23
Nie jest to w ogóle rozwiązanie, eksportujesz obiekt javascript, który ma taką samą składnię jak JSON.
Ma Jerez
Zaktualizowano treść wydania; próba uniknięcia dalszych debat semantycznych.
Gilbert
Dodałem "postbuild": "node myscript.js"krok w moim pliku package.json, który używa funkcji zamiany w pliku, aby zrobić to za mnie. 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
„Konwertuj to na JS” nie jest rozwiązaniem w przypadku importowania pliku JSON. To już nie jest plik JSON. To najlepszy wynik Google dotyczący importowania JSON, a główna odpowiedź brzmi: nie importuj JSON.
Jimbo Jonny
119

W języku TypeScript lub przy użyciu Babel możesz zaimportować plik JSON w swoim kodzie.

// Babel

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

Źródła: https://hackernoon.com/import-json-into-typescript-8d465beded79

williamli
źródło
13
Aby dodać to do tego (importowanie json do maszynopisu), możesz teraz po prostu dodać to do swojego tsconfig ... {"compilerOptions": {"solutionJsonModule": true}}
Matt Coady
4
Czy jakieś przeglądarki to obsługują? Próbowałem tego na obecnym FF i otrzymałem błąd Loading failed for the module with source "example.json"; w przeglądarce Chrome pojawia się komunikat „Nie udało się załadować skryptu modułu: serwer odpowiedział typem MIME innym niż JavaScript„ application / json ”. Ścisłe sprawdzanie typu MIME jest wymuszane dla skryptów modułu zgodnie ze specyfikacją HTML”.
Coderer
@Coderer działa na wszystkich moich przeglądarkach. Czy masz włączoną obsługę ES6 / ES2015?
williamli
2
Przyszło mi do głowy, kiedy mówisz „w ES6”, tak naprawdę masz na myśli „w TS” - myślałem, że mówisz o kodzie emitowanym przez, tscale tak naprawdę nie jest to, co się dzieje. Próbuję uruchomić moduły ES6 natywnie w przeglądarce ( <script type="module">), a powyższe błędy są tym, co otrzymujesz, jeśli uruchomisz tę importlinię bezpośrednio. Proszę mnie poprawić, jeśli się mylę, a faktycznie chodziło Ci o to, że można importować z formatu JSON w rzeczywistym ES6.
Coderer,
3
Kiedy powiedziałem „Czy jakieś przeglądarki to obsługują”, nie miałem na myśli „po transpozycji przez Babel”. W pierwszym powiązanym artykule TS transpiluje importinstrukcję do węzła require()(spróbuj!), A drugie łącze nie mówi nic o imporcie JSON. Problem tutaj nie dotyczy parsera ani systemu modułów, jest to moduł ładujący - moduł ładujący przeglądarki nie rozwiąże importu niczego innego niż JavaScript. Pod maską zawsze musisz użyć wywołania AJAX (fetch / XHR) i przeanalizować wynik, nawet jeśli twój łańcuch narzędzi kompilacji to abstrahuje.
Coderer,
67

Niestety ES6 / ES2015 nie obsługuje ładowania JSON poprzez składnię importu modułu. Ale ...

Można to zrobić na wiele sposobów. W zależności od potrzeb możesz sprawdzić, jak czytać pliki w JavaScript ( window.FileReadermoże to być opcja, jeśli używasz przeglądarki) lub użyć innych programów ładujących, jak opisano w innych pytaniach (zakładając, że używasz NodeJS).

Najprostszym sposobem IMO jest prawdopodobnie umieszczenie JSON jako obiektu JS w module ES6 i wyeksportowanie go. W ten sposób możesz po prostu zaimportować go tam, gdzie go potrzebujesz.

Warto również zauważyć, że jeśli używasz Webpack, importowanie plików JSON będzie działać domyślnie (od webpack >= v2.0.0).

import config from '../config.json';
Simone
źródło
5
Nie ma potrzeby umieszczania go w String. W końcu nazywa się JSON, a nie JSSN.
lepszy oliver
4
Torazaburo wyjaśnił również w poprzednio usuniętej odpowiedzi: Nie ma „systemu modułów” ES6; istnieje API, które jest implementowane przez określony program ładujący. Każdy program ładujący może robić wszystko, co chce, w tym wspierać import plików JSON. Na przykład program ładujący może wybrać obsługę importu foo z './directory, co oznacza importowanie katalogu / index.js
CodingIntrigue
5
w rzeczywistości ES6 / ES2015 obsługują ładowanie JSON poprzez składnię importu: import * jako dane z './example.json';
williamli
+1 za przypomnienie, że webpack robi to automatycznie. Uważaj jednak, jeśli masz pakiet webpack „test: /.js/”, spróbuje skompilować Twój plik json jako JavaScript. #zawieść. Aby to naprawić, zmień to na „test: /.js$/”
Rap,
webpack jest oparty na nodejs, prawda?
Ayyash
20

Używam babel + browserify i mam plik JSON w katalogu ./i18n/locale-en.json z przestrzenią nazw tłumaczeń (do użycia z ngTranslate).

Bez konieczności eksportowania czegokolwiek z pliku JSON (co przy okazji nie jest możliwe), mogłem dokonać domyślnego importu jego zawartości z następującą składnią:

import translationsJSON from './i18n/locale-en';
Francisco Neto
źródło
13

Jeśli używasz węzła, możesz:

const fs = require('fs');

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

LUB

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

Jeszcze:

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

// script.js

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

LUB

import * from '../config.json'
Użytkownik anonimowy 2903
źródło
9

W zależności od narzędzi kompilacji i struktury danych w pliku JSON może wymagać zaimportowania pliku default.

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

np. użycie w ramach Next.js

Pat Migliaccio
źródło
Dodatkowa uwaga dotycząca TypeScript ma zapewnić, że resolveJsonModulejest truew tobie tsconfig.json.
Pat Migliaccio
1
działało idealnie! To rozwiązanie działa podczas importowania json i przechowywania go w zmiennej.
JP Bala Krishna
1

Trochę późno, ale właśnie natknąłem się na ten sam problem, próbując dostarczyć dane analityczne dla mojej aplikacji internetowej, które obejmowały wysyłanie wersji aplikacji na podstawie wersji package.json.

Konfiguracja wygląda następująco: React + Redux, Webpack 3.5.6

Moduł ładujący json nie robi zbyt wiele od czasu Webpack 2+, więc po kilku majstrowaniu przy nim skończyło się na jego usunięciu.

Rozwiązaniem, które faktycznie zadziałało, było po prostu użycie funkcji pobierania. Chociaż najprawdopodobniej wymusi to pewne zmiany w kodzie, aby dostosować się do podejścia asynchronicznego, zadziałało doskonale, zwłaszcza biorąc pod uwagę fakt, że pobieranie będzie oferować dekodowanie json w locie.

Więc oto jest:

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

Należy pamiętać, że ponieważ mówimy tutaj konkretnie o package.json, plik zwykle nie będzie dołączony do twojej kompilacji produkcyjnej (lub nawet dev, jeśli o to chodzi), więc będziesz musiał użyć CopyWebpackPlugin, aby mieć dostęp do podczas korzystania z funkcji pobierania.

Avram Tudor
źródło
Żargon. Funkcja Fetch nie obsługuje pliku lokalnego ... Być może używasz wypełnienia polyfill lub czegoś podobnego.
sapy
Miesiące @sapy późno odpowiadać, ale API pobrać najbardziej absolutnie nie support załadunek od ścieżek bez podania nazwy hosta serwera, a także załadunek z względnymi ścieżkami. To, o czym myślisz, to ładowanie z file:///adresów URL, a nie to, co się tutaj dzieje.
Jamie Ridding
1

W przeglądarce z funkcją pobierania (w zasadzie wszystkie teraz):

W tej chwili nie możemy importplików z typem MIME JSON, tylko pliki z typem MIME JavaScript. Może to być funkcja dodana w przyszłości ( oficjalna dyskusja ).

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

W Node.js 13.2 +:

Obecnie wymaga --experimental-json-modulesflagi , w przeciwnym razie nie jest obsługiwana domyślnie.

Spróbuj biegać

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

i zobacz zawartość obj wyprowadzoną do konsoli.

trusktr
źródło