Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose config file loading logic in the API. #761

Open
lemmabit opened this issue Jun 30, 2016 · 13 comments
Open

Expose config file loading logic in the API. #761

lemmabit opened this issue Jun 30, 2016 · 13 comments
Assignees

Comments

@lemmabit
Copy link
Contributor

lemmabit commented Jun 30, 2016

This right here.

29 of rollup-stream's 65 lines (including the "path" import) are dedicated to duplicating this behavior, and I didn't even include the ability to use Node modules. It would have added a dependency if I had—Rollup is currently the only one. (I didn't think it was important to include because users could require it themselves, but this is assuming that the options module doesn't use ES6 module syntax.)

@Victorystick
Copy link
Contributor

It sounds like a good idea to make any part of Rollup's functionality that could be reused elsewhere available through an official API, so as to avoid reimplementations that slowly drift out of sync with the official one.

@Rich-Harris
Copy link
Contributor

Sorry for slow response. I'm not entirely convinced that loading config files is something that should be supported via an API, since config files are designed for use with the CLI. It's basically just rewriting the import and export statements — if someone was using rollup-stream then they could either a) use reify to do the same thing, or b) write their config file as a CommonJS module instead.

As said in #828 I've very wary of introducing extra stuff that needs to be maintained just for the sake of Gulp.

@fregante
Copy link

I'm very wary of introducing extra stuff that needs to be maintained

Wouldn't this change only move the config parser from the CLI into the API for general use?

@ghost
Copy link

ghost commented Jun 21, 2017

since config files are designed for use with the CLI

I would like to use rollup programmatically, wrapping rollup in another tool that does a few other things, but I would like to allow users to still use the same config file they would if calling rollup directly.

As noted by @bfred-it, it's not our desire to introduce extra behavior not already supported by rollup.

It's our desire to bring the API up-to par with the CLI.

This would allow rollup to be incorporated into other tooling while maintaining consistency with rollup's built-in CLI tool.

This would benefit users:

  • Users could move between tools using rollup with greater ease, as the same config file will work between them.
  • Easier adoption of Rollup as the community can share a common set of documentation when the API behaves the same as the CLI, and between all tools built on Rollup.

This would benefit the rollup contributing community:

  • Those of us using rollup programmatically can innovate more quickly if we can share the common functionality already available in the CLI, instead of needing to maintain our own forks of that functionality.

@ghost
Copy link

ghost commented Jun 21, 2017

Related to #1461

@lemmabit
Copy link
Contributor Author

This is even more necessary now that the config API and the JavaScript API have diverged. The logic to convert a config file into a series of Rollup calls isn't trivial. People do expect to be able to use their Rollup config files with wrappers.

@guybedford
Copy link
Contributor

While, yes a tool could wrap the CLI call, it could be worth considering a simple API wrapper for config files - rollup.rollupConfig('path/to/config.js') or similar. Perhaps a rollup.watchConfig('path/to/config.js') could go along with such a thing too.

@guybedford guybedford reopened this Jun 11, 2018
@shellscape shellscape self-assigned this Aug 10, 2018
@philipwalton
Copy link

I just encountered a situation where I wanted this feature. I had an existing rollup configuration file (which I wanted to keep) but then I also wanted to be able to integrate the rollup task into a gulp build system.

While it wasn't a ton of work to set up rollup to build and watch files using the JS API, since I already had the config, it would have been nice to just pass it to a function.

@shellscape
Copy link
Contributor

Hey folks. This is a saved-form message, but rest assured we mean every word. The Rollup team is attempting to clean up the Issues backlog in the hopes that the active and still-needed, still-relevant issues bubble up to the surface. With that, we're closing issues that have been open for an eon or two, and have gone stale like pirate hard-tack without activity.

We really appreciate the folks have taken the time to open and comment on this issue. Please don't confuse this closure with us not caring or dismissing your issue, feature request, discussion, or report. The issue will still be here, just in a closed state. If the issue pertains to a bug, please re-test for the bug on the latest version of Rollup and if present, please tag @shellscape and request a re-open, and we'll be happy to oblige.

@aleclarson
Copy link
Contributor

Please reopen this issue. :)

@aleclarson
Copy link
Contributor

aleclarson commented Mar 17, 2020

Great news.. This 52-line function will load your rollup.config.{js,ts} file for you!

// Example usage
loadConfigFile('rollup.config', { /* options */ })

async function loadConfigFile(configFile, commandOptions = {}) {
  configFile = path.resolve(configFile)
  configFile +=
    ['.js', '.ts'].find(ext => fs.existsSync(configFile + ext)) || ''

  const bundle = await rollup.rollup({
    external: id =>
      (id[0] !== '.' && !path.isAbsolute(id)) ||
      id.slice(-5, id.length) === '.json',
    input: configFile,
    treeshake: false,
  })

  const {
    output: [{ code }],
  } = await bundle.generate({
    exports: 'named',
    format: 'cjs',
  })

  // temporarily override require
  const extension = path.extname(configFile)
  const defaultLoader = require.extensions[extension]
  require.extensions[extension] = (module, filename) => {
    if (filename === configFile) {
      module['_compile'](code, filename)
    } else {
      defaultLoader(module, filename)
    }
  }

  delete require.cache[configFile]
  const configs = await Promise.resolve()
    .then(() => require(configFile))
    .then(configFileContent => {
      if (configFileContent.default) {
        configFileContent = configFileContent.default
      }
      if (typeof configFileContent === 'function') {
        return configFileContent(commandOptions)
      }
      return configFileContent
    })

  if (Object.keys(configs).length === 0) {
    throw Error(
      'Config file must export an options object, or an array of options objects'
    )
  }

  require.extensions[extension] = defaultLoader
  return Array.isArray(configs) ? configs : [configs]
}

Should I release it under load-rollup-config?

PS: I still support exposing this in the official Rollup API. ;)

@lukastaegert
Copy link
Member

I see what you are doing but considering that the loading logic will be refactored soon to support Node 13 better in #3445, we could rethink about exposing something here.

I'm still not sure though I 100% understand what we need. So what will not happen is that the config loading API will become part of Rollup core, for various reasons (one being that Rollup core is meant to be independent of the host system). We could however expose a second entry point, e.g. const {loadConfig} = require('rollup/dist/bin/load-config') to facilitate this with the signature you outlined. I assume this would work for you?

@lukastaegert lukastaegert reopened this Mar 18, 2020
@aleclarson
Copy link
Contributor

@lukastaegert No objections here! Thanks for the quick reply. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants