在Webpack中加载静态JSON文件

38

我在代码中有如下结构:

var getMenu = function () {
    return window.fetch("portal/content/json/menu.json").then(function (data) {
        return data.json();
    });
};

我在webpack.config.js中尝试了这个:

module: {
    loaders: [
        ...
        {
            test: /\.json$/,
            exclude: /node_modules/,
            use: [
                'file-loader?name=[name].[ext]&outputPath=portal/content/json'
            ]
        },
        ...
   ]
}

项目结构:

dist
  content
     json
        menu.json <- this is missing

src
  content
     json
       menu.json <- source file

问题:

如何使用webpack将src/content/json/menu.json复制到dist/content/json/menu.json

2个回答

48

您正在使用fetch请求JSON文件,这只会发生在运行时。此外,webpack仅处理所有导入的内容。您期望它处理函数的参数,但如果webpack这样做,函数的每个参数都将被视为模块,并且这会破坏该函数的任何其他用途。

如果您希望加载程序启动,请导入该文件。

import './portal/content/json/menu.json';

您也可以直接导入JSON并直接使用,而不是在运行时获取它。 Webpack 2默认情况下对所有.json文件使用json-loader。 您应该删除.json规则,并按以下方式导入JSON。

import menu from './portal/content/json/menu.json';

menu 是一个与从你的 getMenu 函数获得的 JavaScript 对象相同的对象。


9
我使用了你给出的后一种选项,但是出现了“无法找到模块'给定路径'”的错误。 - Olezt
1
如果不使用fetch,那么是否有可能实现OP所要求的功能呢? - F3L1X79

13

如果您想要在运行时/延迟加载JSON,可以使用webpack强大的动态导入功能:

import(
    /* webpackChunkName: "json_menu" */
    './portal/content/json/menu.json'
);

它将返回一个Promise对象,该对象解析为模块对象,并带有包含您的数据的"default"字段。因此,您可能需要像这样使用它(使用es6看起来非常不错):

import(
    /* webpackChunkName: "json_menu" */
    './portal/content/json/menu.json'
).then(({default: jsonMenu}) => {
    // do whatever you like with your "jsonMenu" variable
    console.log('my menu: ', jsonMenu);
});

请注意,动态导入需要一个 babel 插件 syntax-dynamic-import,使用 npm 安装它:

npm i babel-plugin-syntax-dynamic-import -D

祝你有美好的一天


2
这是一个不错的替代方法,但仍然没有告诉我如何让webpack将JSON文件写入dist文件夹。 - Luminous
1
@Luminous 它会自动出现,无论你在任何地方导入的内容都会在编译期间转换为块(请参见webpackChunkName:“json_menu”)。最终文件名和路径将由webpack配置确定。如果您对生成的名称不满意,可以利用代码拆分名称回调进行微调。 - Roman86

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接