这是一个简单的测试案例:
首先,从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配置的模块字段中:
{
test: /\.json/,
loader: 'json-loader'
}
这实际上有效! json文件已加载,错误消失。
所以我的问题是:我在尝试导入json文件的Webpack上做错了什么,或者最新的Webpack在导入json文件方面有所破坏?
答案 0 :(得分:4)
您用于.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'
},