How to use Webpack to combine JSON files from all subdirectories into one?

℡╲_俬逩灬. 提交于 2021-02-18 13:51:29

问题


Say I have a directory structured like this:

1. folder A
  1a. some_file.js
  1b. data.json
2. folder B
  2a. folder B1
     2a1. other_file.json
     2a2. data.json
  2b. folder B2
     2b1. data.json
3. output.json

Is there a webpack loader that can combine data.json in all subfolders, and output it to output.json?

I've found https://www.npmjs.com/package/json-files-merge-loader that seems to do something similar, but it seems to ask for each path to data.json, while I need something that goes through all folders and subfolders for data.json. All data.json keys are unique, and I want output.json to be one JSON object containing all key/value pair from all data.json.


回答1:


webpack is not really suited for the use case you have. Many people think that webpack can be a replacement for a build system, but it's just a module bundler, it doesn't handle every task. Specifically:

  1. webpack traverses require() and import statements, meaning it needs the modules to be statically defined. It's possible to get around this by writing a plugin or using a file generated from a template, but even if you did that...
  2. webpack would have a hard time combining the JSON files in the way you want. webpack is good at bundling files into some sort of modules system (CommonJS or AMD). What you want is not a bundle containing modules, but a file containing arbitrary contents.

webpack might be able to do these things using some fancy plugins, but it's likely not worth it. In your case, you probably just want to write a Node script. If you want, you can use a plugin like this to run the code before build.

const fs = require('fs');
// https://github.com/isaacs/node-glob
const glob = require('glob');

const output = {};

glob('src/**/*.json', (error, files) => {
    files.forEach((filename) => {
        const contents = JSON.parse(fs.readFileSync(filename, 'utf8'));
        Object.assign(output, contents);
    });

    fs.writeFileSync('output.json', JSON.stringify(output));
});



回答2:


Is there a webpack loader that can combine data.json in all subfolders, and output it to output.json?

Use the merge-webpack-plugin.

This is differ from to run the code before build. Because deep webpack integration allow to follow file changes and update results immidiately while hot reloading:

MergePlugin = require("merge-webpack-plugin");
module.exports = {
  module: {
    rules: [
      {
        test: /\.(json)$/i,
        use: [
          MergePlugin.loader()
        ]
      }
    ]
  },
  plugins: [
    new MergePlugin({
      search: './src/**/*.json',
    })
  ]
}
  • if you need only one target file output.json for all folders in your project describe them all in search param, and that is all
  • if you need to join separated files for each top level folders (output_A.json, output_B.json ...) then:
    • if your do not need to lookup through subfolders try to play with group param with value [path] - read more about grouping
    • if you need to join all files through each folder and its subfolders you need to create multiple plugin instances for each top level folder; but you can group files in each plugin instance by name or by ext (see grouping)

and some more




回答3:


@dee Please check this plugin https://www.npmjs.com/package/merge-jsons-webpack-plugin

You can pass array of files/patterns as an input and it will emit single file as json.




回答4:


My multi-json-loader might be helpful here. It accepts a glob and combines the files into a single JSON blob while also retaining relative paths in the output object.

Ie, dirA/a.json, dirB/b.json, and dirB/c.json get output as

{
  "dirA": {
    "a": /*parsed contents of a.json*/
  },
  "dirB": {
    "b": /*parsed contents of b.json*/,
    "c": /*parsed contents of b.json*/
  }
}


来源:https://stackoverflow.com/questions/40000173/how-to-use-webpack-to-combine-json-files-from-all-subdirectories-into-one

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!