dart-sass icon indicating copy to clipboard operation
dart-sass copied to clipboard

Improve error message when a custom importer returns a Buffer instead of a string

Open Genuifx opened this issue 4 years ago • 4 comments

when using @import to import customer CSS subset file such as @import "a.wxss", the dart-sass compiler always throws the error Error: Can't find stylesheet to import., even I manually read file contents and pass to done Functions.

Version:

reproduce code:

a.scss

@import "./index.skeleton.wxss";

index.skeleton.wxss CSS-subset file.

// some CSS compat rules

process scripts:

import sass from 'sass';
import path from 'path';
import fs from 'fs';
import Fiber from 'fibers';

...some code 

let ret = sass.renderSync({
    ...configs,
    data,
    file: filepath,
    filber: Fiber,
    // includePaths: [filepath],
    importer(url, prev, done) {
        // debugger;
        let file = path.resolve(path.dirname(prev), url);
        let ext = path.extname('url')

        if (ext === '.wxss') {
            done({
                contents: fs.readFileSync(file)
            })
        } 

        return file;
    }
})

Genuifx avatar Nov 08 '21 09:11 Genuifx

Your code says path.extname('url') instead of path.extname(url). url is probably meant to be passed as the variable, not the string.

PapaNappa avatar Nov 11 '21 13:11 PapaNappa

using node-fibers is work. but node-fibers is not compat with node 16.

Update [April 13th, 2021] -- Fibers is not compatible with nodejs v16.0.0 or later. Unfortunately, v8 commit dacc2fee0f is a breaking change and workarounds are non-trivial.

without enabling fiber option. importer seems not work

sass.renderSync({
      ...configs,
      importer(url, prev) {
          let file = path.resolve(path.dirname(prev), url);
          let ext = path.extname(url)

          if (ext === '.wxss') {
              return {
                  contents: fs.readFileSync(file)
              }
          } 
          return {file};
      }
  })

and get Error: Error: NoSuchMethodError: method not found: 'charCodeAt' (receiver.charCodeAt is not a function)

@PapaNappa

Genuifx avatar Dec 13 '21 07:12 Genuifx

It looks like the underlying issue is that the contents expects a string, but fs.readFileSync(file) returns a Buffer. You need to either pass an encoding to readFileSync (e.g. fs.readFileSync(file, 'utf8')) or call toString() on the result.

We could probably improve the error message though.

jathak avatar Dec 15 '21 22:12 jathak

It's work. Thanks @jathak

Genuifx avatar Mar 25 '22 08:03 Genuifx

Having looked deeply at this issue, I think this is just another issue with using an untyped language like javascript, had this been typescript the compiler would have prevented this from happening at all

However that said, I agree that the SassException is misleading so I'll focus on that instead (although I do have a decent solution for the former 😛)

Goodwine avatar Oct 27 '22 02:10 Goodwine