vuejs / router

🚦 The official router for Vue.js
https://router.vuejs.org/
MIT License
3.93k stars 1.19k forks source link

Provide a way to disable warnings for "No match found" when testing #359

Closed cexbrayat closed 4 years ago

cexbrayat commented 4 years ago

What problem does this feature solve?

When adding tests to a component using the router, one might need to provide a mock router. I currently use:

const mockRouter = createRouter({ history: createWebHistory(), routes: [] });
describe('Navbar.vue', () => {
  test('should ...', () => {
    const navbar = mount(Navbar, {
      global: {
        plugins: [mockRouter],
        stubs: {
          RouterLink: RouterLinkStub
        }
      }
    });
    // ...
  });
});

It works perfectly, but the router emits a warning:

console.warn node_modules/vue-router/dist/vue-router.cjs.js:225
    [Vue Router warn]: No match found for location with path "/"

As most tests are using the same code, the warning is emitted a lot and pollutes the test output.

What does the proposed API look like?

Until VTU or the router itself provides built-in support for testing (if ever, see https://github.com/vuejs/vue-test-utils-next/issues/152 for curious readers), do you think we could guard this warning with a setting to hide it? I can open a PR if you provide some guidance (and think this is useful of course).

posva commented 4 years ago

I see how this can be annoying. I think it's better to remove it, like in Vue router 3. It can be added in user land with a beforeEach hook:

router.beforeEach((to, from, next) => {
  if (!to.matched.length) console.warn('no match')
  next()
})
cexbrayat commented 4 years ago

The user land solution is a nice workaround, but quite cumbersome to add to every test suite in a real project :)

I'm not sure I understood you correctly sorry: I think it's better to remove it -> do you want a PR removing the warning from the codebase?

Edit: the proper one is https://github.com/vuejs/vue-router-next/blob/e050abcf617f5e35e1f251a58f364bc1ee73f68a/src/router.ts#L263-L265

posva commented 4 years ago

I'm not sure I understood you correctly sorry: I think it's better to remove it -> do you want a PR removing the warning from the codebase

yes. The warning can be added in user land for specific projects. We could also disable it if __TEST__ is defined or something similar that is defined by VTU

posva commented 4 years ago

On a second thought, this will help beginners (by helping them to find typos in to props) much more than it will hurt advanced users (by flooding their console) and can be fixed by adding a match all route to the test environment:

{ path: '/:pathMatch(.*)', component: NotFound }

In the case of a fake router, this can be handled internally as well

posva commented 4 years ago

As talked previously, this is helping more people than it's hurting. It's a common mistake to do a typo and people not realizing it. In the case of tests, we will provide a mocked router anyway

migken commented 4 years ago

This warn is too stupid, please remove it.

vincerubinetti commented 2 years ago

The warning existing isn't stupid. But it's also quite common to provide users a logLevel parameter to control what types of info is logged. The maintainers should consider adding something like that.

Currently I'm testing a page that has hundreds of undefined routes (they won't be undefined in the future, but for now they are), and I have to do a log of scrolling to find the console information I'm actually looking for.

isaackearl commented 1 year ago

Is there still no way to disable the vue-router warning?

kevinwheeler commented 1 year ago

Although it adds a (display none) DOM element, adding this to my route config seems to work for my purposes to suppress the warning.

    {
        path: "/my-path",
        name: "MyRouteName",
        // Suppress the warning: [Vue Router warn]: Record with path "/my-path" is either missing a "component(s)" or "children" property.
        component: {template: `<span style="display: none;"></span>`}
    },
hokkaido commented 1 year ago

@posva In a duplicate of this #1828 I mentioned other use cases outside of just testing where one would want to use the router's resolve method. One is the situation where routes and redirects can be provided through an API or through other external sources and where it makes sense to check whether there already exists a route that resolves to a url. So basically in situations where you want to add dynamic routes to an existing route table.

Additionally, vue has a configurable warn handler where it would make sense for it to be used in this project as well instead of rolling its own?

mcpeakdb commented 1 year ago

Flagging to ask why not consider adding a configuration option to disable this? A happy compromise for the rookie and expert developer.

deckerdent commented 11 months ago

I stumbled over this, is this something being considered? Have the same "problem". The warning doesn't hurt me personally but I'm about to write a template for multiple dev teams working in a micro-frontend setup and starting the app and already have warnings seems odd to me.

TLDR; when one uses vue-router as the primary router in a micro-frontend setup (in my case with single-spa) you want it to handle the url updates and history but not the rendering of components as the framework will do this. It would be good if one could suppress the warning in this case

The case:

I work with single-spa. I create micro-frontend app templates for common page partials such as header, nav, footer and so on. We will reuse these every time we start a new single-spa project, basically cloning the "commons" micro-frontend projects. E.g. Clone the header and give it a new logo or title, clone the nav give it new links/routes and so on...

I'm now working on a nav micro-frontend template and this will serve as the primary router for the single-spa apps. Eventually it will trigger single-spa to mount / unmount other micro-frontends. The app uses vue-router but routes only consist of path and name. They don't need a component as single-spa will mount or unmount micro-frontends on url-changes this vue-router triggers. I don't want, when another developer clones this micro-frontend, a warning is shown in the console.

vincerubinetti commented 3 months ago

So I have a generic AppLink component that handles using RouterLink vs a as appropriate (and handles some other things). I tried putting a check in it like this:

const component = computed(() =>
  router.resolve(props.to).name ? "RouterLink" : "a",
);

But I still see the warning logs. I'm guessing the warnings are coming from router.resolve as well.

Does anyone know a way to check if any given route path (not route name, and not just the current route) matches any of the defined routes without producing a warning (and without doing a poor re-implementation of the route matching vue-router does under the hood)?