导入json文件时出现Webpack错误

aza*_*gru 3 javascript json webpack

这是一个破坏的简单测试用例:

首先,从Node保存一个json文件:

const fs = require('fs')

let test = {
  foo: [
    { 1: 'a'},
    { 2: 'b'}
  ]
};

fs.writeFileSync('./test.json', JSON.stringify(test), 'utf-8');
Run Code Online (Sandbox Code Playgroud)

然后,尝试将此json导入到由Webpack处理的js文件中(我使用的是最新版的Webpack,3.4.1):

import test from './test.json';

console.log(test);
Run Code Online (Sandbox Code Playgroud)

失败并显示以下错误:

ERROR in ./test.json                                       
Module build failed: SyntaxError: Unexpected token, expected ; (1:6)

> 1 | {"foo":[{"1":"a"},{"2":"b"}]}
Run Code Online (Sandbox Code Playgroud)

控制台输出所指向的令人反感的字符是“ foo”后的冒号。

我的Webpack配置非常简单,只有以下module选项:

  module: {
    rules: [
      {
        test: /\.js/,
        exclude: [ path.resolve(__dirname, 'node_modules') ],
        loader: 'babel-loader'
      },
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: "css-loader"
        })
      }
    ]
  },
Run Code Online (Sandbox Code Playgroud)

感到困惑,我打开了JSON加载程序页面,该页面通知我:

由于webpack> = v2.0.0,默认情况下将导入JSON文件。

由于我使用的是Webpack 3.4.1版,因此我认为json-loader是不必要的。尽管如此,出于绝望,我将以下规则添加到Webpack config的modules字段中:

  {
    test: /\.json/,
    loader: 'json-loader'
  }
Run Code Online (Sandbox Code Playgroud)

这实际上有效!json文件已加载,错误消失了。

所以我的问题是:我在尝试导入json文件时Webpack做错了吗,还是最新的Webpack在导入json文件方面被打破了?

Mic*_*ngo 5

您用于.js规则的正则表达式也匹配.json,因为您要查找的只是.js路径中的任意位置。以下所有内容都将成功匹配(大多数都不可能被导入甚至不存在):

file.js
file.json
file.js.backup
.js/file.css
.jshintrc
Run Code Online (Sandbox Code Playgroud)

test.json匹配正则表达式,这意味着您正在应用babel-loader它。Babel仅接受JavaScript,而JSON将无法解析。它抱怨冒号(:)的原因是因为使用ES6您可以使用大括号创建一个新范围。例如:

const msg = "Outer";

// Entering new scope
{
  // msg is free in this scope, shadows the outer one.
  const msg = "Inner";
  console.log(msg); // Inner
}
// Exiting scope

console.log(msg); // Outer

// SyntaxError: Identifier 'msg' has already been declared
const msg = "Re-definition";
Run Code Online (Sandbox Code Playgroud)

我认为在JavaScript中并没有很多用途,但是在其他语言中(例如Rust)使用的次数更多。JSON的大括号开始了一个新的作用域,而不是一个对象,并且JavaScript中的字符串后的冒号无效。

为了不适用babel-loader.json您只需要匹配的文件.js在路径的末尾,通过使用$锚(字符串的结尾),就像你用那样.css的规则。

{
  test: /\.js$/,
  exclude: [ path.resolve(__dirname, 'node_modules') ],
  loader: 'babel-loader'
},
Run Code Online (Sandbox Code Playgroud)