问题
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:
- webpack traverses
require()
andimport
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... - 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 insearch
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)
- if your do not need to lookup through subfolders try to play with group param with value
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