-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
default transformFunctions doesn't include jest-resolve's Resolver.resolveModule #375
Comments
In the end I wrote a custom jest resolver that reads from my webpack config, uses The implementation could definitely be cleaned up and made a bit more robust/generic, probably some generic 'xConfigAdapter' type things to map jest/babel/etc config -> the appropriate const fs = require('fs')
const path = require('path')
const webpackMerge = require('webpack-merge')
const { CachedInputFileSystem, ResolverFactory } = require('enhanced-resolve')
// TODO: If we wanted to read config out of babel..
// Ref: https://babeljs.io/docs/en/babel-core#advanced-apis
const getSanitisedNodeEnv = () => {
const nodeEnv = process.env.NODE_ENV
switch (nodeEnv) {
case 'development':
case 'test':
case 'production':
return nodeEnv
default:
return 'test'
}
}
const root = fs.realpathSync(process.cwd())
// We want to be able to import from our webpack config
// Refs:
// https://webpack.js.org/configuration/resolve/
// https://webpack.js.org/api/resolvers/
const webpackConfig = require(`${root}/config/webpack/${getSanitisedNodeEnv()}`)
const jestDefaults = require('jest-config').defaults
// We want to be able to import from our jest config
const jestConfig = require(`${root}/jest.config`)
// Ref: https://github.com/facebook/jest/blob/master/packages/jest-runtime/src/cli/index.ts#L59-L68
// TODO: Read the jest config 'properly' (including parsing everything)
// Validation Error: Module jest-localstorage-mock in the setupFiles option was not found.
// console.warn(require('jest-config').readConfig({}, root))
const jestRootDir = jestConfig.rootDir || root
const rootDirReplacer = path => path.replace('<rootDir>', jestRootDir)
const mappedJestDefaults = {
extensions: jestDefaults.moduleFileExtensions.map(ext => `.${ext}`),
}
// Map the relevant jest config options into webpack config layout
// Ref: https://jestjs.io/docs/en/configuration
const mappedJestConfig = {
modules: [
...(jestConfig.roots || []).map(rootDirReplacer),
...(jestConfig.modulePaths || []).map(rootDirReplacer),
...(jestConfig.moduleDirectories || []),
],
extensions: jestConfig.moduleFileExtensions,
}
// TODO: handle https://jestjs.io/docs/en/configuration#modulenamemapper-objectstring-string
// TODO: handle https://jestjs.io/docs/en/configuration#modulepathignorepatterns-arraystring
// Refs:
// https://webpack.js.org/configuration/resolve/#resolvealias
// Note: resolve.alias takes precedence over other module resolutions.
// https://github.com/tleunen/babel-plugin-module-resolver/blob/master/DOCS.md#alias
const jestAliases = {
alias: {
'test-helpers': path.resolve(jestRootDir, 'spec/javascripts/helpers'),
},
}
// Note: When not defined here the strategy defaults to 'append'
const mergeStrategies = {}
// Ref: https://github.com/survivejs/webpack-merge#merging-with-strategies
const mergedResolverFactoryConfig = webpackMerge.smartStrategy(mergeStrategies)(
webpackConfig.resolve,
mappedJestDefaults,
mappedJestConfig,
jestAliases
)
// Refs:
// https://github.com/webpack/enhanced-resolve
// https://github.com/webpack/enhanced-resolve#creating-a-resolver
// https://github.com/webpack/enhanced-resolve#resolver-options
// https://github.com/webpack/enhanced-resolve/wiki/Plugins
// https://github.com/webpack/enhanced-resolve/blob/master/lib/ResolverFactory.js
// https://github.com/webpack/enhanced-resolve/blob/master/lib/node.js#L76-L91
const createSyncResolver = options => {
const resolver = ResolverFactory.createResolver({
useSyncFileSystemCalls: true,
fileSystem: new CachedInputFileSystem(fs, 4000),
...options,
})
// https://github.com/webpack/enhanced-resolve/blob/master/lib/node.js#L13-L15
const context = {
environments: ['node+es3+es5+process+native'],
}
return (baseDir, thingToResolve) =>
resolver.resolveSync(context, baseDir, thingToResolve)
}
const webpackResolver = createSyncResolver(mergedResolverFactoryConfig)
// Ref: https://jestjs.io/docs/en/configuration#resolver-string
const jestWebpackResolver = (path, options) => {
let webpackResolved
let defaultResolved
try {
webpackResolved = webpackResolver(options.basedir, path)
} catch (_error) {
defaultResolved = options.defaultResolver(path, options)
console.warn(
'[JestWebpackResolver] WARNING: Failed to resolve, falling back to default jest resolver:\n',
{ path, options, webpackResolved, defaultResolved }
)
}
return webpackResolved || defaultResolved
}
module.exports = jestWebpackResolver |
I've configured my alternate search paths as part of this module's
roots
(rather than in jest's config), and I get the following:This appears to be because
jest-resolve
'sResolver.resolveModule
isn't included in the list of defaulttransformFunctions
:Looking at
normalizeTransformedFunctions
I can see that our customtransformFunctions
are appended to the list of defaults:Using a custom jest resolver we can log more info just before this crash happens:
Which shows the following just before it crashes:
This looks as though we should be able to use add
Resolver.resolveModule
to our customtransformFunctions
:Though unfortunately this doesn't seem to work.. presumably because
jest-resolve
is in ournode_modules
, and that isn't getting transpiled by babel, so this plugin never gets a chance to hook it.At this stage I could probably look at hacking something together using a custom
resolvePath
function:But given the project is looking for maintainers (#346).. it might be better for me to find an alternative solution to my needs.
For those that come across this in future, I was originally wanting centralise my webpack resolving/aliasing in babel, so it could 'just work' among webpack, jest, babel, etc.
Some things that attempt to do similar'ish:
The text was updated successfully, but these errors were encountered: