npm脚本以密钥作为文件名来连接json文件

时间:2017-09-25 17:57:17

标签: json npm gruntjs concat npm-scripts

有没有人知道npm脚本要将多个json文件与键作为文件名连接。

示例

fileone.json

{
  "john": "doe"
}

filetwo.json

{
  "foo": "bar"
}

输出我想:

concat.js

{
  "fileone": {
     "john": "doe"
   },
  "filetwo": {
     "foo": "bar"
   }
}

有几个笨拙的任务可以实现这一目标,但我不会在我的项目中添加另一个任务运行器。

npm concat-cli主要用于连接javascript文件,因此如果用于json,则生成的文件不正确。

所以如果有人在这里知道一个好的解决方案,谢谢。

1 个答案:

答案 0 :(得分:1)

  

有没有人知道用于连接多个json文件的npm脚本以及作为文件名的密钥?

简短回答 - 我没有现成的解决方案可以解决这个问题。

解决方案

为避免使用其他任务运行器(例如grunt),您可以考虑使用自己的自定义节点脚本来处理此要求。然后只需通过npm-script

调用节点脚本

以下示例要点显示了如何实现这一目标......

<强> concat.js

自定义节点脚本如下:

'use strict';

var path = require('path');
var readline = require('readline');
var fs = require('fs');

// Default destination path for resultant json file.
var destPath = path.join(__dirname, 'result.json');

// Default no console logging.
var verbose = false;

// Nice ticks for logging aren't supported via windows cmd.exe
var ticksymbol = process.platform === 'win32' ? '√' : '✔';

var jsonFilePaths = [];
var concatenatedJson = {};

// Create a readline interface ( https://nodejs.org/api/readline.html )
// to read each path piped via the glob pattern in npm-script.
var rl = readline.createInterface({
  input: process.stdin,
  output: null,
  terminal: false
});

// Handle the optional `-o` argument for the destination filepath.
if (process.argv.indexOf('-o') !== -1) {
  destPath = path.join(__dirname, process.argv[process.argv.indexOf('-o') + 1]);
}

// Handle the optional `-v` argument for verbose logging.
if (process.argv.indexOf('-v') !== -1) {
  verbose = true;
}

/**
 * Get the json filename for use as json key.
 * @param {String} filepath - The filepath to the source json file.
 * @returns {String} The json filename without file extension (.json).
 */
function getKeyFromFileName(filePath) {
  return path.basename(filePath, '.json');
}

/**
 * Obtain the contents of the source .json file.
 * @param {String} filepath - The filepath to the source json file.
 * @returns {String} The json content.
 */
function readJsonFile(filePath) {
  return fs.readFileSync(filePath, { encoding: 'utf8' });
}

/**
 * Create a new json/object using filename as key for files content.
 * @param {String} filepath - The filepath to the source json file.
 */
function concatJson(filePath) {
  var key = getKeyFromFileName(filePath),
    json = readJsonFile(filePath);

  concatenatedJson[key] = JSON.parse(json);
}

/**
 * Save the resultant concatenated json file.
 * @param {String} filepath - The filepath to save the resultant json file.
 * @param {String} content - The json content to save to file.
 */
function saveFile(filePath, content) {
  fs.writeFile(filePath, content, function(err) {
    if (err) {
      return console.log(err);
    }

    if (verbose) {
      console.log(ticksymbol + ' Successfully created: ' + destPath);
    }
  });
}

// Read each line from process.stdin
// I.e. Each json filepath found via the glob pattern in npm-script
rl.on('line', function(filePath) {
  jsonFilePaths.push(filePath);
});

// When readline closes begin processing json files and write
// the resultant concatenated json data to disk.
rl.on('close', function() {
  jsonFilePaths.forEach(function (filePath) {
    concatJson(filePath);
  });

  saveFile(destPath, JSON.stringify(concatenatedJson, null, 2));
});

<强> NPM-脚本

您可以通过concat.js这样调用npm-script脚本:

"scripts": {
  "concat": "glob \"path/to/**/*.json\" | node concat"
},

注意: cli-glob用于指定glob模式以查找要连接的源.json文件。所以你需要安装它:

$ npm i -D cli-glob

glob模式,即读取"glob \"path/to/**/*.json\"的部分,查找要连接的所有.json文件,以便将它们连接到concat.js脚本。需要根据项目目录结构(即,您的源.json文件所在的位置)重新定义此glob模式。

附加说明

  1. 上面的npm-script要点假定concat.js已保存在项目根目录中(即与package.json相同的级别)。您当然可以将其保存在其他地方,只需在npm-scripts中相应地定义它的路径即可。例如,假设您将其保存在名为.scripts的不可见文件夹中,该文件夹位于项目根目录中,然后您将定义npm-script as follows:
  2.    "scripts": {
         "concat": "glob \"path/to/**/*.json\" | node .scripts/concat"
       },
    
    1. 默认情况下,结果/连接的.json文件将保存到名为result.json的项目根目录中的文件中。但是,可以在-o中提供可选的npm-script参数来定义备用目标路径。例如;要将结果文件保存到项目根目录中名为quux.json的文件中,npm-script将定义如下:
    2.    "scripts": {
           "concat": "glob \"path/to/**/*.json\" | node .scripts/concat -o quux.json"
         },
      
      1. 生成的.json文件也可以保存到项目根目录下的子文件夹中。例如,假设您要将名为foobar.json的文件中的结果保存到项目根目录中名为build的文件夹中,然后按如下方式配置npm-script
      2. (注意:目标文件夹/文件夹必须存在,因为concat.js不会为您创建它们。但是,可以添加该功能)

           "scripts": {
             "concat": "glob \"path/to/**/*.json\" | node .scripts/concat -o build/foobar.json"
           },
        
          默认情况下,
        1. concat.js无法确认成功连接.json个文件。要将完成消息记录到控制台,显示保存文件的路径,请在-v中添加npm-script选项/标记,例如:
        2.    "scripts": {
               "concat": "glob \"path/to/**/*.json\" | node .scripts/concat -v -o build/foobar.json"
             },
          

          运行$ npm run concat (使用显示的最后一个配置)会在完成后在控制台中记录与此类似的内容:

            

          ✔ Successfully created: /Path/to/myProject/build/foobar.json

          希望这有帮助!