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

Unable to resolve files inside Jest #710

Closed
cshawaus opened this issue Jun 1, 2019 · 12 comments
Closed

Unable to resolve files inside Jest #710

cshawaus opened this issue Jun 1, 2019 · 12 comments
Labels
bug JavaScript Issues particular to the Node.js distribution needs info

Comments

@cshawaus
Copy link

cshawaus commented Jun 1, 2019

I'm currently messing around with Sass True and Dart Sass but I'm running into an issue by which the renderSync method in Dart Sass is unable to resolve any paths I give to it. Please see the error below.

source/<removed>/scss/tests/font-face.spec.scss: no such file or directory

      15 |
      16 | sassTestFiles.forEach(file => {
    > 17 |   const rendered = sass.renderSync({ file })
         |                         ^
      18 |
      19 |   console.log(rendered)
      20 | })

I've gone through the implementation several times and I can't see where I'm going wrong as it seems like such a simple example that I expect to work since sass-loader is working as expected with Dart Sass.

Below is the code in question which runs inside Jest but I have also tried inside a vanilla node script and it works just fine so I'm not sure if it is a Jest or Dart Sass issue.

import { resolve } from 'path'
import { sync } from 'glob'
import sass from 'sass'

const sassTestFiles = sync(resolve(process.cwd(), 'source/**/*.spec.scss'))

sassTestFiles.forEach(file => {
  const rendered = sass.renderSync({ file })

  console.log(rendered)
})

Any help would be appreciated.

@nex3
Copy link
Contributor

nex3 commented Jun 2, 2019

If this is only an issue within Jest, I suggest filing an issue there. I'm not familiar with Jest, and without a reproduction that uses the raw Sass API there's not much I can do.

@nex3 nex3 added bug JavaScript Issues particular to the Node.js distribution needs info labels Jun 2, 2019
@cshawaus cshawaus closed this as completed Jun 5, 2019
@justinappler
Copy link

@cshawaus Did you find a solution to this?

@dwightjack
Copy link

@cshawaus @justinappler I tried the same setup and had the same problem.
Since with node-sass everything was working fine I guessed it could be an issue with the default Jest environment. In my case setting "testEnvironment": "node" on the jest config seems to fix the problem.

@johncrim
Copy link

I also encountered the same issue. I documented my findings in true repo, but I'm duplicating it here b/c the root problem is an interaction between jest (when using testEnvironment: 'jsdom') and dart-sass.

As others reported, using testEnvironment: 'node' in my jest.config allowed me to use sass.dart.js normally. I had to create a separate jest.config.js for my sass tests, because my other jest tests are (Angular) front-end tests, and require jsdom.

Note that I only saw this specific issue on Linux - on windows the tests work as expected with jest and dart-sass.

However, I also experienced another, almost surely related problem on Windows - the dart-sass @import / @use file resolution failed to find scss files in the same directory. So I (before discovering the testEnvironment: node workaround) had written my own importer, which fixed up the file resolution. After switching to testEnvironment: node, I was able to remove my importer b/c local file imports worked as expected in dart-sass.

Given all this, it seems safe to conclude that dart-sass file or path resolution doesn't work correctly within jest when using testEnvironment: jsdom.

I can provide a repro if helpful (without using sass-true), but I'm not able to isolate the problem to just sass.dart.js - the repro would include jest and sass.dart.js.

@nex3
Copy link
Contributor

nex3 commented Feb 12, 2020

I also encountered the same issue. I documented my findings in true repo, but I'm duplicating it here b/c the root problem is an interaction between jest (when using testEnvironment: 'jsdom') and dart-sass.

As others reported, using testEnvironment: 'node' in my jest.config allowed me to use sass.dart.js normally. I had to create a separate jest.config.js for my sass tests, because my other jest tests are (Angular) front-end tests, and require jsdom.

Dart Sass uses many Node APIs, so I'm surprised it does anything outside a Node environment.

@apaatsio
Copy link

apaatsio commented Oct 2, 2020

The suggested workaround does not work with Create React App because it's not possible to override the testEnvironment option. There is a github issue (facebook/create-react-app#8880) about this but no one from the CRA team has responded so I'm not gonna hold my breath.

My solution was to switch to node-sass.

@nex3
Copy link
Contributor

nex3 commented Oct 5, 2020

How does Node Sass work without a Node environment?

@apaatsio
Copy link

apaatsio commented Oct 6, 2020

@nex3 Jest does not run tests in a browser. It uses jsdom ("fake DOM") to mimic browser environment. So, it is still running in a Node environment.

I tracked the bug down to this line:

var file = options.file == null ? null : p.absolute(options.file);

path.absolute() returns a URL in Node/jsdom/Jest environment when it should return a file system path. For example, path.absolute("/home/user/project/styles.scss") returns http://localhost/home/user/project/styles.scss when it should return just /home/user/project/styles.scss.

path probably thinks it's running inside a browser because window.location.href is defined by jsdom. (See path FAQ).

Edit: I created a reproduction of the issue at https://github.com/apaatsio/dart-sass-issue-710

git clone git@github.com:apaatsio/dart-sass-issue-710.git
cd dart-sass-issue-710
yarn install
yarn test --watchAll

@nex3
Copy link
Contributor

nex3 commented Oct 6, 2020

@apaatsio Thanks for tracking that down! It looks like it's another example of a longstanding thorn in our side, dart-lang/sdk#27979.

@zaydek
Copy link

zaydek commented Nov 16, 2020

I just ran into this or something related to this myself.

I found in the Jest docs you can use this comment to change the test environment per file. As mentioned previously in this thread, you can also change test environment project-wise.

/**
 * @jest-environment node
 */

From the docs: https://jestjs.io/docs/en/configuration#testenvironment-string.

Apparently jsdom is somehow incompatible with the file system. Anyway, by telling Jest you want node to be the test environment, that fixed things for me.

Example code:

/**
 * @jest-environment node
 */
import sass from "sass";

test("test", () => {
	const result = sass.renderSync({
		file: "src/file.scss",
	});
	expect(result.css.toString()).toBe("...")
})

@PatrickHollweck
Copy link

PatrickHollweck commented Nov 24, 2020

I had the same issue as @zaydek the explaination by @apaatsio is correct.

Can confirm that it is not an issue in dart-sass, but jest.

Just for anyone having the same issue:
If you don't want to change this in every single file you can also put the following into your projects package.json which will enable this setting globally.

"jest": {
  "testEnvironment": "node"
},

@MageJohn
Copy link

If changing the testEnvironment isn't an option for you, this kinda worked for us:

delete window.location;
window.location =  {
  href: __dirname
}

It could then correctly find the file. However, we then ran into issues with importing files, so unless that can be solved this might only work if your file is standalone.

lfdebrux added a commit to alphagov/govuk-prototype-kit that referenced this issue May 17, 2022
There is a bug where `sass.compile` will throw with an extremely
unhelpful error trace when running in Jest [[1]].

>     TypeError: J.getInterceptor$ax(...).map$1$1 is not a function
>
>     at Object.map$1$1$ax (node_modules/sass/sass.dart.js:24513:44)
>     at listDir_closure0.call$0 (node_modules/sass/sass.dart.js:87066:18)
>     at Object._systemErrorToFileSystemException0 (node_modules/sass/sass.dart.js:20776:23)
>     at Object.listDir0 (node_modules/sass/sass.dart.js:20771:16)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84710:34)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84706:35)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)

It has been suggested
that it is related to `path.absolute` being overridden by the jsdom
environment [[2]], but the workaround of using the "node" environment
does not solve the issue for us.

Instead, what did work is using the legacy API [[3]]. I'm not sure why
this is, but it seems to do the trick. Note that with the legacy API,
the file path is part of the options object, rather than being the
first argument. If you forget to change the call signature, you will get
a different unhelpful error message:

> NoSuchMethodError: method not found: 'call'

[1]: sass/dart-sass#1692
[2]: sass/dart-sass#710 (comment)
[3]: https://sass-lang.com/documentation/js-api#legacy-api
BenSurgisonGDS pushed a commit to alphagov/govuk-prototype-kit that referenced this issue May 17, 2022
There is a bug where `sass.compile` will throw with an extremely
unhelpful error trace when running in Jest [[1]].

>     TypeError: J.getInterceptor$ax(...).map$1$1 is not a function
>
>     at Object.map$1$1$ax (node_modules/sass/sass.dart.js:24513:44)
>     at listDir_closure0.call$0 (node_modules/sass/sass.dart.js:87066:18)
>     at Object._systemErrorToFileSystemException0 (node_modules/sass/sass.dart.js:20776:23)
>     at Object.listDir0 (node_modules/sass/sass.dart.js:20771:16)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84710:34)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84706:35)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)

It has been suggested
that it is related to `path.absolute` being overridden by the jsdom
environment [[2]], but the workaround of using the "node" environment
does not solve the issue for us.

Instead, what did work is using the legacy API [[3]]. I'm not sure why
this is, but it seems to do the trick. Note that with the legacy API,
the file path is part of the options object, rather than being the
first argument. If you forget to change the call signature, you will get
a different unhelpful error message:

> NoSuchMethodError: method not found: 'call'

[1]: sass/dart-sass#1692
[2]: sass/dart-sass#710 (comment)
[3]: https://sass-lang.com/documentation/js-api#legacy-api
BenSurgisonGDS pushed a commit to alphagov/govuk-prototype-kit that referenced this issue May 17, 2022
There is a bug where `sass.compile` will throw with an extremely
unhelpful error trace when running in Jest [[1]].

