简体   繁体   English

Storybook - 无法在不抛出无尽的 NPM 错误的情况下模拟嵌套的 React-Router-Dom 链接

[英]Storybook - Cannot Mock a Nested React-Router-Dom Link without throwing endless NPM errors

I am trying to implement StorybookJS into a SSR React app.我正在尝试将 StorybookJS 实现到 SSR React 应用程序中。 Basic components work fine (button, headers etc).基本组件工作正常(按钮、标题等)。 But anything that nests using dependencies like react-router-dom breaks.但是任何使用react-router-dom等依赖项嵌套的东西都会中断。

Example: We have a custom built <Link /> component that manages external links with a ternary.示例:我们有一个自定义构建的<Link />组件,它使用三元组管理外部链接。 The external links flip to <a href= while internals use react-router-dom's <Link> imported as <ReactLink /> .外部链接翻转为<a href=而内部使用 react-router-dom 的<Link>导入为<ReactLink /> That code is like this:该代码是这样的:

// src/client/components/link/Link.js 

import { Link as ReactLink } from "react-router-dom";
import { isLinkExternal } from "services/utils";

export const Link = ({ href, children = null, ...props }) => {

  return isLinkExternal(href) ? (
    <a href={href} {...props}>
      {children}
    </a>
  ) : (
    <ReactLink to={href} {...props}>
      {children}
    </ReactLink>
  );
};

The StorybookJS file for it looks like this:-它的 StorybookJS 文件如下所示:-

// link.stories.js

import React from "react";
import { Link } from "./Link"; // importing my component

export default {
  title: "My Components/Link",
  component: Link, // assigning my component
};

export const MyStoryBookLink = () => <Link href="/foo">I am a link</Link>;

Now, when i run Storybook it throws a load of errors, here are the recurring/main ones:-现在,当我运行 Storybook 时,它会抛出一大堆错误,以下是重复出现的/主要的错误:-

ERROR in ./node_modules/redis-parser/lib/hiredis.js
Module not found: Error: Can't resolve 'hiredis' in '/Users/me/Documents/my-proj/node_modules/redis-parser/lib'
...
...
@ ./.storybook/generated-stories-entry.js

I haven't touched anything redis / hiredis related and there is no such file as generated-stories-entry.js .我没有接触任何与 redis / hiredis 相关的东西,也没有generated-stories-entry.js这样的文件。 The app works perfectly in Dev and Production so this is exclusively a Storybook env issue.该应用程序在 Dev 和 Production 中完美运行,因此这完全是 Storybook 环境问题。

Next error down:下一个错误:

ERROR in ./node_modules/cache-manager-ioredis/node_modules/ioredis/lib/connectors/connector.js
Module not found: Error: Can't resolve 'net' in '/Users/me/Documents/myProject/node_modules/cache-manager-ioredis/node_modules/ioredis/lib/connectors'

Again, Though we are using cache-manager-ioredis , no idea why this is suddenly missing a module if it works fine on the app itself and all i'm trying to do is render a.同样,虽然我们使用的cache-manager-ioredis ,但不知道为什么突然缺少一个模块,如果它在应用程序本身上运行良好,而我想要做的就是渲染一个。

Next one:下一个:

Module not found: Error: Can't resolve 'tls' in cache-manager-ioredis

Same thing again^^又是一样的^^

Then i get a load of these:然后我得到了这些:

     /Users/me/Documents/myProj/__mocks__/hiredis doesn't exist
            .mjs
              /Users/me/Documents/myProj/__mocks__/hiredis.mjs doesn't exist
            .js
              /Users/me/Documents/myProj/__mocks__/hiredis.js doesn't exist
            .jsx
              /Users/me/Documents/myProj/__mocks__/hiredis.jsx doesn't exist
            .ts
              /Users/me/Documents/myProj/__mocks__/hiredis.ts doesn't exist
            .tsx
              /Users/me/Documents/myProj/__mocks__/hiredis.tsx doesn't exist
            .json
              /Users/me/Documents/myProj/__mocks__/hiredis.json doesn't exist
            .cjs
              /Users/me/Documents/myProj/__mocks__/hiredis.cjs doesn't exist

Suggests it's looking for mocks to cover these sub sub sub dependencies, wherever they're needed.建议它正在寻找模拟来覆盖这些 sub sub sub 依赖项,无论它们在哪里需要。

I get the same for net and tls .我对nettls也一样。

Finally, I get some:最后,我得到一些:

Field 'browser' doesn't contain a valid alias configuration

I'm thinking somewhere in the depths of using react-router-dom/Link it is trying to find these, and they would only be there if webpack dev server / hot reloading made them accessible, OR if they were transpiled to be accessible from the production bundle.我正在考虑在使用react-router-dom/Link的深处某处,它试图找到这些,并且只有在 webpack 开发服务器/热重载使它们可访问,或者如果它们被转换为可从生产包。

But how do I mock these out?但是我如何嘲笑这些呢? And is there an easy way to do it rather than manually mocking every sub dependency?有没有一种简单的方法可以做到这一点,而不是手动 mocking 每个子依赖项?

I have tried:我努力了:

  1. adding __mocks__/react-router-dom.js with an export const Link = ({props}) => <div>{children}</div> but it doesnt seem to kick in.使用export const Link = ({props}) => <div>{children}</div>添加__mocks__/react-router-dom.js但它似乎没有启动。

  2. adding alias logic to .storybook/main.js :alias逻辑添加到.storybook/main.js

webpackFinal: (config) => {
    config.resolve.alias['react-router-dom'] = require.resolve('../__mocks__/react-router-dom.js');
    return config;
  },

Again, nothing seems to change.同样,似乎没有任何改变。

  1. using the storybook-react-router pkg but this seems quite old now, it configs to an old config.js file rather than main.js and uses the older storiesOf syntax.使用storybook-react-router pkg 但这现在看起来很旧,它配置到旧的config.js文件而不是main.js并使用旧的storiesOf语法。 Also couldn't get to do anything.也无能为力。

  2. manually installed tls , hiredis etc as --save-dev dependencies.手动安装tlshiredis等作为--save-dev依赖项。 But this seems hack.但这似乎很骇人听闻。 Why are these modules missing?为什么缺少这些模块?

I cannot believe Storybook is this hard to use, more likely I'm overlooking something.我不敢相信 Storybook 这么难用,更有可能是我忽略了一些东西。 I just want to mock something as common and basic as a from RRD.我只想模拟一些像 RRD 中的 a 一样常见和基本的东西。

What am I doing wrong?我究竟做错了什么? What am I missing?我错过了什么?

I think I found the reason.我想我找到了原因。 It is because of node.js packages.这是因为 node.js 个包。 To make it work, there are 2 solutions.要使其工作,有 2 个解决方案。

  1. avoid importing node.js packages (usually related to SSR) for storybook related code.避免为 storybook 相关代码导入 node.js 包(通常与 SSR 相关)。 I use NX to structure my code, so I can easily move those part to its own library and only reference it from the top.我使用 NX 来构建我的代码,因此我可以轻松地将这些部分移动到它自己的库中,并且只从顶部引用它。 (No storybook for the top App either in this solution) (此解决方案中也没有顶级应用程序的故事书)

  2. skip those packages in the config.跳过配置中的那些包。

something like就像是

config.resolve.fallback = { http: false, net: false, tls: false, fs: false, dns: false, path: false };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM