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

Custom importer sass.NULL usage #1291

Closed
kenjiqq opened this issue Dec 3, 2015 · 20 comments
Closed

Custom importer sass.NULL usage #1291

kenjiqq opened this issue Dec 3, 2015 · 20 comments

Comments

@kenjiqq
Copy link

kenjiqq commented Dec 3, 2015

The documentions for custom importers state that
If an importer does not want to handle a particular path, it should return sass.NULL

But if you implement the importer in a package, that will be used as a dependency, this package will have a dependency on node-sass and have node-sass package in it's node_modules.

So when this importer is run from another package, like grunt-sass that has its own dependency on node-sass, the node-sass module used in grunt-sass and in the importer will not be the same object and the object reference equality check in node-sass will fail.

var result = importer.call(options.context, file, prev, done);
//result will be a sass.NULL from another node-sass object and the === fails
if (result) {
    done(result === module.exports.NULL ? null : result);
}

This cause node-sass to think all imports are handled by this importer no matter what.

@kenjiqq
Copy link
Author

kenjiqq commented Dec 3, 2015

This is assuming the importer implementation does a require('node-sass') to get a node-sass reference. How else would it be able to access sass.NULL

@xzyfer
Copy link
Contributor

xzyfer commented Dec 3, 2015

Good questions. Maybe @am11 or @saper would have thoughts here.

@kenjiqq
Copy link
Author

kenjiqq commented Dec 3, 2015

In some situation using peerDependencies will solve it, but probably not everywhere

@saper
Copy link
Member

saper commented Dec 3, 2015

Would that help if we would just return undefined? I actually think we should drop sass.NULL and use that native node type, just haven't got around to implementing it yet.

@xzyfer
Copy link
Contributor

xzyfer commented Dec 10, 2015

@chriseppstein I'd like to hear your thoughts on this since I expect any decision here will impact eyeglass.

@am11
Copy link
Contributor

am11 commented Dec 10, 2015

@kenborge, you have made a very good point and thanks for spotting and reporting this issue.
This issue is in node-sass code itself, which can be hot fixed as:

- done(result === module.exports.NULL ? null : result);
+ done(result.toString() === module.exports.NULL.toString() ? null : result);
// both will return `[object SassNull]` which is different than `[object Object]`

or

- done(result === module.exports.NULL ? null : result);
+ done(result.constructor.toString() === module.exports.NULL.constructor.toString() ? null : result);

The idea was to not advertise these export too much and still able to provide control for explicitly returning SassNull type.

@saper
Copy link
Member

saper commented Dec 20, 2015

@kenborge can you check if my preliminary fix #1308 makes it better? Are you returning your imports vi done( ... ) or by return? If via done(...) then this could be a duplicate of #1296.

@saper
Copy link
Member

saper commented Dec 20, 2015

Actually asking for sass.NULL is a mistake. With #1308 returning JavaScript null should work as well.

@am11
Copy link
Contributor

am11 commented Dec 20, 2015

In JavaScript return null;, return; and returning nothing are interchangeable, which is not applicable here as we need to differentiate between done and return. Explicitly returning sass.NULL is by design.

@saper
Copy link
Member

saper commented Dec 20, 2015

@am11 What about undefined? Unspecified parameter / return value is undefined:

> console.log( ( function() { return; } )() );
undefined
undefined
> console.log( ( function() { return null; } )() );
null

This is what this patch is checking against.

@am11
Copy link
Contributor

am11 commented Dec 20, 2015

@saper, either test the type sass.NULL or drop sass.NULL completely and use return null everywhere (i.e. breaking change). The reason why it wasn't done that (return null and test based on undefined) way in first place is to avoid the confusion and keep the type-systems separate.

@saper
Copy link
Member

saper commented Dec 21, 2015

My patch uses null everywhere and aliases sass.NULL and sass.sass_types.Null.NULL to null for compatibility.

@xzyfer
Copy link
Contributor

xzyfer commented Dec 27, 2015

A couple things.

