TypeError "styled": 符号不是函数

Posted

技术标签:

【中文标题】TypeError "styled": 符号不是函数【英文标题】:TypeError "styled": symbol is not a function 【发布时间】:2021-02-27 10:18:44 【问题描述】:

我正在运行 npm test 并收到以下错误:

 FAIL  src/App.test.js
  ● Test suite failed to run

    TypeError: symbol is not a function
        at String (<anonymous>)

      3 | import styled from "styled-components";
      4 | 
    > 5 | const NoAccess = styled(NoAccess_)`
        |                  ^
      6 |   width: 100px;
      7 |   height: 75px;
      8 | `;

      at options (node_modules/styled-components/src/models/StyledComponent.js:265:68)
      at je (node_modules/styled-components/src/models/StyledComponent.js:265:68)
      at Object.<anonymous> (src/App.js:5:18)
      at Object.<anonymous> (src/App.test.js:2:1)

styled 是在抛出错误的组件中导入的,所以我不确定为什么它是“不是函数”。

我在下面创建了一个最小的示例。

小例子

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

App.js

import React from "react"
import NoAccess_ from './NO_ACCESS.svg';
import styled from "styled-components";

const NoAccess = styled(NoAccess_)`
  width: 100px;
  height: 75px;
`;

function App() 
  return (
    <div className="App">
      <NoAccess />
    </div>
  );


export default App;

App.test.js

import React from "react"
import App from './App'
import  render, screen  from "@testing-library/react";

test("renders correct content", () => 
  const  getByText, getByLabelText  = render(<App />)
  screen.debug()
)

package.json


  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": 
    "@babel/plugin-transform-react-jsx": "^7.12.5",
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "identity-obj-proxy": "^3.0.0",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.0",
    "styled-components": "^5.2.1",
    "web-vitals": "^0.2.4"
  ,
  "scripts": 
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "jest",
    "eject": "react-scripts eject"
  ,
  "eslintConfig": 
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  ,
  "browserslist": 
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  ,
  "jest": 
    "verbose": false,
    "rootDir": ".",
    "collectCoverageFrom": [
      "**/*.js,jsx,ts,tsx",
      "!**/*.d.ts"
    ],
    "moduleFileExtensions": [
      "js",
      "jsx",
      "ts",
      "tsx"
    ],
    "moduleNameMapper": 
      "\\.(css|less|scss|sass|svg)$": "identity-obj-proxy"
    ,
    "transform": 
      "\\.[jt]sx?$": "babel-jest",
      "^.+\\.jsx?$": "babel-jest",
      "^.+\\.svg$": "<rootDir>/svgTransform.js"
    ,
    "transformIgnorePatterns": [
      "/node_modules/"
    ],
    "testMatch": [
      "**/*.spec,test.js,jsx,ts,tsx"
    ]
  ,
  "devDependencies": 
    "@babel/plugin-proposal-class-properties": "^7.12.1",
    "@babel/preset-env": "^7.12.1",
    "@babel/preset-react": "^7.12.5",
    "babel-jest": "^26.6.3",
    "jest": "^26.6.3"
  


<svg   viewBox="0 0 100 75" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M98.333 0H1.66699C0.746094 0 0 0.746094 0 1.66699V58.3335C0 59.2537 0.746094 59.9998 1.66699 59.9998H46.667V73.333C46.667 74.2539 47.4131 75 48.334 75H81.667C82.5879 75 83.334 74.2539 83.334 73.333V59.9998H98.333C99.2539 59.9998 100 59.2537 100 58.3335V1.66699C100 0.746094 99.2539 0 98.333 0ZM50 71.6667V44.9998H80V71.6667H50ZM65 28.3333C60.3994 28.3386 56.6719 32.0664 56.667 36.667V41.6665H53.333V36.667C53.333 30.2231 58.5566 25 65 25C71.4434 25 76.666 30.2239 76.666 36.667V41.6665H73.333V36.667C73.3281 32.0664 69.5996 28.3386 65 28.3333ZM70 36.667V41.6665H60V36.667C60 33.905 62.2383 31.6665 65 31.6665C67.7617 31.6665 70 33.905 70 36.667ZM96.667 56.6665H83.334V43.3335C83.334 42.4126 82.5879 41.6665 81.667 41.6665H80V36.667C80 28.3821 73.2842 21.6667 65 21.6667C56.7158 21.6667 50 28.3821 50 36.667V41.6665H48.334C47.4131 41.6665 46.667 42.4126 46.667 43.3335V56.6665H3.33301V16.6665H96.667V56.6665ZM96.667 13.333H3.33301V3.33325H96.667V13.333ZM10 53.333H26.667C27.5879 53.333 28.334 52.5869 28.334 51.6667V40.0212C28.3242 37.187 26.5273 34.6677 23.8506 33.7363C24.6006 32.6353 25.002 31.333 25 30V21.6665C25 20.7456 24.2539 19.9995 23.333 19.9995H13.334C12.4131 19.9995 11.667 20.7456 11.667 21.6665V30C11.666 31.333 12.0664 32.6353 12.8174 33.7363C10.1396 34.6677 8.34277 37.187 8.33398 40.0212V51.6667C8.33398 52.5869 9.08008 53.333 10 53.333ZM15.001 23.3328H21.667V30C21.667 31.8411 20.1748 33.3335 18.334 33.3335C16.4932 33.3335 15.001 31.8411 15.001 30V23.3328ZM11.667 40.0212C11.6689 38.1697 13.1699 36.6682 15.0215 36.6667H21.6455C23.4971 36.6682 24.999 38.1697 25 40.0212V49.9998H11.667V40.0212ZM93.333 6.66675H90V10H93.333V6.66675ZM83.334 6.66675H86.667V10H83.334V6.66675ZM63.333 66.6665V59.6931C61.9102 59.1897 60.79 58.0696 60.2861 56.646C59.3662 54.042 60.7305 51.1855 63.333 50.2654C65.9375 49.3447 68.7939 50.7095 69.7148 53.3127C70.6348 55.9158 69.2705 58.7729 66.667 59.6931V66.6665H63.333ZM66.667 55.0002C66.667 54.0793 65.9209 53.3333 65 53.3333C64.0791 53.3333 63.333 54.0793 63.333 55.0002C63.333 55.9204 64.0791 56.6665 65 56.6665C65.9209 56.6665 66.667 55.9204 66.667 55.0002Z" fill="#007079"/>
</svg>

我猜需要在配置中添加一些东西,但我不确定是什么。

到目前为止我所做的尝试:

1。将 svg 括在括号中使测试通过,但不是编译项目(npm run dev)

2。使用 moduleMapper(不工作)

"moduleNameMapper": 
      "\\.(svg)$": "<rootDir>/test/__mocks__/svgMock.js"
    

和 svgMock:

module.exports = '';

灵感来自Unit testing of styled-components with SVG imports。

(工作)肮脏的解决方案:

用 JS 导出 svg:

