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

Add Mock Service Worker - msw #513

Merged
merged 15 commits into from
Mar 14, 2024
Merged

Conversation

jmcpeak
Copy link
Contributor

@jmcpeak jmcpeak commented Feb 13, 2024

Copy link
Collaborator

@webpro webpro left a comment

Choose a reason for hiding this comment

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

Thanks @jmcpeak! Thanks a lot for the PR. I'd love to add a plugin for MSW, but also wonder what would be the best default configuration for entry files (I've added some comments).

'mocks/browser.{js,ts}',
'mocks/handlers.{js,ts}"',
'mocks/index.{js,ts}"',
'mocks/server.{js,ts}"',
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are these the default locations?

Feels like files like those listed and src/mocks/node.js could be located anywhere without clear defaults, right? If most projects would follow a certain convention that could work too, but I'm not aware of any. Do you have any insights or links that could help here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The default everyone does is in a root directory of /mocks see all the examples - https://github.com/mswjs/examples/tree/main/examples/with-vitest - this is vitest, but its true for all examples.
And here is another example of the /mocks dir - https://mswjs.io/docs/integrations/browser#conditionally-enable-mocking

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not 100% sure if I'm using the correct knip functions to check for these files. The tests pass and it works - just not sure.

Copy link
Contributor Author

@jmcpeak jmcpeak Feb 15, 2024

Choose a reason for hiding this comment

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

Also, if we could peek inside their package.json we could get the correct directory for mockServiceWorker.{js,,ts}:

"msw": {
  "workerDirectory": "public"
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks!

The findReferences function receives a second options arguments which contains options.manifest.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not 100% sure if I'm using the correct knip functions to check for these files. The tests pass and it works - just not sure.

Many tests are more "end to end" and use the main() function, then you can assert things on the returned issues and counters objects. See e.g. https://github.com/webpro/knip/blob/main/packages/knip/test/plugins/ava2.test.ts

Copy link
Collaborator

Choose a reason for hiding this comment

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

Seems like the msw.workerDirectory value is not taken into account yet?

The patterns here don't have src/ included while the fixture does have that.

More importantly, the example you share shows that vitest.setup.ts imports ./mocks/node.js which in turn imports ./handlers.js. This makes me think none of the mocks/* files need to be configured in Knip, since vitest.setup.ts is already covered by the Vitest plugin.

Maybe you had some other plugin missing that led to the mock/* files not being included?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

const localConfig = basename(configFilePath) === 'package.json' ? manifest.msw : undefined;
const workerDirectory = localConfig?.workerDirectory;

if (workerDirectory) {
  ENTRY_FILE_PATTERNS.push(`${workerDirectory}/mockServiceWorker.{js,ts}`)
}

This bit of code looks for the entry somewhere else other than the default of public

packages/knip/src/plugins/next/index.ts Outdated Show resolved Hide resolved
packages/knip/fixtures/plugins/msw/msw.toml Outdated Show resolved Hide resolved
Copy link
Collaborator

@webpro webpro left a comment

Choose a reason for hiding this comment

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

Looks like it comes down to adding (only) ${package.json#msw.workerDirectory}/mockServiceWorker.js into the process :)

package-lock.json Outdated Show resolved Hide resolved
packages/knip/fixtures/plugins/msw/package-lock.json Outdated Show resolved Hide resolved
packages/knip/src/plugins/msw/index.ts Outdated Show resolved Hide resolved
packages/knip/src/plugins/next/index.ts Outdated Show resolved Hide resolved
'mocks/browser.{js,ts}',
'mocks/handlers.{js,ts}"',
'mocks/index.{js,ts}"',
'mocks/server.{js,ts}"',
Copy link
Collaborator

Choose a reason for hiding this comment

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

Seems like the msw.workerDirectory value is not taken into account yet?

The patterns here don't have src/ included while the fixture does have that.

More importantly, the example you share shows that vitest.setup.ts imports ./mocks/node.js which in turn imports ./handlers.js. This makes me think none of the mocks/* files need to be configured in Knip, since vitest.setup.ts is already covered by the Vitest plugin.

Maybe you had some other plugin missing that led to the mock/* files not being included?

join(cwd, 'src/mocks/handlers.ts'),
join(cwd, 'src/mocks/index.ts'),
join(cwd, 'src/mocks/server.ts'),
])
Copy link
Collaborator

Choose a reason for hiding this comment

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

The idea is that those files are not in issues.files. This test now asserts that the files are unused, which would defeat the purpose of the plugin.

Copy link
Contributor Author

@jmcpeak jmcpeak Feb 17, 2024

Choose a reason for hiding this comment

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

Seems like the msw.workerDirectory value is not taken into account yet?

So I've been looking at this deeper - seems like it is really only used for the npx init script...

"Save the given PUBLIC_DIR in package.json for future automatic updates of the worker script."

https://mswjs.io/docs/cli/init/#flags

I can still put the check in, my guess is most people installing it don't use the --save flag.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe you had some other plugin missing that led to the mock/* files not being included?

Nope, tried with vanilla knip install, these files are still listed as not used. I did not have vitest installed or configured in this vanilla install.

Copy link
Contributor Author

@jmcpeak jmcpeak Feb 17, 2024

Choose a reason for hiding this comment

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

The patterns here don't have src/ included while the fixture does have that.

I didn't want to assume they create a /src directory - I used /src in my example test, guess I should have included them in my root / dir as well.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I can still put the check in, my guess is most people installing it don't use the --save flag.

This is the default, my guess is that MSW has a postinstall script that does this by default (also without --save).

Nope, tried with vanilla knip install, these files are still listed as not used.

I wonder what imports those files. Either there are source file(s) importing them, but somehow not part of the process, or they're imported by some external tool and we're missing a plugin. By now I'm inclined to think it's not MSW importing them automatically (except for the service worker).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I don't know what to do about this one.

@jmcpeak
Copy link
Contributor Author

jmcpeak commented Feb 23, 2024

Anything else you want me to modify? I have changed the code/tests to work properly now.

@webpro
Copy link
Collaborator

webpro commented Feb 23, 2024

The conversations/questions are closed/marked "resolved" while in fact they aren't. In general I think it's better to have the reviewer mark them as resolved.

@jmcpeak
Copy link
Contributor Author

jmcpeak commented Feb 23, 2024

The conversations/questions are closed/marked "resolved" while in fact they aren't. In general I think it's better to have the reviewer mark them as resolved.

My bad, I thought they we an indicator to you that I finished the work and you should take a look.

@webpro
Copy link
Collaborator

webpro commented Feb 23, 2024

The thing is, I'm still not sure how to deal with those entry files. Iirc the example you've showed me imported mock/* file(s):

@webpro
Copy link
Collaborator

webpro commented Mar 12, 2024

Let's wrap up this one. Here's how I think it should work:

  • Default entry is (only) ['mockServiceWorker.js']
  • In findDependencies we can look up localConfig?.workerDirectory and only if found, return the toEntryPattern(join()) of that dir and mockServiceWorker.js
  • No other entry patterns should be there, I think also mockServiceWorker.ts is not picked up by MSW?
  • I think that's it, really :)

Let me know you'd like to finish this (happy to have you be the contributor!), otherwise I'm happy to pick it up.

@jmcpeak
Copy link
Contributor Author

jmcpeak commented Mar 12, 2024

Let's wrap up this one. Here's how I think it should work:

  • Default entry is (only) ['mockServiceWorker.js']
  • In findDependencies we can look up localConfig?.workerDirectory and only if found, return the toEntryPattern(join()) of that dir and mockServiceWorker.js
  • No other entry patterns should be there, I think also mockServiceWorker.ts is not picked up by MSW?
  • I think that's it, really :)

Let me know you'd like to finish this (happy to have you be the contributor!), otherwise I'm happy to pick it up.

I'd love to take it over the finish line - I will implement the changes you requested today

@@ -10,7 +10,7 @@ import remarkStringify from 'remark-stringify';
import { unified } from 'unified';
import { u } from 'unist-builder';
import { base } from '../config.js';
import type { Plugin } from '../../knip/src/types/plugins.js';
import type { Plugin } from 'knip/dist/types/plugins.ts';
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this is an unrelated change?

@@ -1,3 +1,5 @@
// eslint-disable-next-line n/no-restricted-import
import path from 'node:path';
Copy link
Collaborator

Choose a reason for hiding this comment

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

The restriction is there for a reason, please use the internal join.

assert(issues.files.has(join(cwd, 'junk.js')));
assert(issues.files.has(join(cwd, 'mocks/junk.js')));
assert(issues.files.has(join(cwd, 'src/mocks/junk.js')));

assert.deepEqual(counters, {
...baseCounters,
devDependencies: 1,
files: 3,
files: 13,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please remove unused files, we don't need to assert that functionality in this test.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Please undo changes in the lockfile, I think they're unrelated?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They are, just forgot about it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

don't know why tests are failing, they work locally

Copy link
Collaborator

Choose a reason for hiding this comment

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

QA didn't pass because of this change: #513 (comment)

@webpro webpro merged commit 1404348 into webpro-nl:main Mar 14, 2024
7 of 11 checks passed
@webpro
Copy link
Collaborator

webpro commented Mar 14, 2024

🚀 This pull request is included in v5.1.0. See Release 5.1.0 for release notes.

@webpro
Copy link
Collaborator

webpro commented Mar 14, 2024

Thanks for bearing with me, Jason. Hope you don't mind I wrapped up the PR. It's out now! 🚀

@jmcpeak
Copy link
Contributor Author

jmcpeak commented Mar 14, 2024

Thanks for bearing with me, Jason. Hope you don't mind I wrapped up the PR. It's out now! 🚀

Don't mind at all, glad that I could contribute!

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

Successfully merging this pull request may close these issues.

2 participants