>     TypeError: J.getInterceptor$ax(...).map$1$1 is not a function
>
>     at Object.map$1$1$ax (node_modules/sass/sass.dart.js:24513:44)
>     at listDir_closure0.call$0 (node_modules/sass/sass.dart.js:87066:18)
>     at Object._systemErrorToFileSystemException0 (node_modules/sass/sass.dart.js:20776:23)
>     at Object.listDir0 (node_modules/sass/sass.dart.js:20771:16)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84710:34)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84706:35)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)

It has been suggested
that it is related to `path.absolute` being overridden by the jsdom
environment [[2]], but the workaround of using the "node" environment
does not solve the issue for us.

Instead, what did work is using the legacy API [[3]]. I'm not sure why
this is, but it seems to do the trick. Note that with the legacy API,
the file path is part of the options object, rather than being the
first argument. If you forget to change the call signature, you will get
a different unhelpful error message:

> NoSuchMethodError: method not found: 'call'

[1]: sass/dart-sass#1692
[2]: sass/dart-sass#710 (comment)
[3]: https://sass-lang.com/documentation/js-api#legacy-api
BenSurgisonGDS pushed a commit to alphagov/govuk-prototype-kit that referenced this issue May 17, 2022
There is a bug where `sass.compile` will throw with an extremely
unhelpful error trace when running in Jest [[1]].

>     TypeError: J.getInterceptor$ax(...).map$1$1 is not a function
>
>     at Object.map$1$1$ax (node_modules/sass/sass.dart.js:24513:44)
>     at listDir_closure0.call$0 (node_modules/sass/sass.dart.js:87066:18)
>     at Object._systemErrorToFileSystemException0 (node_modules/sass/sass.dart.js:20776:23)
>     at Object.listDir0 (node_modules/sass/sass.dart.js:20771:16)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84710:34)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84706:35)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)

It has been suggested
that it is related to `path.absolute` being overridden by the jsdom
environment [[2]], but the workaround of using the "node" environment
does not solve the issue for us.

Instead, what did work is using the legacy API [[3]]. I'm not sure why
this is, but it seems to do the trick. Note that with the legacy API,
the file path is part of the options object, rather than being the
first argument. If you forget to change the call signature, you will get
a different unhelpful error message:

> NoSuchMethodError: method not found: 'call'

[1]: sass/dart-sass#1692
[2]: sass/dart-sass#710 (comment)
[3]: https://sass-lang.com/documentation/js-api#legacy-api
lfdebrux added a commit to alphagov/govuk-prototype-kit that referenced this issue May 18, 2022
There is a bug where `sass.compile` will throw with an extremely
unhelpful error trace when running in Jest [[1]].

>     TypeError: J.getInterceptor$ax(...).map$1$1 is not a function
>
>     at Object.map$1$1$ax (node_modules/sass/sass.dart.js:24513:44)
>     at listDir_closure0.call$0 (node_modules/sass/sass.dart.js:87066:18)
>     at Object._systemErrorToFileSystemException0 (node_modules/sass/sass.dart.js:20776:23)
>     at Object.listDir0 (node_modules/sass/sass.dart.js:20771:16)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84710:34)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84706:35)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)

It has been suggested
that it is related to `path.absolute` being overridden by the jsdom
environment [[2]], but the workaround of using the "node" environment
does not solve the issue for us.

Instead, what did work is using the legacy API [[3]]. I'm not sure why
this is, but it seems to do the trick. Note that with the legacy API,
the file path is part of the options object, rather than being the
first argument. If you forget to change the call signature, you will get
a different unhelpful error message:

> NoSuchMethodError: method not found: 'call'

[1]: sass/dart-sass#1692
[2]: sass/dart-sass#710 (comment)
[3]: https://sass-lang.com/documentation/js-api#legacy-api
lfdebrux added a commit to alphagov/govuk-prototype-kit that referenced this issue May 19, 2022
There is a bug where `sass.compile` will throw with an extremely
unhelpful error trace when running in Jest [[1]].

>     TypeError: J.getInterceptor$ax(...).map$1$1 is not a function
>
>     at Object.map$1$1$ax (node_modules/sass/sass.dart.js:24513:44)
>     at listDir_closure0.call$0 (node_modules/sass/sass.dart.js:87066:18)
>     at Object._systemErrorToFileSystemException0 (node_modules/sass/sass.dart.js:20776:23)
>     at Object.listDir0 (node_modules/sass/sass.dart.js:20771:16)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84710:34)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84706:35)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)

