sass / node-sass

:rainbow: Node.js bindings to libsass
https://npmjs.org/package/node-sass
MIT License
8.5k stars 1.33k forks source link

Interface to struct Sass_Compiler* comp #2223

Open spion opened 6 years ago

spion commented 6 years ago

Hi!

url() references in SASS have always been a hot issue, with some people thinking they should be relative to the file they appear, others wanting to preserve the current behaviour.

Bundlers such as WebPack and ParcelJS on the other hand would also benefit from hooks that could rewrite URLs.

One solution would be to define custom functions such as say, relurl, which will get rewritten when transformed to the right url() during compilation

Unfortunately, this is not possible at the moment (or at least I can't see how?). The hook for custom functions only receives the function argument. If we want to access the current file being parsed, we cannot. The variable this which represents the compiler context doesn't have access to the C compiler API (as in, we cannot query for the last import).

It would be nice if the context object contains a JSObject wrapper of the SASS compiler, through which we could call functions such as the libsass C example:

union Sass_Value* call_fn_foo(const union Sass_Value* s_args, Sass_Function_Entry cb, struct Sass_Compiler* comp)
{
  Sass_Import_Entry import = sass_compiler_get_last_import(comp);
  const char* prev_abs_path = sass_import_get_abs_path(import);
}

Then we could pass a functions options such as this:

// ...
functions: {
 relurl(node) {
        let currentDir = path.basename(this.compiler.getLastImportPath());
        let assetAbsPath = path.resolve(currentDir, node.getValue());
        let assetRelativePath = path.relative(path.basename(originalFile), assetAbsPath);

        return new sass.types.String(`url(${assetRelativePath})`);
      }
}
// ...
nschonni commented 6 years ago

Might be a dupe of #895