Skip to content
This repository has been archived by the owner on Jun 8, 2023. It is now read-only.

Use babel's built-in option manager for loading configs. #28

Merged
merged 8 commits into from
Nov 9, 2016

Conversation

izaakschroeder
Copy link
Contributor

@izaakschroeder izaakschroeder commented Nov 2, 2016

There is an issue if you configure this plugin anywhere outside of your .babelrc. For example, if you have:

{
  "presets": ["my-preset"]
}

And in your preset you have this plugin configured, then this plugin will fail to find that configuration value. It will also fail if you have multiple .babelrc's and the configuration is defined up the tree somewhere (as is also possible).

By leveraging babel's built-in option manager for doing all the heavy lifting we avoid these pitfalls. No dealing with environment settings or checking the shape of the configuration object. It's also a lot less code and coverage goes to the moon 🚀 .

The only minor concern is that it leverages a bit of babel's "inner" workings and if they change that then this could break but that's no better than how it is now really.

Everything. Just. Works.™

@codecov-io
Copy link

codecov-io commented Nov 2, 2016

Current coverage is 100% (diff: 100%)

Merging #28 into master will increase coverage by 2.56%

Diff Coverage File Path
•••••••••• 100% src/index.js

Powered by Codecov. Last update 60aec31...c618af7

@tleunen
Copy link
Owner

tleunen commented Nov 2, 2016

Hi @izaakschroeder, thanks for the contribution.
Does it mean you also have the issue with babel-plugin-module-resolver?

It's a good point you bring. with the plugin set in a preset, the current version won't find the configuration.

I wonder if there's a better way other than using internal babel core functions though.

@izaakschroeder
Copy link
Contributor Author

I don't think there is an issue with babel-plugin-module-resolver because it gets its config straight from babel itself (no config parsing shenanigans). This is the only package that needs updating and indeed this now makes it so both places get (roughly) the same config. There's extra logic in here for appending root and merging alias though (as it was before).

I don't think there's a better way unless babel decides to make them a more public API. The darker hackery was only to set cwd properly. I think this is workable in the meantime though for all the benefits it brings; you?

@tleunen
Copy link
Owner

tleunen commented Nov 2, 2016

The beta version of the plugin tries finds the babelrc config location to determine the working directory for the paths resolution, so we might also have others issues I guess... (see this change)

When you're setuping the plugin in a preset, what are the paths you're using? relative to the config or relative to the project root directory? If it's relative to the babelrc file, we should be fine

@izaakschroeder
Copy link
Contributor Author

It should be possible to change that to use a more refined resolution mechanism if it's needed. I think plugins have access to a bunch of information about themselves. The premise of this was to use the "original" or root .babelrc as the cwd (hence the [0] in the list of configs).

@izaakschroeder
Copy link
Contributor Author

When you're setuping the plugin in a preset, what are the paths you're using? relative to the config or relative to the project root directory? If it's relative to the babelrc file, we should be fine

It's the latter, otherwise this whole thing wouldn't work 😄

@tleunen
Copy link
Owner

tleunen commented Nov 2, 2016

hmm At the same time, I'm not sure taking the first one as cwd is best too.

Let's say a project has /client/src and /server/src. You might have a root config at / with common usage then a more specific one in both configuration. If you have the module-resolver plugin set in /server, I believe the paths set in the configuration must be relative to /server, not /, right?

@tleunen
Copy link
Owner

tleunen commented Nov 2, 2016

It's the latter, otherwise this whole thing wouldn't work

Yep after your previous comment I figured that out ;) But it could have been relative to the config specifying the preset (which could make more sense to me).

@izaakschroeder
Copy link
Contributor Author

izaakschroeder commented Nov 2, 2016

I think it would be fairly pointless relative to the config... since there's no way of knowing where the config is mounted at (i.e. at which level within node_modules). The only thing would be if you had some module that you depended on that you wanted to alias. Seems like you could get around it by just using absolute paths in that case though.

Results are here: https://github.com/metalabdesign/babel-preset-metalab/pull/12/files and here: https://github.com/metalabdesign/eslint-config-metalab/compare/use-new-resolver?expand=1

@izaakschroeder
Copy link
Contributor Author

You can see both builds passing using this branch. 😄

@izaakschroeder
Copy link
Contributor Author

izaakschroeder commented Nov 2, 2016

Let's say a project has /client/src and /server/src. You might have a root config at / with common usage then a more specific one in both configuration. If you have the module-resolver plugin set in /server, I believe the paths set in the configuration must be relative to /server, not /, right?

Correct. But we're making assumptions to begin with already which is that wherever we find a .babelrc relative to the original file is where we want your cwd to be (which would indeed be /server in this case in your original code too). Don't really think there is a "right" answer. If you want to be less opinionated then you should probably just make it a config option. In babel they pass in moduleRoot and sourceRoot and you can set that on the CLI too I think.

@izaakschroeder
Copy link
Contributor Author

If you wanted to use that approach then you would need to pass that option through to babel here: https://github.com/babel/babel-eslint/blob/master/index.js#L368

