Реализация модулей ES6, как загрузить файл json

88

Реализую пример из https://github.com/moroshko/react-autosuggest

Важный код выглядит так:

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

Этот код копирования и вставки из примера (который работает) имеет ошибку в моем проекте:

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

Если вынуть приставку json !:

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

Таким образом, я не получал ошибок во время компиляции (импорт завершен). Однако при его выполнении у меня возникли ошибки:

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

Если я его отлаживаю, я вижу, что пригород - это объект, а не массив, поэтому функция фильтрации не определена.

Однако в примере комментируемые предложения представляют собой массив. Если я перепишу такие предложения, все заработает:

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

Итак ... какой json! префикс делает в импорте?

Почему я не могу вставить это в свой код? Какая-то конфигурация бабеля?

пользователь2670996
источник
1
Пожалуйста, пожалуйста, еще раз оцените выбранный ответ, это действительно хотите, чтобы вы использовали модули ES6. Вам вообще ничего не нужно, только JS, который понимает модули ES6. stackoverflow.com/a/53878451/124486
Эван Кэрролл

Ответы:

156

В первую очередь необходимо установить json-loader:

npm i json-loader --save-dev

Тогда есть два способа его использования:

  1. Чтобы избежать добавления json-loaderкаждого, importвы можете добавить в webpack.configэту строку:

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

    Затем импортируйте jsonтакие файлы

    import suburbs from '../suburbs.json';
    
  2. Используйте json-loaderпрямо в своем import, как в вашем примере:

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

Примечание: В webpack 2.*вместо ключевого слова loadersнужно использовать rules,.

также webpack 2.*использует json-loaderпо умолчанию

Файлы * .json теперь поддерживаются без json-loader. Вы все еще можете его использовать. Это не критическое изменение.

v2.1.0-beta.28

Александр Т.
источник
1
Спасибо огромное! Документация для json-loader фактически показывала настройки для webpack v2, поэтому у меня ничего не работало (с использованием v1!). Так что для всех вас, используйте загрузчики, а не правила! Кроме того, измените «использование» внутри этого объекта на «загрузчик», как в этом ответе!
nbkhope
5
Как упоминалось в @ alexander-t, теперь вы можете импортировать файлы json без json-loader, но, если вы столкнетесь с проблемой, когда json-loader не распознается, вы должны просто добавить суффикс '-loader' в конфигурацию загрузчиков вот так:{ test: /\.json$/, loader: 'json-loader' }
cvetanov
Почему импортированный json не копируется в outDir, если он импортируется через машинописный текст?
Прощай, StackExchange
17

json-loader не загружает файл json, если это массив, в этом случае вам нужно убедиться, что у него есть ключ, например

{
    "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 .....
]}
ДмитрийСеменов
источник
Хорошенькая, не думал об этом!
Zachary Dahan
9

Это работает только на 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

После json-loaderустановки теперь вы можете просто использовать:

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

или, что еще проще:

import suburbs from '../suburbs';
Позвольте мне подумать об этом
источник
0

Нашел эту ветку, когда не смог загрузить с json-fileпомощью ES6 TypeScript 2.6. Я продолжал получать эту ошибку:

TS2307 (TS) Не удается найти модуль json-loader! ./ suburbs.json

Чтобы он заработал, мне сначала пришлось объявить модуль. Надеюсь, это кому-то сэкономит несколько часов.

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

...

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

Если бы я попытался опустить loaderот json-loaderя получил следующее сообщение об ошибке из webpack:

ПРЕРЫВНОЕ ИЗМЕНЕНИЕ: больше не разрешается опускать суффикс «-loader» при использовании загрузчиков. Вам нужно указать json-loader вместо json, см. Https://webpack.js.org/guides/migrating/#automatic-loader-module-name-extension-removed

Огглас
источник
0

Узел v8.5.0 +

Вам не нужен загрузчик JSON. Node предоставляет модули ECMAScript (поддержка модулей ES6) с --experimental-modulesфлагом, вы можете использовать его следующим образом

node --experimental-modules myfile.mjs

Тогда это очень просто

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

Затем вы привяжете его к переменной myJSON.

Эван Кэрролл
источник