Skip to content
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

Ignore paths in node_modules #239

Open
Xesenix opened this issue Jun 24, 2018 · 7 comments
Open

Ignore paths in node_modules #239

Xesenix opened this issue Jun 24, 2018 · 7 comments

Comments

@Xesenix
Copy link

Xesenix commented Jun 24, 2018

Im trying to test if webpack builds with provided configuration but test fail on some libraries lazy requiring json configuration like for example:

Cannot find module './refs/json-schema-draft-06.json' from 'ajv.js'

Either give a way to disable mocking require or disable mocking paths by some reqexp.

@Xesenix
Copy link
Author

Xesenix commented Jun 24, 2018

Also, it may be that case that some coverage reports are broken because I see mock receives requests for map files and returns null for them...

Also if i was patien enought something like this solves problem but takes ages to create:

mockFs({
  'package.json': '{ "name": "test-app-00" }',
  'node_modules/ajv/lib/refs/json-schema-draft-06.json': fs.readFileSync('node_modules/ajv/lib/refs/json-schema-draft-06.json'),
  'node_modules/extract-text-webpack-plugin/schema/plugin.json': fs.readFileSync('node_modules/extract-text-webpack-plugin/schema/plugin.json'),
  'node_modules/extract-text-webpack-plugin/schema/loader.json': fs.readFileSync('node_modules/extract-text-webpack-plugin/schema/loader.json'),
  'node_modules/extract-text-webpack-plugin/dist/loader.js': fs.readFileSync('node_modules/extract-text-webpack-plugin/dist/loader.js'),
  'node_modules/babel-plugin-transform-decorators-legacy': fs.readFileSync('node_modules/babel-plugin-transform-decorators-legacy/lib/index.js'),
  'node_modules/babel-template': fs.readFileSync('node_modules/babel-template/lib/index.js'),
  'node_modules/babel-runtime/core-js/symbol': fs.readFileSync('node_modules/babel-runtime/core-js/symbol.js'),
  'node_modules/core-js/library/fn/symbol': fs.readFileSync('node_modules/core-js/library/fn/symbol/index.js'),
  'node_modules/core-js/modules/es6.symbol': fs.readFileSync('node_modules/core-js/modules/es6.symbol.js'),
  'node_modules/core-js/modules/_global': fs.readFileSync('node_modules/core-js/modules/_global.js'),
  'node_modules/core-js/modules/_has': fs.readFileSync('node_modules/core-js/modules/_has.js'),
  'node_modules/core-js/modules/_descriptors': fs.readFileSync('node_modules/core-js/modules/_descriptors.js'),
  'node_modules/core-js/modules/_export': fs.readFileSync('node_modules/core-js/modules/_export.js'),
  'node_modules/core-js/modules/_redefine': fs.readFileSync('node_modules/core-js/modules/_redefine.js'),
  'node_modules/core-js/modules/_meta': fs.readFileSync('node_modules/core-js/modules/_meta.js'),
  'node_modules/core-js/modules/_fails': fs.readFileSync('node_modules/core-js/modules/_fails.js'),
  'node_modules/core-js/modules/_shared': fs.readFileSync('node_modules/core-js/modules/_shared.js'),
  'node_modules/core-js/modules/_set-to-string-tag': fs.readFileSync('node_modules/core-js/modules/_set-to-string-tag.js'),
  'node_modules/core-js/modules/_uid': fs.readFileSync('node_modules/core-js/modules/_uid.js'),
  'node_modules/core-js/modules/_wks': fs.readFileSync('node_modules/core-js/modules/_wks.js'),
  'node_modules/core-js/modules/_wks-ext': fs.readFileSync('node_modules/core-js/modules/_wks-ext.js'),
  'node_modules/core-js/modules/_wks-define': fs.readFileSync('node_modules/core-js/modules/_wks-define.js'),
  'node_modules/core-js/modules/_enum-keys': fs.readFileSync('node_modules/core-js/modules/_enum-keys.js'),
  'node_modules/core-js/modules/_is-array': fs.readFileSync('node_modules/core-js/modules/_is-array.js'),
  'node_modules/core-js/modules/_an-object': fs.readFileSync('node_modules/core-js/modules/_an-object.js'),
  'node_modules/core-js/modules/_is-object': fs.readFileSync('node_modules/core-js/modules/_is-object.js'),
  'node_modules/core-js/modules/_to-iobject': fs.readFileSync('node_modules/core-js/modules/_to-iobject.js'),
  'node_modules/core-js/modules/_to-primitive': fs.readFileSync('node_modules/core-js/modules/_to-primitive.js'),
  'node_modules/core-js/modules/_property-desc': fs.readFileSync('node_modules/core-js/modules/_property-desc.js'),
  'node_modules/core-js/modules/_object-create': fs.readFileSync('node_modules/core-js/modules/_object-create.js'),
  'node_modules/core-js/modules/_object-gopn-ext': fs.readFileSync('node_modules/core-js/modules/_object-gopn-ext.js'),
  'node_modules/core-js/modules/_object-gopd': fs.readFileSync('node_modules/core-js/modules/_object-gopd.js'),
  'node_modules/core-js/modules/_object-dp': fs.readFileSync('node_modules/core-js/modules/_object-dp.js'),
  'node_modules/core-js/modules/_object-keys': fs.readFileSync('node_modules/core-js/modules/_object-keys.js'),
// got bored at this point
});

@JeffSpies
Copy link

Just ran into the exact same error; ajv requires a json file in a function call, leading to this issue.

Any mock-fs friendly way to deal with this other than the very manual method suggested by the OP? :)

Thanks!

@myoffe
Copy link

myoffe commented Dec 2, 2018

Got the exact same issue as OP.

@dominictobias
Copy link

Same issue I think, function I'm testing calls @babel/traverse and results in:

Error: ENOENT, no such file or directory '/Users/infensus/Sites/yebu/yebu-cli/node_modules/lodash/clone.js'
      at Binding.<anonymous> (node_modules/mock-fs/lib/binding.js:1166:13)
      at maybeCallback (node_modules/mock-fs/lib/binding.js:61:17)
      at Binding.lstat (node_modules/mock-fs/lib/binding.js:1163:10)
      at Object.realpathSync (fs.js:1478:29)
      at toRealPath (internal/modules/cjs/loader.js:205:13)
      at tryFile (internal/modules/cjs/loader.js:201:22)
      at tryExtensions (internal/modules/cjs/loader.js:213:22)
      at Function.Module._findPath (internal/modules/cjs/loader.js:295:20)
      at Function.Module._resolveFilename (internal/modules/cjs/loader.js:600:25)
      at Function.Module._load (internal/modules/cjs/loader.js:529:25)
      at Module.require (internal/modules/cjs/loader.js:659:17)
      at require (internal/modules/cjs/helpers.js:22:18)
      at _clone (node_modules/@babel/traverse/lib/visitors.js:23:39)
      at Object.explode (node_modules/@babel/traverse/lib/visitors.js:102:30)
      at traverse (node_modules/@babel/traverse/lib/index.js:75:12)
      at NodePath.traverse (node_modules/@babel/traverse/lib/path/index.js:161:24)
      at Scope.crawl (node_modules/@babel/traverse/lib/scope/index.js:684:10)
      at Scope.init (node_modules/@babel/traverse/lib/scope/index.js:634:32)
      at NodePath.setScope (node_modules/@babel/traverse/lib/path/context.js:126:30)
      at NodePath.setContext (node_modules/@babel/traverse/lib/path/context.js:141:8)
      at NodePath.pushContext (node_modules/@babel/traverse/lib/path/context.js:207:8)
      at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:106:14)
      at TraversalContext.visitSingle (node_modules/@babel/traverse/lib/context.js:90:19)
      at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:146:19)
      at Function.traverse.node (node_modules/@babel/traverse/lib/index.js:94:17)
      at traverse (node_modules/@babel/traverse/lib/index.js:76:12)
      at Promise (src/util/parser/annotate-js.js:71:5)
      at new Promise (<anonymous>)
      at annotate (src/util/parser/annotate-js.js:52:10)
      at process.internalTickCallback (internal/process/next_tick.js:77:7)

@mishelen
Copy link

mishelen commented Jul 7, 2020

Same issue with dynamic require and ajv
Kind of this doesn't help:

mock({
 'node_modules/ajv/lib/refs/json-schema-draft-06.json': 
   fs.readFileSync('node_modules/ajv/lib/refs/json-schema-draft-06.json'),
})

@mishelen
Copy link

mishelen commented Jul 8, 2020

^^ Solved with #213 (comment)

@cshawaus
Copy link

cshawaus commented Oct 7, 2020

Hi all,

Not sure if people are still trying to find a nice way of managing this or not but I came up with a cleaner solution compared to #213 (comment).

My solution enforces lazy loading and skips non-essential directories using only mock-fs which brought my wait times for a single suite down from ~27 seconds on average to ~10 seconds which is still a little bit of time to wait but I haven't found another file system mocking solution that does the job better and has as good of an API as what mock-fs does.

import fs from 'fs'
import path from 'path'
import mockFS from 'mock-fs'

import type FileSystem from 'mock-fs/lib/filesystem'

function lazyLoadNodeModules(mockedFileSystem: FileSystem.DirectoryItems, from: string, depth = 6): void {
  const stat = fs.lstatSync(from)

  if (stat.isDirectory() && depth > 0) {
    for (const item of fs.readdirSync(from)) {
      if (item.startsWith('.') || item === '@types') {
        continue
      }

      lazyLoadNodeModules(mockedFileSystem, path.join(from, item), depth - 1)
    }
  } else if (stat.isFile()) {
    mockedFileSystem[from] = mockFS.load(from, { lazy: true })
  }
}

export default lazyLoadNodeModules

To use it, import the above code as a separate file in your test code and then run it with:

import mockFS from 'mock-fs'

beforeAll(() => {
  const mockedFileSystem = {}

  lazyLoadNodeModules(mockedFileSystem, path.resolve(path.join(process.cwd(), 'node_modules')))

  mockFS(mockedFileSystem)
})

afterAll(() => {
  mockFS.restore()
})

By default this will:

  1. Skip all dotfiles
  2. Skip @types directories

I recommend only mocking what you need for smaller projects, but mocking everything – if like me – you're doing webpack testing.

Hope this helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants