rsnext/packages/next/build/jest/jest.ts
Tim Neutkens 2800a2b1c0
Ensure next/jest is published (#31296)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2021-11-11 11:48:12 +01:00

134 lines
4.6 KiB
TypeScript

import { loadEnvConfig } from '@next/env'
import { resolve, join } from 'path'
import loadConfig from '../../server/config'
import { PHASE_TEST } from '../../shared/lib/constants'
// import loadJsConfig from '../load-jsconfig'
import * as Log from '../output/log'
async function getConfig(dir: string) {
const conf = await loadConfig(PHASE_TEST, dir)
return conf
}
/**
* Loads closest package.json in the directory hierarchy
*/
function loadClosestPackageJson(dir: string, attempts = 1): any {
if (attempts > 5) {
throw new Error("Can't resolve main package.json file")
}
var mainPath = attempts === 1 ? './' : Array(attempts).join('../')
try {
return require(join(dir, mainPath + 'package.json'))
} catch (e) {
return loadClosestPackageJson(dir, attempts + 1)
}
}
console.warn(
'"next/jest" is currently experimental. https://nextjs.org/docs/messages/experimental-jest-transformer'
)
/*
// Usage in jest.config.js
const nextJest = require('next/jest');
// Optionally provide path to Next.js app which will enable loading next.config.js and .env files
const createJestConfig = nextJest({ dir })
// Any custom config you want to pass to Jest
const customJestConfig = {
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
}
// createJestConfig is exported in this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig)
*/
export default function nextJest(options: { dir?: string } = {}) {
// createJestConfig
return (customJestConfig: any) => {
// Function that is provided as the module.exports of jest.config.js
// Will be called and awaited by Jest
return async () => {
let nextConfig
let paths
let resolvedBaseUrl
let isEsmProject = false
if (options.dir) {
const resolvedDir = resolve(options.dir)
const packageConfig = loadClosestPackageJson(resolvedDir)
isEsmProject = packageConfig.type === 'module'
nextConfig = await getConfig(resolvedDir)
loadEnvConfig(resolvedDir, false, Log)
// TODO: revisit when bug in SWC is fixed that strips `.css`
// const result = await loadJsConfig(resolvedDir, nextConfig)
// paths = result?.jsConfig?.compilerOptions?.paths
// resolvedBaseUrl = result.resolvedBaseUrl
}
// Ensure provided async config is supported
const resolvedJestConfig =
typeof customJestConfig === 'function'
? await customJestConfig()
: customJestConfig
return {
...resolvedJestConfig,
moduleNameMapper: {
// Handle CSS imports (with CSS modules)
// https://jestjs.io/docs/webpack#mocking-css-modules
'^.+\\.module\\.(css|sass|scss)$':
require.resolve('./object-proxy.js'),
// Handle CSS imports (without CSS modules)
'^.+\\.(css|sass|scss)$': require.resolve('./__mocks__/styleMock.js'),
// Handle image imports
'^.+\\.(jpg|jpeg|png|gif|webp|avif|svg)$': require.resolve(
`./__mocks__/fileMock.js`
),
// Custom config will be able to override the default mappings
...(resolvedJestConfig.moduleNameMapper || {}),
},
testPathIgnorePatterns: [
// Don't look for tests in node_modules
'/node_modules/',
// Don't look for tests in the the Next.js build output
'/.next/',
// Custom config can append to testPathIgnorePatterns but not modify it
// This is to ensure `.next` and `node_modules` are always excluded
...(resolvedJestConfig.testPathIgnorePatterns || []),
],
transform: {
// Use SWC to compile tests
'^.+\\.(js|jsx|ts|tsx)$': [
require.resolve('../swc/jest-transformer'),
{
styledComponents:
nextConfig && nextConfig.experimental.styledComponents,
paths,
resolvedBaseUrl: resolvedBaseUrl,
isEsmProject,
},
],
// Allow for appending/overriding the default transforms
...(resolvedJestConfig.transform || {}),
},
transformIgnorePatterns: [
// To match Next.js behavior node_modules is not transformed
'/node_modules/',
// CSS modules are mocked so they don't need to be transformed
'^.+\\.module\\.(css|sass|scss)$',
// Custom config can append to transformIgnorePatterns but not modify it
// This is to ensure `node_modules` and .module.css/sass/scss are always excluded
...(resolvedJestConfig.transformIgnorePatterns || []),
],
}
}
}
}