Linaria: Jest tests fail: Using the "styled" tag in runtime is not supported.

Created on 3 Jul 2020  ·  2Comments  ·  Source: callstack/linaria

Environment

  • Linaria version: 1.3.3
  • Node.js version: v12.16.2
  • OS: MacOS 10.15.5
  • jest/babel-jest: 26.1.0
  • react: 16.13.1

Description

Hi! I want to change emotion to linaria, but I met a problem with testing.

I have a component with styled.*:

export const Clamper = styled.span<T.Clamper>`
  overflow: hidden;

   ....
`;

jest.config.js:

module.exports = {
  preset: 'ts-jest',
  testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|tests).[tj]s?(x)'],
  // setupFilesAfterEnv: ['<rootDir>/config/jest/jest.setup.ts'],
  testPathIgnorePatterns: ['<rootDir>/node_modules/'],
  moduleNameMapper: {
    '@/(.*)$': '<rootDir>/src/$1',
    '.*\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|pdf)$':
      '<rootDir>/config/jest/fileMock.js',
    '\\.(css)$': '<rootDir>/config/jest/styleMock.js',
  },
  globals: {
    'ts-jest': {
      babelConfig: true,
    },
  },
};

And when I run test, I get the problem(but with build is fine):
Screenshot 2020-07-03 at 03 07 02

Please, help me, I tried different ways already

Reproducible Demo

Please clone and install the following git repo: https://github.com/viczhuravlev/gramr-ui/tree/feat/changeEmotionToLinaria

bug report 🦗 modules aliasing 🔗 testing 🛡 complete repro 🖥️

All 2 comments

I'm also facing this error with Jest + Linaria + React + TypeScript, using ts-jest and using the following config:

module.exports = {
  testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.([tj]sx?)$",
  moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"],
  testPathIgnorePatterns: [`node_modules`],
  testURL: `http://localhost`,
  moduleNameMapper: {
    ".+\\.(css|styl|less|sass|scss)$": `identity-obj-proxy`,
  },
  transform: {
    "^.+\\.tsx?$": `ts-jest`,
  },
  globals: {
    __PATH_PREFIX__: ``,
    "ts-jest": {
      babelConfig: {
        presets: [
          ["@babel/preset-env", { targets: { node: "current" } }],
          "@babel/preset-react",
          ["linaria/babel", { evaluate: true, displayName: true }],
        ],
      },
    },
  },
};

Environment

  • Linaria version: 1.4.0-beta.10
  • Node.js version: v10.21.0
  • OS: Ubuntu 20.04 LTS x86_64
  • Jest: 26.1.0
  • React: 16.13.1
  • TypeScript: 3.9.6
  • ts-jest: 26.1.3
  • @babel/core: 7.10.4

Investigation

I'm not sure if I'm facing the same issue as @viczhuravlev, though I suspect I am. Debugging the linaria/babel preset using the Node debugger and placing a breakpoint inside linaria/babel/utils/isStyledOrCss.ts to investigate the shape of the Babel AST in both:

  • A working Linaria + TypeScript build using Gatsby and gatsby-plugin-linaria
  • My current non-functional Jest build using the above config.

From source code that looks like:

import { styled } from "linaria/react";
import React from "react";

const Styled = {
  Path: styled.circle`
    fill: none;
    stroke: var(--color);
    stroke-linecap: round;
    stroke-width: var(--stroke);

    animation: spinnerDash 1.5s ease-in-out infinite;
  `,
};

export default Styled.Path;

The Gatsby and Jest-based builds have slightly different ASTs regarding line numbers, but the most significant difference appears to be the difference between the AST subtree destructed as tag on babel/utils/isStyledOrCss.ts#L15.

AST Tag Nodes

In these, there is the existence of a new parent object on the styled template tag, react_1, which when looking at the generated code from the AST, is the import alias created during transpilation:

"use strict";

var __importDefault = this && this.__importDefault || function (mod) {
  return mod && mod.__esModule ? mod : {
    "default": mod
  };
};

Object.defineProperty(exports, "__esModule", {
  value: true
});

const react_1 = require("linaria/react");

const react_2 = __importDefault(require("react"));

const Styled = {
  Path: react_1.styled.circle`
    fill: none;
    stroke: var(--primary);
    stroke-linecap: round;
    stroke-width: 8px;
  `
};

const Spinner = () => <svg viewBox="0 0 50 50">
    <Styled.Path cx="25" cy="25" r="20" />
  </svg>;

exports.default = Spinner;

This is from the whole file, which is here (gist). For comparison, the Gatsby build is here (gist).

Was this page helpful?
0 / 5 - 0 ratings