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
Use require
instead of requireFromString
.
#51
Conversation
e210a0c
to
abf5ee2
Compare
/cc @davidtheclark 😄 |
This looks interest @izaakschroeder, thanks! I will try to find time this weekend to look into it. |
Thanks! It shouldn't be a breaking change. 🎉 I |
You could also modify |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a test where the JS module uses ES2015 syntax? Maybe destructuring and spread operators in the exported object, and also some other unsupported stuff? I'm guessing this will break things, right?
There are also some conflicts to fix and also documentation to add. We should note the new possibilities and also note that reading JS is sync now, so users might get a performance boost by excluding it.
The downside I can see to this is that it is sync instead of async — that was the original reason for using require-from-string
. I really wish there were a way around that, but maybe there is not. It's true that the robustness we gain from avoiding require-from-string
is probably worth the trouble of require
being sync.
var readFile = require('./readFile'); | ||
var irequire = require('./require'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to give this variable and the file more descriptive names. How about importJs
?
@@ -195,6 +196,7 @@ test.serial('find invalid package.json', function (assert) { | |||
|
|||
test.serial('find invalid JS in .config.js file', function (assert) { | |||
var startDir = absolutePath('a/b'); | |||
mock('./a/b/foo.config.js', './fixtures/foo-invalid.js'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this make the case absolutePath('a/b/foo.config.js'):
below unnecessary?
Although there's some niceness in using the string data straight from the filesystem, you lose the ability to use anything that hooks into the native `require` call – namely `babel` and friends. By using vanilla `require` it becomes possible to use ES6 files for your configuration (or indeed anything else that hooks into standard node module loading machinery). Performance-wise the change should be negligible, given the filesystem/stat cache will be hot from having just loaded the contents of the file.
As requested.
abf5ee2
to
f22168f
Compare
✔️ Done. Doesn't break anything in terms of backwards compatibility far as I know.
✔️ Conflicts fixed. If you can give me an example of the docs you want I can add them, otherwise feel free to note it however you like; really the only difference is that people using babel will see things "just work". More of a bug fix than a feature I think.
The I/O for one config file (most likely at startup) will probably be negligible; if users are trying to optimize for the 0.05ms it takes to read a config file... there are probably better optimization targets to look out for 😄 Thanks for the feedback! Hope this works! 🎉 |
/cc @davidtheclark ^ |
The test with ES2015 syntax uses Babel ... I guess I poorly explained the point. We can't advertise that you can just use ES2015 modules: you can only do so if your Node application is compiled with Babel, right? We'll need to hash out the specific way to explain this in the docs. Since it's a matter of documentation, let's remove the test and additional dependencies. Regarding docs: any references to async in the README need to be qualified or removed. And references to JS exports should note that ES2015 modules can be used but cosmiconfig does not compile the source to ES5 — the consumer app needs to handle the ES2015. After those additions to the docs — and sorry about the flip-flopping on the test — let's merge and release. |
This reverts commit f22168f.
✔️ Done! All yours. 🎉 |
@izaakschroeder Dang, after merging I realized that there are lots of problems with the tests. I can try to finish this up, but the most important question is this: |
@izaakschroeder I reverted this merge. Sorry for the confusion. Please open another PR from your branch, but there are some essential changes necessary for the tests to work:
importJsStub = sinon.stub(importJs, 'import', function (searchPath) {
switch (searchPath) {
case absolutePath('a/b/foo.config.js'):
case absolutePath('a/foo.config.js'):
case absolutePath('foo.config.js'):
throw new Error({ code: 'MODULE_NOT_FOUND' });
}
}); Sorry, you probably thought this wasn't a huge change, but it really is fundamentally modifying the way that JS files get loaded, so will involve a lot of adjustments. If you are not able to do this, I can try to find some time this weekend. |
What do you mean "some essential changes necessary for the tests to work"? The build passed just fine previously - which tests are failing?
Yeah it probably shouldn't. It won't break anything, other than being an extremely minor performance annoyance. (Basically just heating cache which the next
Indeed if the former change is made then an update here becomes a necessary concession.
What test does this need to be stubbed for? But you are correct, sinon can't stub default exports; so giving it a name will allow sinon to stub it. |
Yes, tests were passing; but they were not testing the right things, so it doesn't matter that they were passing. They need to be changed if we are to integrate this new feature. Almost all the tests need to be changed, because they all were testing JS files read via
(Re "heating cache" I don't think that's going to happen: In this case we will later read the file again with The
|
Although there's some niceness in using the string data straight from the filesystem, you lose the ability to use anything that hooks into the native
require
call – namelybabel
and friends. By using vanillarequire
it becomes possible to use ES6 files for your configuration (or indeed anything else that hooks into standard node module loading machinery). Performance-wise the change should be negligible, given the filesystem/stat cache will be hot from having just loaded the contents of the file.There's also a check in here to use the default export from ES6 modules if its present.
And it's one less (runtime) dependency.