关于javascript:es6模块实现,如何加载json文件

es6 modules implementation, how to load a json file

我正在从https://github.com/moroshko/react-autosuggest实现一个示例

重要代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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);
}

该示例中的复制粘贴代码(有效)在我的项目中出现错误:

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

如果我取出前缀json !:

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

这样,我在编译时不会出错(导入已完成)。
但是执行时出现错误:

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

如果我调试它,我可以看到郊区是一个对象,而不是一个数组,因此未定义过滤器功能。

但是,在示例中,注释建议是一个数组。 如果我这样重写建议,那么一切都会正常:

1
2
3
4
5
6
7
8
9
10
11
  const suggestions = suburbs
  var suggestions = [ {
    'suburb': 'Abbeyard',
    'postcode': '3737'
  }, {
    'suburb': 'Abbotsford',
    'postcode': '3067'
  }, {
    'suburb': 'Aberfeldie',
    'postcode': '3040'
  } ].filter(suburbObj => suburbMatchRegex.test(suburbObj.suburb))

所以...什么json! 在导入中做前缀?

为什么不能将其放入代码中? 一些babel配置?


首先,您需要安装json-loader

1
npm i json-loader --save-dev

然后,有两种使用方式:

  • 为了避免在每个import中添加json-loader,您可以在webpack.config中添加以下行:

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

    然后像这样导入json文件

    1
    import suburbs from '../suburbs.json';
  • 如示例所示,直接在import中使用json-loader

    1
    import suburbs from 'json!../suburbs.json';
  • 注意:
    webpack 2.*中而不是关键字loaders中,需要使用rules

    默认情况下webpack 2.*也使用json-loader

    *.json files are now supported without the json-loader. You may still use it. It's not a breaking change.

    v2.1.0-beta.28


    json-loader如果为数组,则不会加载json文件,在这种情况下,您需要确保它具有密钥,例如

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    {
       "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 .....
    ]}


    这仅适用于React和React Native

    1
    2
    3
    4
    5
    6
    7
    8
    const data = require('./data/photos.json');

    console.log('[-- typeof data --]', typeof data); // object


    const fotos = data.xs.map(item => {
        return { uri: item };
    });

    节点v8.5.0 +

    您不需要JSON加载程序。 Node通过--experimental-modules标志提供ECMAScript模块(支持ES6模块),您可以像这样使用它

    1
    node --experimental-modules myfile.mjs

    那很简单

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

    然后,将其绑定到变量myJSON


    安装json-loader后,现在您可以简单地使用

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

    或者,甚至更简单

    1
    import suburbs from '../suburbs';

    当我无法使用ES6 TypeScript 2.6加载json-file时找到了该线程。我不断收到此错误:

    TS2307 (TS) Cannot find module 'json-loader!./suburbs.json'

    为了使其正常工作,我必须先声明该模块。我希望这可以为某人节省几个小时。

    1
    2
    3
    4
    5
    6
    7
    8
    declare module"json-loader!*" {
      let json: any;
      export default json;
    }

    ...

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

    如果尝试从json-loader省略loader,则从webpack收到以下错误:

    BREAKING CHANGE: It's no longer allowed to omit the '-loader' suffix
    when using loaders.
    You need to specify 'json-loader' instead of 'json',
    see https://webpack.js.org/guides/migrating/#automatic-loader-module-name-extension-removed