如何使用一个输出分别汇总多个目录

时间:2017-05-28 21:35:57

标签: javascript node.js rollupjs transpiler

所以,我有一个目录:

mods/
-core/
--index.js
--scripts/
---lots of stuff imported by core/index

如果要汇总到例如mods/core/index.min.js

,这适用于典型的汇总方式

但是我有很多这些mods/**/目录,我想利用它们汇总到iifes这一事实。每个mods/**/index.js将而不是export分配给我们假定提供的全局变量:

mods/core/index.js

import ui from './scripts/ui/'
global.ui = ui

mods/someMod/scripts/moddedClass.js

export default class moddedClass extends global.ui.something { /* some functionality extension */}

mods/someMod/index.js

import moddedClass from './scripts/moddedClass'
global.ui.something = moddedClass

所以希望你能看到每个mod目录如何以典型的方式汇总,但是,我需要将实际的iifes放在另一个目录中,以便:

mods/compiled.js

(function compiled() {
  const global = {};

  (function core() {
    //typical rollup iife
  })();

  (function someMod() {
    //typical rollup iife
  })();

  //a footer like return global or global.init()
})();

非常感谢为此提供任何帮助。我认为,最简单的答案是,我可以简单地为每个mod的iife获取一个字符串值,而不是将其汇总到文件中。

此时我可以按照某些/mods/或其他内容指定的顺序迭代modlist.json目录,并在每个/mod/index.js上调用汇总,然后自己构建外部iife字符串。

但是,我认为这不是源映射的完整解决方案?或者可以包含多个内联源图?考虑到源映射,我想知道是否有必要进行另一个构建步骤,其中每个mod在此系统进入之前都会被转换。

2 个答案:

答案 0 :(得分:1)

使用rollup的bundle.generate api生成多个iifes并使用fs.appendFile将它们写入一个文件。

对于源图,您可以使用此模块(它来自汇总的同一作者)https://github.com/rich-harris/sorcery

答案 1 :(得分:1)

好的,所以我最终解决这个问题的方法是使用source-map-concat

它基本上完成了我所说的,开箱即用。我唯一要做的就是异步迭代mod目录并汇总每个mod,然后将结果传递给source-map-concat,因为rollup.rollup返回一个Promise。

我最终还想要内联源代码映射,以便可以直接注入代码而不是写入文件,因此我使用了convert-source-map

唯一需要解决的问题是子源映射。如果我生成文件,法术会很好用,但我想把它作为字符串来源。现在它至少会告诉我错误来自哪个mod,而不是它来自的子文件。如果有人知道如何对琴弦进行巫术式操作,请告诉我。

以下是我文件中的相关最终代码:

const rollup  = require("rollup")
const concat  = require("source-map-concat")
const convert = require("convert-source-map")

const fs   = require("fs")
const path = require("path")

const modsPath = path.join(__dirname, "mods")

const getNames = _ => JSON.parse(fs.readFileSync(path.join(modsPath, "loadList.json"), "utf8"))

const wrap = (node, mod) => {
  node.prepend("\n// File: " + mod.source + "\n")
}

const rolls = {}
const bundles = {}

const rollupMod = (modName, after) => {
  let dir = path.join(modsPath, modName),
      file = path.join(dir, "index.js")

  rollup.rollup({
    entry: file,
    external: "G",
    plugins: []
  }).then(bundle => {
    rolls[modName] = bundle.generate({
      format: "iife",
      moduleName: modName,
      exports: "none",
      useStrict: false,
      sourceMap: true
    })

    after()
  })
}

const rollupMods = after => {
  let names = getNames(), i = 0,
      rollNext = _ => rollupMod(names[i++], _ => i < names.length - 1? rollNext() : after())

  rollNext()
}

const bundleCode = after => {
  rollupMods(_ => {
    let mods = concat(getNames().map(modName => {
      let mod = rolls[modName]

      return {
        source: path.join(modsPath, modName),
        code: mod.code,
        map: mod.map
      }
    }), {
      delimiter: "\n",
      process: wrap
    })

    mods.prepend("(function(){\n")
    mods.add("\n})();")

    let result = mods.toStringWithSourceMap({
      file: path.basename('.')
    })

    bundles.code = result.code + "\n" + convert.fromObject(result.map).toComment()

    after(bundles.code)
  })
}

exports.bundleCode = bundleCode