It has been suggested
that it is related to `path.absolute` being overridden by the jsdom
environment [[2]], but the workaround of using the "node" environment
does not solve the issue for us.

Instead, what did work is using the legacy API [[3]]. I'm not sure why
this is, but it seems to do the trick. Note that with the legacy API,
the file path is part of the options object, rather than being the
first argument. If you forget to change the call signature, you will get
a different unhelpful error message:

> NoSuchMethodError: method not found: 'call'

[1]: sass/dart-sass#1692
[2]: sass/dart-sass#710 (comment)
[3]: https://sass-lang.com/documentation/js-api#legacy-api
lfdebrux added a commit to alphagov/govuk-prototype-kit that referenced this issue May 19, 2022
There is a bug where `sass.compile` will throw with an extremely
unhelpful error trace when running in Jest [[1]].

>     TypeError: J.getInterceptor$ax(...).map$1$1 is not a function
>
>     at Object.map$1$1$ax (node_modules/sass/sass.dart.js:24513:44)
>     at listDir_closure0.call$0 (node_modules/sass/sass.dart.js:87066:18)
>     at Object._systemErrorToFileSystemException0 (node_modules/sass/sass.dart.js:20776:23)
>     at Object.listDir0 (node_modules/sass/sass.dart.js:20771:16)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84710:34)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84706:35)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)

It has been suggested
that it is related to `path.absolute` being overridden by the jsdom
environment [[2]], but the workaround of using the "node" environment
does not solve the issue for us.

Instead, what did work is using the legacy API [[3]]. I'm not sure why
this is, but it seems to do the trick. Note that with the legacy API,
the file path is part of the options object, rather than being the
first argument. If you forget to change the call signature, you will get
a different unhelpful error message:

> NoSuchMethodError: method not found: 'call'

[1]: sass/dart-sass#1692
[2]: sass/dart-sass#710 (comment)
[3]: https://sass-lang.com/documentation/js-api#legacy-api
lfdebrux added a commit to alphagov/govuk-prototype-kit that referenced this issue May 19, 2022
There is a bug where `sass.compile` will throw with an extremely
unhelpful error trace when running in Jest [[1]].

>     TypeError: J.getInterceptor$ax(...).map$1$1 is not a function
>
>     at Object.map$1$1$ax (node_modules/sass/sass.dart.js:24513:44)
>     at listDir_closure0.call$0 (node_modules/sass/sass.dart.js:87066:18)
>     at Object._systemErrorToFileSystemException0 (node_modules/sass/sass.dart.js:20776:23)
>     at Object.listDir0 (node_modules/sass/sass.dart.js:20771:16)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84710:34)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84706:35)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)

It has been suggested
that it is related to `path.absolute` being overridden by the jsdom
environment [[2]], but the workaround of using the "node" environment
does not solve the issue for us.

Instead, what did work is using the legacy API [[3]]. I'm not sure why
this is, but it seems to do the trick. Note that with the legacy API,
the file path is part of the options object, rather than being the
first argument. If you forget to change the call signature, you will get
a different unhelpful error message:

> NoSuchMethodError: method not found: 'call'

[1]: sass/dart-sass#1692
[2]: sass/dart-sass#710 (comment)
[3]: https://sass-lang.com/documentation/js-api#legacy-api
BenSurgisonGDS pushed a commit to alphagov/govuk-prototype-kit that referenced this issue May 20, 2022
There is a bug where `sass.compile` will throw with an extremely
unhelpful error trace when running in Jest [[1]].

>     TypeError: J.getInterceptor$ax(...).map$1$1 is not a function
>
>     at Object.map$1$1$ax (node_modules/sass/sass.dart.js:24513:44)
>     at listDir_closure0.call$0 (node_modules/sass/sass.dart.js:87066:18)
>     at Object._systemErrorToFileSystemException0 (node_modules/sass/sass.dart.js:20776:23)
>     at Object.listDir0 (node_modules/sass/sass.dart.js:20771:16)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84710:34)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)
>     at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:84706:35)
>     at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27273:24)
>     at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:84699:32)

It has been suggested
that it is related to `path.absolute` being overridden by the jsdom
environment [[2]], but the workaround of using the "node" environment
does not solve the issue for us.

Instead, what did work is using the legacy API [[3]]. I'm not sure why
this is, but it seems to do the trick. Note that with the legacy API,
the file path is part of the options object, rather than being the
first argument. If you forget to change the call signature, you will get
a different unhelpful error message:

> NoSuchMethodError: method not found: 'call'

[1]: sass/dart-sass#1692
[2]: sass/dart-sass#710 (comment)
[3]: https://sass-lang.com/documentation/js-api#legacy-api
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug JavaScript Issues particular to the Node.js distribution needs info
Projects
None yet
Development

No branches or pull requests

9 participants