if you implement the importer in a package, that will be used as a dependency, this package will have a dependency on node-sass

This is essentially forcing a peer dependency, which I agree is bad.

Actually asking for sass.NULL is a mistake.
Explicitly returning sass.NULL is by design.

I agree that with returning sass.NULL.

In JavaScript return null;, return; and returning nothing are interchangeable

Technically not true.

> function foo() { return null; }
undefined
> function bar() { return; }
undefined
> foo()
null
> bar()
undefined

What about undefined?

We could strictly check against undefined to get around the issue @am11 mentions with return null. @saper's patch does this.

Although technically null is not undefined as @am11 points out they are used interchangeably in the JS community. So much so a lot of developers don't know the conceptual difference. This means we're practically asking for false bug reports due to this misunderstanding.


My preference would be move sass-types into it's own repo as discussed in #1088 (comment)

This solves the peerDependency problem, preserves the semantics of returning sass.NULL from importers/functions, and resolves abilities with returning null vs undefined.

@xzyfer
Copy link
Contributor

xzyfer commented Dec 27, 2015

It's also worth noting that we currently do not distinguish between custom importers returning false, null, undefined, or sass.NULL.

The exception being #1308 where we don't correctly handle return sass.NULL with async importers.

@xzyfer
Copy link
Contributor

xzyfer commented Dec 27, 2015

I've added test coverage for the existing importer noop return semantics in #1319. This will prevent us from unintentionally introducing BC breaks.

@xzyfer
Copy link
Contributor

xzyfer commented Dec 27, 2015

TLDR;

@kenborge you can currently return null or undefined to get the same behaviour as sass.NULL in custom importers.

@am11 @saper I've opened #1320 to discussion creating a sass-types package.

@xzyfer xzyfer closed this as completed Dec 27, 2015
@saper
Copy link
Member

saper commented Dec 27, 2015

There are several problems with explicitly using undefined (it can be redefined for example), but we use it only because we want to be nice to those returning via return value instead of done(value) - we intercept that return value for them. It is not a proper solution, but kind of works and checking for undefined fits that ugly pattern.

@saper
Copy link
Member

saper commented Dec 27, 2015

Maybe we would better off by moving this code into the C++ binding. We should know better in C++ if the value was returned and how.

@pmowrer
Copy link

pmowrer commented Feb 24, 2016

@xzyfer Returning null or undefined in place of sass.NULL does not appear to work (3.4.2). The importer will just hang indefinitely after processing a few files whereas it completes using sass.NULL.

@xzyfer
Copy link
Contributor

xzyfer commented Feb 24, 2016

@pmowrer I believe this has been patched in the current beta. Try npm install node-sass@beta.

xzyfer added a commit to xzyfer/node-sass that referenced this issue Mar 23, 2016
With sass#1291 custom importers can now return `null` instead of
`sass.NULL`. This means custom importer modules no longer need to
have node-sass as a dependency.
xzyfer added a commit to xzyfer/node-sass that referenced this issue Mar 23, 2016
With sass#1291 custom importers can now return `null` instead of
`sass.NULL`. This means custom importer modules no longer need to
have node-sass as a dependency.
pmowrer added a commit to pmowrer/node-sass-json-importer that referenced this issue May 17, 2016
Returning `sass.NULL` when not handling an import was causing issues
when multiple installs of `node-sass` were present as they would have
independent instances of `sass.NULL`.

See discussion here: sass/node-sass#1291

It appears using `null` instead of `sass.NULL` works as of `node-sass`
3.5.x.
Friendly-users referenced this issue in Friendly-users/node-sass Jul 9, 2024
-----
It is inappropriate to include political and offensive content in public code repositories.

Public code repositories should be neutral spaces for collaboration and community, free from personal or political views that could alienate or discriminate against others. Political content, especially that which targets or disparages minority groups, can be harmful and divisive. It can make people feel unwelcome and unsafe, and it can create a hostile work environment.

Please refrain from adding such content to public code repositories.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants