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

Strengthened ModuleLoader & unit tests; now supports mixed ESM / CJS plugins #163

Merged
merged 7 commits into from May 26, 2021
Merged

Strengthened ModuleLoader & unit tests; now supports mixed ESM / CJS plugins #163

merged 7 commits into from May 26, 2021

Conversation

typhonrt
Copy link
Contributor

@typhonrt typhonrt commented May 14, 2021

@amphro I do have a second PR which is pertinent. I made one mistake in the separate unit tests insofar that at the very tail end I relied on just the separate ModuleLoader unit test to pass outside of a full runtime use case and this was the one time I didn't test final changes against my ESM middleware / CLI.

What went wrong: In the ModuleLoader.resolvePath method when I created the the bad path tests require.resolve used a 2nd time would throw an exception. I didn't add in tests for good paths w/ no extensions which is how Oclif works. require.resolve will resolve the extension (.js). I switched to path.resolve and while the unit tests passed the aspect of not resolving the extension failed when running w/ my external ESM middleware & ESM CLI after #160 was merged.

So the initial unit test while everything passed I made a small mistake in modifying the ModuleLoader code to satisfy the tests and didn't do a full runtime test.


This PR significantly hardens ModuleLoader restoring correct behavior. In addition I didn't want to go back to using require.resolve and made a custom extension resolution algorithm that checks for (.js, .mjs, .cjs). There is a major benefit to this as I worked out a way to support mixed CJS / ESM loading of plugins. Oclif can now support fully ESM plugins w/ "type": "module" in the package.json and all .js files being ESM. There is also support now for loading ESM via .mjs file extensions from a CommonJS plugin and vice versa with an ESM plugin w/ "type": "module" one can load CJS via the .cjs extension.

I strengthened the unit tests for ModuleLoader, but more importantly I added complete runtime tests for ESM, mixed ESM w/ CJS (.cjs), and mixed CJS w/ ESM (.mjs) which you can find in ./test/config/fixtures/ -> esm, mixed-cjs-esm, and mixed-esm-cjs.

Note (edit update below): For the new runtime tests I initially I copied the style of ./test/config/fixtures/typescript which includes an unnecessary yarn.lock file. I removed them from the ESM / CJS runtime tests in a commit on Friday.

The files changed / count increase is from the new runtime tests.

And yeah I tested this PR w/ my external ESM Oclif middleware / CLI as well, so it is definitely fixed.

Not ideal per se w/ two PRs for the core ESM addition, but this PR definitely gets things there 100% and has full unit tests and newly added runtime tests to back it up.

@typhonrt
Copy link
Contributor Author

I did decide to remove the unnecessary yarn.lock files from the newly added ESM / CJS tests in ./test/config/fixtures This file can also be removed from the ./test/config/fixtures/typescript test as well. There is no installation for these tests and the mocked package.json is the only configuration necessary for the ESM / CJS runtime tests added.

This makes it really obvious what has changed in this PR.

Copy link
Contributor

@amphro amphro left a comment

Choose a reason for hiding this comment

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

Sorry for the delay on this review. Just a couple of small comments. Are you ready with this change?

withConfig
.stdout()
.it('runs init hook', async ctx => {
// to-do: fix union types
Copy link
Contributor

Choose a reason for hiding this comment

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

It isn't clear to me what this todo needs to fix

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These "to-do" statement are lifted directly from test/config/typescript.test.ts which the new ESM and mixed ESM / CJS tests used as the example runtime test except for changing around the type of source being tested.

However there does seem to be a reason for the comment being there; the line:
await (ctx.config.runHook as any) will cause TSC to post an error without the as any.

Screen Shot 2021-05-25 at 11 14 30 PM

If you do track down the method signature in /src/interfaces there appears to be a union type.

Looks like @RasPhilCo can comment on it from looking at git history.

withConfig
.stdout()
.it('runs init hook', async ctx => {
// to-do: fix union types
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

configESM.pjson.type = 'module'

const result = await ModuleLoader.loadWithData(module.isESM ? configESM : config, module.path)
// const result = await ModuleLoader.loadWithData(module.isESM ? configESM : config, module.path)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope.. Left over from being able to remove creating a special config for ESM testing. The ModuleLoader update / fix is a bit more flexible now

@typhonrt
Copy link
Contributor Author

typhonrt commented May 26, 2021

@amphro Thanks for checking in.. I was going to give it 14 days before bumping this myself. I have made two more commits removing the "to-do" statements and left over commented out old implementation from the newly added runtime tests.

Things are ready to merge if you are happy with the PR.

Don't go too far though as I'll get the other two PRs in right away once this is merged.

@amphro amphro merged commit 788bf17 into oclif:master May 26, 2021
@amphro
Copy link
Contributor

amphro commented May 26, 2021

I'll keep an eye out for the additional PRs

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

Successfully merging this pull request may close these issues.

2 participants