【问题标题】:Webpack error when importing a json file导入 json 文件时出现 Webpack 错误
【发布时间】:2017-08-05 17:15:03
【问题描述】:

下面是一个简单的测试用例,会被打破:

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

const fs = require('fs')

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

fs.writeFileSync('./test.json', JSON.stringify(test), 'utf-8');

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

import test from './test.json';

console.log(test);

这会失败并出现以下错误:

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

> 1 | {"foo":[{"1":"a"},{"2":"b"}]}

控制台输出指向的违规字符是“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"
        })
      }
    ]
  },

迷惑不解,我打开了 JSON 加载器页面,它告诉我:

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

由于我使用的是 Webpack v. 3.4.1,我认为 json-loader 是不必要的。尽管如此,出于绝望,我还是在 Webpack 配置的 modules 字段中添加了以下规则:

  {
    test: /\.json/,
    loader: 'json-loader'
  }

这确实有效! json文件加载完毕,错误消失。

所以我的问题是:是我在尝试导入 json 文件时 Webpack 做错了什么,还是最新的 Webpack 在导入 json 文件时出现了问题?

【问题讨论】:

    标签: javascript json webpack


    【解决方案1】:

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

    file.js
    file.json
    file.js.backup
    .js/file.css
    .jshintrc
    

    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";
    

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

    要不将babel-loader 应用于.json 文件,您只需使用$ 锚(字符串结尾)匹配路径末尾的.js,就像使用.css 一样规则。

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

    【讨论】:

    • 哎哟!我太傻了,犯了那个正则表达式错误!当然你是对的——当我修复正则表达式时,错误消失了。感谢您提供非常详细的答案!
    猜你喜欢
    • 2021-08-10
    • 2019-12-28
    • 1970-01-01
    • 2023-03-24
    • 2019-04-05
    • 1970-01-01
    • 1970-01-01
    • 2017-12-21
    • 1970-01-01
    相关资源
    最近更新 更多