Skip to content

resolve-plugins #67

Description

@tunnckoCore

Resolve plugins / transforms / presets just like Babel and Browserify does it. Useful for loading complex configs from package.json file.
Sync and async mode.

const extend = require('extend-shallow')
const resolvePackage = require('resolve-package')

const arrayify = (val) => {
  if (!val) return []
  if (Array.isArray(val)) return val
  return [val]
}

// just uses synchrouns `require`
const resolvePluginsSync = (plugins, opts) => arrayify(plugins).map((plugin) => {
  if (typeof plugin === 'string') {
    let id = `${opts && opts.prefix || ''}${plugin}`
    return require(id)()
  }
  if (Array.isArray(plugin)) {
    let id = `${opts.prefix || ''}${plugin[0]}`
    const fn = typeof plugin[0] === 'function'
      ? plugin[0]
      : require(id)

    return fn(plugin[1])
  }
  return plugin
})

// uses `resolve-package`, that's why it is async
const resolvePlugins = (plugins, opts) => {
  plugins = arrayify(plugins).filter(Boolean)

  if (!plugins.length) {
    return Promise.resolve([])
  }
  opts = extend({ prefix: '' }, opts)

  return Promise.all(plugins.map((plugin) => {
    // allows `plugins: ['foo', 'bar', 'baz']`
    if (typeof plugin === 'string') {
      let id = `${opts.prefix}${plugin}`
      return resolvePackage(id, opts).then((fp) => {
        return require(fp)()
      })
    }
    // allows nesting and passing options to each plugin
    // e.g. `plugins: [ fn, ['foo', {opts: 'here'}], 'bar', quix() ]
    if (Array.isArray(plugin)) {
      if (typeof plugin[0] === 'string') {
        return resolvePackage(`${opts.prefix}${plugin[0]}`, opts)
          .then((fp) => {
            return require(fp)(plugin[1])
          })
      }
      if (typeof plugin[0] === 'function') {
        let fn = plugin[0]
        return Promise.resolve(fn(plugin[1]))
      }
      let msg = 'first item of array should be function or string'
      let err = new TypeError(msg)
      return Promise.reject(err)
    }
    // allows `plugins: [fn1, fn2]`
    if (typeof plugin === 'function') {
      return Promise.resolve(plugin())
    }
    // just pass to the tool, like Rollup expect each plugin
    // to return an object, so you can directly pass objects
    // e.g. `plugins: [{name: 'rollup-plugin-foo', transform: fn}]`
    return Promise.resolve(plugin)
  }))
}

const json = JSON.parse(`{"rollup": {
  "plugins": [
    "commonjs",
    ["node-resolve", { "jsnext": true }]
    ["buble", {
      "target": { "node": "4" }
    }]
  ]
}}`)

resolvePlugins(json.browserify.transform, {prefix: 'rollup-plugin-'}).then((res) => {
  console.log('done', res)
})

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions