jaredpalmer / tsdx

Zero-config CLI for TypeScript package development
https://tsdx.io
MIT License
11.24k stars 508 forks source link

how to test components generated by tsdx builds? #885

Closed anil-sequoia closed 3 years ago

anil-sequoia commented 3 years ago

Current Behavior

We have a component, hooks and utilities library which is private repo based on lerna and tsdx.

The name of the packages are as follows @eureka/components, @eureka/hooks and @eureka/utilities

The dist folder of components has index.js files which looks like this:

'use strict'

if (process.env.NODE_ENV === 'production') {
  module.exports = require('./components.cjs.production.min.js')
} else {
  module.exports = require('./components.cjs.development.js')
}

And then the component.cjs.development has import like below:

var PropTypes = _interopDefault(require('prop-types'));
var styled = require('styled-components');
var styled__default = _interopDefault(styled);
var css$ = _interopDefault(require('@styled-system/css'));
var styledSystem = require('styled-system');
var AllTheExportsFromHooks = require('@eureka/hooks');
var AllTheExportsFromComponents = require('@eureka/components');
var ReactDOM = _interopDefault(require('react-dom'));
var dateFns = require('date-fns');
var DatePicker = _interopDefault(require('react-datepicker'));
require('react-datepicker/dist/react-datepicker.css');
var lodash = require('lodash');
var AllTheExportsFromUtilities = require('@eureka/utilities');
var reactLive = require('react-live');

// .... more code blow.

Now this same dist folder becomes part on node_modules in another application where I am using @eureka/components

Now in dev mode and production mode it all works fine.

But the problem is with tests in this consumer application

I have started writing unit test cases using react-testing-library and jest

But the import i showed above does not resolve. and cause failure in test runs.

What all I was able to figure out yet:

The jest will not transform anything in node_modules by default. Hence the require statements in cjs file will not be resolved.

Basically if you will see above

var AllTheExportsFromComponents = require('@eureka/components');

The line above is blank object. Ideally it should have reference to the object having all the components returned from @eureka/components.

My jest config looks like this now:

module.exports = {
    'roots': ['<rootDir>/src'],
    'collectCoverageFrom': ['src/**/*.{js,jsx,ts,tsx}', '!src/**/*.d.ts'],
    'setupFiles': [
        'jest-canvas-mock',
        'react-app-polyfill/jsdom',
        './src/unitTestingConfig/setup.js',
    ],
    'setupFilesAfterEnv': ['./src/unitTestingConfig/setFilesAfterEnv.js'],
    'testMatch': [
        '<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}',
        '<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}',
    ],
    'testEnvironment': 'jest-environment-jsdom-fourteen',
    'transform': {
        '^.+\\.(js|jsx|ts|tsx)$': '<rootDir>/node_modules/babel-jest',
        // 'node_modules\\/@eureka\\/.*.\\/dist\\/.*.(js|jsx)$': '<rootDir>/node_modules/babel-jest',
        '^.+\\.css$': '<rootDir>/config/jest/cssTransform.js',
        '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '<rootDir>/config/jest/fileTransform.js',
    },
    'transformIgnorePatterns': [
        '!node_modules\\/@eureka\\/.*.\\/dist\\/.*.(js|jsx)$',
        '[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$',
        '^.+\\.module\\.(css|sass|scss)$',
    ],
    'modulePaths': ['./src'],
    'moduleNameMapper': {
        '^react-native$': 'react-native-web',
        '^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy',
    },
    'moduleFileExtensions': [
        'web.js',
        'js',
        'web.ts',
        'ts',
        'web.tsx',
        'tsx',
        'json',
        'web.jsx',
        'jsx',
        'node',
    ],
    'watchPlugins': ['jest-watch-typeahead/filename', 'jest-watch-typeahead/testname'],
    'moduleDirectories': ['node_modules', './src/unitTestingConfig'],
};

So my question is, what can do right to fix this scenario or it is not a good practice to test component's behavior coming from node_modules.

Your environment

System:
    OS: macOS Mojave 10.14.5
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 281.99 MB / 16.00 GB
    Shell: 5.3 - /bin/zsh
  Binaries:
    Node: 12.10.0 - ~/.nvm/versions/node/v12.10.0/bin/node
    Yarn: 1.17.3 - ~/.nvm/versions/node/v12.10.0/bin/yarn
    npm: 6.10.3 - ~/.nvm/versions/node/v12.10.0/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Browsers:
    Chrome: 85.0.4183.121
    Firefox: 72.0.2
    Safari: 12.1.1
agilgur5 commented 3 years ago

Sorry to hear about your troubles, but I'm not sure how this is related to TSDX and you haven't made that clear. The files are already compiled so you shouldn't have to transform them, they work in dev and prod, and tsdx test shallow merges your Jest config, so you've already overwritten much of it.

Issues also are not a support forum for debugging help. Feel free to use StackOverflow or something, but even there the expectation is that you furnish an MVCE, which is quite lacking here. You've only provided a few small snippets of a seemingly large codebase, and not a minimal reproduction.

I've provided some comments on your statements below, but, to repeat, this is not a support forum for debugging help, especially not for issues unrelated to TSDX.


The dist folder of components has index.js files which looks like this:

Yes, that's normal, intended behavior

var AllTheExportsFromComponents = require('@eureka/components');

This sounds like a recursive import, you said this is inside of components...

The jest will not transform anything in node_modules by default. Hence the require statements in cjs file will not be resolved.

I'm not sure how those are related -- transforms and resolutions are two different things. You normally don't need to transform anything in node_modules either -- it contains built / compiled / transpiled code. Files output to dist/ by TSDX are already built, there's no need to transform them.

The line above is blank object. Ideally it should have reference to the object having all the components returned from @eureka/components.

If this returns something then that means it is resolved. If it's "not resolved", then Node will throw an error.

So my question is, what can do right to fix this scenario or it is not a good practice to test component's behavior coming from node_modules.

I don't understand what the problem is to begin with, but no, normally one tests the package itself. That also enables test watch mode (i.e. tsdx test --watch), which can't be done when testing dist/ instead of src/ without running another process to constantly build (i.e. tsdx watch). You can have integration tests on top of that though, which would, almost by definition, test installed packages.