@tleunen
Copy link
Owner

tleunen commented Nov 2, 2016

I always have 1 babelrc file at the root of the project so I'm not really affected by all this, I'm just trying to find the best solution to your use case and the ones from others users who don't have the babelrc at the root but in the /src directory for example

@izaakschroeder
Copy link
Contributor Author

I always have 1 babelrc file at the root of the project so I'm not really affected by all this

Pretty much me too, at least as far as multiple .bablerc files go. My use case is for being able to use this in presets 😄

@tleunen
Copy link
Owner

tleunen commented Nov 4, 2016

How will it work when people specify the configuration using babel-register? (see tleunen/babel-plugin-module-resolver#61 for context)

Also if @hzoo or @loganfsmyth could tell me if there's a better way instead of using internal babel stuff, it would be great :)

@izaakschroeder
Copy link
Contributor Author

izaakschroeder commented Nov 7, 2016

@tleunen if you're specifying cwd in the configuration, can we resolve this? (i.e. have it merged and use the cwd from the configuration).

@tleunen
Copy link
Owner

tleunen commented Nov 7, 2016

Yep, lets get this merged and we'll see later if we can have a better support from Babel instead of using internal stuff.

There're conflicts now in the PR though

@izaakschroeder
Copy link
Contributor Author

Will rebase now 😄

There is an issue if you configure this plugin anywhere outside of your `.babelrc`. For example, if you have:

```json
{
  "presets": ["my-preset"]
}
```

And in your preset you have this plugin configured, then this plugin will fail to find that configuration value. By leveraging babel's built-in option manager for doing all the heavy lifting we avoid these pitfalls.
@izaakschroeder
Copy link
Contributor Author

izaakschroeder commented Nov 7, 2016

@tleunen Thoughts on changing the default cwd option to:

pluginOpts.cwd || process.cwd()

Which is much easier to reason about and the user can set it to whatever they want and avoids this scary problem of walking the babel configuration tree (and means I can use less internal functions).

@izaakschroeder
Copy link
Contributor Author

@tleunen Tests currently failing, but you can see the idea and there's a pretty big reduction in babel core voodoo for doing it.

@loganfsmyth
Copy link

There is no official API for this and I'm not sure if that's something I'd want to add, but either way if you're going to depend on this could I at least recommend wrapping these in a try/catch with a useful error message, so if it one day breaks because Babel changes something, users will know it is because of this module, not something Babel did?

@izaakschroeder
Copy link
Contributor Author

@loganfsmyth @tleunen Tests are now in place to notify users in case babel's internals get changed.

@@ -4,6 +4,7 @@

const path = require('path');
const resolverPlugin = require('../src/index');
const OptionManager = require('babel-core/lib/transformation/file/options/option-manager');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This require could also fail since the file could get moved.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved. 🚀

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather, resolved in the module code itself. This file is just a test so I don't think guards are necessary here. And indeed, I'm sure this issue could be caught quickly with this present + https://greenkeeper.io/

@izaakschroeder
Copy link
Contributor Author

Will squash when everyone is happy 🎉

@@ -49,6 +15,30 @@ function opts(file, config) {

exports.interfaceVersion = 2;

function getPlugins(file, target) {
const OptionManager = require('babel-core/lib/transformation/file/options/option-manager'); // eslint-disable-line

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this again, you can actually use require('babel-core').OptionManager.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👌 👌 👌

Copy link
Owner

@tleunen tleunen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good, thanks @izaakschroeder for the recent changes!

And thanks a lot @loganfsmyth for the review

@@ -43,7 +43,8 @@
"standard-version": "^3.0.0"
},
"peerDependencies": {
"babel-plugin-module-resolver": "^2.3.0"
"babel-core": "^6.0.0",
"babel-plugin-module-resolver": "^3.0.0-beta"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert to the 2.3.0 version, I'm dropping the v3 beta for now.

@@ -49,6 +15,30 @@ function opts(file, config) {

exports.interfaceVersion = 2;

function getPlugins(file, target) {
try {
const OptionManager = require('babel-core').OptionManager; // eslint-disable-line
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not: Should be safe to move it again at the top of the file, right?

@izaakschroeder
Copy link
Contributor Author

@tleunen Look good?

@tleunen tleunen merged commit 952863e into tleunen:master Nov 9, 2016
@tleunen
Copy link
Owner

tleunen commented Nov 9, 2016

Thank you both of you :)

@izaakschroeder izaakschroeder deleted the use-babel-configurator branch November 9, 2016 09:02
@vdh
Copy link
Contributor

vdh commented Nov 10, 2016

This change caused some sort of disparity between local and global eslint, and maybe it's just this summer heat but I can't figure out what exactly is going on with this plugin's current directory handling.

@tleunen
Copy link
Owner

tleunen commented Nov 11, 2016

I have, hopefully, temporarily reverted the changes and released v2.2.1. I'll check more over the weekend how to fix the cwd issue. See #30

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

Successfully merging this pull request may close these issues.

None yet

5 participants