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

SASS fails to compile files under Jest #1692

Closed
TheLonelyAdventurer opened this issue May 14, 2022 · 11 comments
Closed

SASS fails to compile files under Jest #1692

TheLonelyAdventurer opened this issue May 14, 2022 · 11 comments

Comments

@TheLonelyAdventurer
Copy link

Running sass.compile(path) wil throw a suspicious exception:

TypeError: J.getInterceptor$ax(...).map$1$1 is not a function

      at Object.map$1$1$ax (node_modules/sass/sass.dart.js:24596:44)
      at listDir_closure0.call$0 (node_modules/sass/sass.dart.js:87563:18)
      at Object._systemErrorToFileSystemException0 (node_modules/sass/sass.dart.js:20859:23)
      at Object.listDir0 (node_modules/sass/sass.dart.js:20854:16)
      at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:85221:34)
      at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27356:24)
      at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:85210:32)
      at _realCasePath_helper_closure0.call$0 (node_modules/sass/sass.dart.js:85217:35)
      at JsLinkedHashMap.putIfAbsent$2 (node_modules/sass/sass.dart.js:27356:24)
      at _realCasePath_helper0.call$1 (node_modules/sass/sass.dart.js:85210:32)

The code above was run using jest.

Basic code that reproduces the error:

const sass = require('sass');

const config =
	{ sourceMap: false
	, sourceMapIncludeSources: false
	, style: 'compressed'
	, verbose: true
	, logger: console
	, alertAscii: false
	, alertColor: true
	, functions: {}
	, importers: []
	, loadPaths: []
	, quietDeps: true
	};


function compile() {
	return sass.compile('test.scss');
}

console.log(compile());

The exact same code works when run outside jest.

I've tracked down the compiled js of sass up to this line of sass.dart.js:

immagine

which is called by:

immagine

which is in turn called by:

immagine

As expected these are the results in my debugger for checking the parameters:

immagine

I am not sure what map$1$1 is, but it seems to depend on the running environment as far as I understand the problem.

@akabekobeko
Copy link

akabekobeko commented May 15, 2022

I have the same problem in my environment, if I run sass.compile(path) without Jest it works fine.
There may be a problem with Dart's build or Jest's interpretation.

@jathak
Copy link
Member

jathak commented May 16, 2022

Duplicate of #710.

@jathak jathak closed this as completed May 16, 2022
@akabekobeko
Copy link

@jathak
Specifying testEnvironment: "node" in jest.config.js does not solve the problem.
This value currently defaults to node, but an error will still occur if explicitly specified.

If deprecated, the explanation in #710 is not sufficient. Either #710 or the "recommended method" resolves the error, or should explicitly state in the README or API reference that execution by Jest is not supported.

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
@lfdebrux
Copy link

We also had this issue, and also found that setting the Jest environment to "node" did not help.

However, we found another workaround, Instead, what did work is using the legacy API. 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'

(this bit us a few times 😅 )

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
@jathak
Copy link
Member

jathak commented May 23, 2022

@akabekobeko @lfdebrux Does setting testEnvironment to jest-environment-node-single-context work? That's what we use here.

@akabekobeko
Copy link

@jathak
Thanks!
That way sass.compile(path) is now executable on Jest.

Add npm

$ npm i -D jest-environment-node-single-context

Config

module.exports = {
  testEnvironment: 'jest-environment-node-single-context',
  verbose: true,
  testTimeout: 10000,
  transform: {
    '^.+\\.ts$': 'ts-jest',
  },
};

Test on Jest

transpileCss calls sass.compile(path) internally.

import { transpileCss } from './css';

it('Transpile SCSS', () => {
  const css = transpileCss('sass', './src2/data/scss/app.scss');
  const expected = `body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  background-color: #fbfcfa;
}`;
  expect(css).toBe(expected);
});

Result

 PASS  src2/css.test.ts
  ✓ Transpile SCSS (55 ms)

@TheLonelyAdventurer
Copy link
Author

TheLonelyAdventurer commented May 26, 2022

I tried to use it, but fails with:

TypeError: The "options.context" property must be an vm.Context. Received an instance of Object

Could it be because I'm using Yarn with pnp modules?

Reported in kayahr/jest-environment-node-single-context#10

@akabekobeko
Copy link

akabekobeko commented May 26, 2022

@TheLonelyAdventurer
I am running the tests with npm test, not using Yarn and pnp module. The following PR is an actual successful example.

@TheLonelyAdventurer
Copy link
Author

@akabekobeko yeah it's probably a specific issue with Yarn

@mizdra
Copy link

mizdra commented Aug 27, 2022

I found another workaround. This method also works for testEnvironment: 'node'.

Here is the tricks:

The following PR is an actual successful example.
mizdra/happy-css-modules@a42397b

@TheLonelyAdventurer
Copy link
Author

I tried to use it, but fails with:

TypeError: The "options.context" property must be an vm.Context. Received an instance of Object

Could it be because I'm using Yarn with pnp modules?

Reported in kayahr/jest-environment-node-single-context#10

@TheLonelyAdventurer I am running the tests with npm test, not using Yarn and pnp module. The following PR is an actual successful example.

* [chore: Added test for AltCSS transpile by akabekobeko · Pull Request #17 · vivliostyle/vivliostyle-sitegen](https://github.com/vivliostyle/vivliostyle-sitegen/pull/17)

Update: the package also fails with yarn1 and NPM. I guess there is an issue with node modules.

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

5 participants