storybook: Getting "Cannot use import statement outside a module" with MDX files running with Jest

Describe the bug When I add MDX documentation files into my Storybook and run Storyshots with Jest I’m getting SyntaxError: Cannot use import statement outside a module for each of loaded MDX.

Expected behavior Console should be without errors

Code snippets

console.warn
    Unexpected error: SyntaxError: Cannot use import statement outside a module

      at Object.warn (node_modules/@storybook/client-logger/dist/index.js:53:73)
      at node_modules/@storybook/core/dist/client/preview/loadCsf.js:110:34
          at Array.forEach (<anonymous>)
      at node_modules/@storybook/core/dist/client/preview/loadCsf.js:103:20
          at Array.forEach (<anonymous>)
      at node_modules/@storybook/core/dist/client/preview/loadCsf.js:102:12
      at ConfigApi.configure (node_modules/@storybook/client-api/dist/config_api.js:27:7)
//jest.config.js

module.exports = {
  roots: ['./src'],
  setupFilesAfterEnv: ['./jest.setup.ts'],
  moduleFileExtensions: ['js', 'ts', 'tsx', 'json'],
  testPathIgnorePatterns: ['node_modules/'],
  transform: {
    '^.+\\.tsx?$': 'ts-jest',
    '^.+\\.mdx?$': '@storybook/addon-docs/jest-transform-mdx',
  },
  testMatch: ['./**/*.(test).(ts|tsx)'],
  moduleNameMapper: {
    '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
      'identity-obj-proxy',
  },
};
// main.ts

module.exports = {
  stories: ['../src/**/*.stories.@(tsx|jsx|mdx)'],
  addons: ['@storybook/addon-actions', '@storybook/addon-docs'],
  typescript: {
    check: false,
    checkOptions: {},
    reactDocgen: 'react-docgen-typescript',
    reactDocgenTypescriptOptions: {
      shouldExtractLiteralValuesFromEnum: true,
      propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true),
    },
  },
};
//storyshots/jest.config.js

/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');
const { mergeRight } = require('ramda');
const globalJestConfig = require('../jest.config');
/* eslint-enable */

const storyshotsJestConfig = {
  rootDir: path.join(__dirname, '..'),
  roots: ['./storyshots'],
  testMatch: ['./**/storyshots.runner.ts'],
};

module.exports = mergeRight(globalJestConfig, storyshotsJestConfig);
// storyshots/storyshots.runner.ts
import path from 'path';
import initStoryshots from '@storybook/addon-storyshots';
import { imageSnapshot } from '@storybook/addon-storyshots-puppeteer';

const pathToStorybookStatic = path.join(__dirname, '../storybook-static');

const beforeScreenshot = () => {
  return new Promise(
    (resolve) =>
      setTimeout(() => {
        resolve();
      }, 1000), // sometimes text doesn't render in time, so we wait one second for each image
  );
};

initStoryshots({
  suite: 'Image snapshots',
  storyNameRegex: /^((?!.*?DontTest).)*$/,
  framework: 'react',
  configPath: path.join(__dirname, '../.storybook'),
  test: imageSnapshot({
    beforeScreenshot,
    storybookUrl:
      process.env.CI === 'true'
        ? `file://${pathToStorybookStatic}`
        : `http://host.docker.internal:6006`,
    getMatchOptions: () => ({
      failureThreshold: 0.0,
      failureThresholdType: 'percent',
    }),
  }),
});

System:

System:
    OS: macOS 10.15.4
    CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
  Binaries:
    Node: 12.13.1 - ~/.nvm/versions/node/v12.13.1/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.14.5 - ~/Documents/PROJECTS/ambrosia-design-system/node_modules/.bin/npm
  Browsers:
    Chrome: 83.0.4103.116
    Safari: 13.1
  npmPackages:
    @storybook/addon-actions: ^6.0.0-beta.36 => 6.0.0-beta.37 
    @storybook/addon-docs: ^6.0.0-beta.36 => 6.0.0-beta.37 
    @storybook/addon-storyshots: ^6.0.0-beta.36 => 6.0.0-beta.37 
    @storybook/addon-storyshots-puppeteer: ^6.0.0-beta.36 => 6.0.0-beta.37 
    @storybook/react: ^6.0.0-beta.36 => 6.0.0-beta.37 
    @storybook/theming: ^6.0.0-beta.36 => 6.0.0-beta.37 

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 11
  • Comments: 19 (6 by maintainers)

Most upvoted comments

I replaced ts-jest to babel-jest and the error was disappear.

1. Install the babel

yarn add -D babel-jest @babel/preset-env @babel/preset-react @babel/preset-typescript

2. Create the jest.transform.js file

module.exports = require('babel-jest').createTransformer({
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          esmodules: true,
        },
      },
    ],
    '@babel/preset-react',
    '@babel/preset-typescript',
  ],
});

3. Add transform to your jest.config.js

module.exports = {
  testEnvironment: 'jsdom',
  transform: {
    '^.+\\.[tj]sx?$': './jest.transform.js',
    '^.+\\.mdx?$': '@storybook/addon-docs/jest-transform-mdx',
  },
};

@shilman Any update on this?

I have the same problem when running Jest after enabling the storyshot addon. It can also be reproduced on the ‘sb init’ project.

@oxilor this did not fix for me 😦

My repo’s setup to use CSF for Stories with MDX for docs. Because my MDX is only for docs, I don’t actually need the MDX for my unit tests so I can just tell Jest to throw it away:

jest.config.js

module.exports = {
  moduleNameMapper: {
    '\\.mdx?$': '<rootDir/__mocks__/mdxMock.js',
  }
}

mocks/mdxMock.js

module.exports = {}

I created a repo with configuration that works for me, but in this project storyshots started to include Storybook’s stories from node_modules. In my real project it works nice. Unfortunately, I don’t have time to deal with this problem. If someone knows how to fix it, let me know.

@ajkl2533 Did you get this to work with ts-jest ?

I just discovered this project, so I pretty much don’t know what I’m doing. I got this error because my .babel file wasn’t in the root directory of the project. I know nothing about Babel, but I’d make sure that’s straight. I’m trying to follow along with the Svelte /SBV6 tutorials.

Hi everyone! Seems like there hasn’t been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don’t have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!