export default () =>
(<svg   viewBox="0 0 100 75" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M98.333 0H1.66699C0.746094 0 0 0.746094 0 1.66699V58.3335C0 59.2537 0.746094 59.9998 1.66699 59.9998H46.667V73.333C46.667 74.2539 47.4131 75 48.334 75H81.667C82.5879 75 83.334 74.2539 83.334 73.333V59.9998H98.333C99.2539 59.9998 100 59.2537 100 58.3335V1.66699C100 0.746094 99.2539 0 98.333 0ZM50 71.6667V44.9998H80V71.6667H50ZM65 28.3333C60.3994 28.3386 56.6719 32.0664 56.667 36.667V41.6665H53.333V36.667C53.333 30.2231 58.5566 25 65 25C71.4434 25 76.666 30.2239 76.666 36.667V41.6665H73.333V36.667C73.3281 32.0664 69.5996 28.3386 65 28.3333ZM70 36.667V41.6665H60V36.667C60 33.905 62.2383 31.6665 65 31.6665C67.7617 31.6665 70 33.905 70 36.667ZM96.667 56.6665H83.334V43.3335C83.334 42.4126 82.5879 41.6665 81.667 41.6665H80V36.667C80 28.3821 73.2842 21.6667 65 21.6667C56.7158 21.6667 50 28.3821 50 36.667V41.6665H48.334C47.4131 41.6665 46.667 42.4126 46.667 43.3335V56.6665H3.33301V16.6665H96.667V56.6665ZM96.667 13.333H3.33301V3.33325H96.667V13.333ZM10 53.333H26.667C27.5879 53.333 28.334 52.5869 28.334 51.6667V40.0212C28.3242 37.187 26.5273 34.6677 23.8506 33.7363C24.6006 32.6353 25.002 31.333 25 30V21.6665C25 20.7456 24.2539 19.9995 23.333 19.9995H13.334C12.4131 19.9995 11.667 20.7456 11.667 21.6665V30C11.666 31.333 12.0664 32.6353 12.8174 33.7363C10.1396 34.6677 8.34277 37.187 8.33398 40.0212V51.6667C8.33398 52.5869 9.08008 53.333 10 53.333ZM15.001 23.3328H21.667V30C21.667 31.8411 20.1748 33.3335 18.334 33.3335C16.4932 33.3335 15.001 31.8411 15.001 30V23.3328ZM11.667 40.0212C11.6689 38.1697 13.1699 36.6682 15.0215 36.6667H21.6455C23.4971 36.6682 24.999 38.1697 25 40.0212V49.9998H11.667V40.0212ZM93.333 6.66675H90V10H93.333V6.66675ZM83.334 6.66675H86.667V10H83.334V6.66675ZM63.333 66.6665V59.6931C61.9102 59.1897 60.79 58.0696 60.2861 56.646C59.3662 54.042 60.7305 51.1855 63.333 50.2654C65.9375 49.3447 68.7939 50.7095 69.7148 53.3127C70.6348 55.9158 69.2705 58.7729 66.667 59.6931V66.6665H63.333ZM66.667 55.0002C66.667 54.0793 65.9209 53.3333 65 53.3333C64.0791 53.3333 63.333 54.0793 63.333 55.0002C63.333 55.9204 64.0791 56.6665 65 56.6665C65.9209 56.6665 66.667 55.9204 66.667 55.0002Z" fill="#007079"/>
</svg>)

【问题讨论】:

您能否更新您的问题以包含导入NoAccess_ 的组件的Minimal, Complete, and Reproducible 代码示例? @DrewReese 现在添加了最小示例。 【参考方案1】:

看起来您将加载程序设置为导入svg 以返回一个组件,这意味着只要您可以通过使用在svg 文件的情况下返回jsx 的转换器来对jest 执行相同的方式.

我建议使用jest-svg-transformer 转换svg 文件如下:

// Install 
// npm i -D jest-svg-transformer / yarn add -D jest-svg-transformer

transform: 
  // ...
  "\\.svg$": "jest-svg-transformer"
,

您还必须删除现有的映射器模拟 svg 文件:

"moduleNameMapper": 
  "\\.(css|less|scss|sass)$": "identity-obj-proxy", // Remove `svg` from this pattern
,

【讨论】:

仍然得到相同的 TypeError: symbol is not a function for styled(...) 不幸的是 请记住直接使用transform。你能分享你到目前为止所做的一切吗?配置? 或者创建一个最小的可重现 repo 会更好 Minimal Repo 问题是有一个现有的 svg 文件模拟文件,它会覆盖导致问题的变压器文件。我还是为你更新了答案

以上是关于TypeError "styled": 符号不是函数的主要内容,如果未能解决你的问题,请参考以下文章

改变dom的style

vue style class 动态绑定

使用JQuery完成表格的隔行换色

使用kubeadm快速启用一个集群

如何用JS给div添加样式

TypeError: undefined is not a function (in '...styled Components.default.button...')