Skip to content
This repository has been archived by the owner on Jul 24, 2024. It is now read-only.

Unable to get it working on Windows #793

Closed
PhiLhoSoft opened this issue Mar 24, 2015 · 15 comments
Closed

Unable to get it working on Windows #793

PhiLhoSoft opened this issue Mar 24, 2015 · 15 comments

Comments

@PhiLhoSoft
Copy link

Either it is a true bug report against the library, or it is one against the documentation (the top readme)...

> node -v
v0.12.0
> npm -v
2.7.3
> node C:\Dev\Web\Playground\node_modules\node-sass\bin\node-sass -v
node-sass       3.0.0-alpha.0   (Wrapper)       [JavaScript]
libsass         3.1.0           (Sass Compiler) [C/C++]

As you can see, I develop on Windows 7...
I am making a simple "skeleton" web application at https://github.com/PhiLhoSoft/Web-Playground
The idea is to experiment with a development stack, including Sass, of course.
I chose to skip Gulp / Grunt in favor of pure npm task running, so I have to learn the command line versions of the tools.

After reading the docs, I tried to generate a CSS file from my Sass one with the following script:

"css": "node node-sass-run.js"

where the JS ile is as follows:

var sass = require("node-sass");

sass.render(
{
    file: "src/main/sass/playground.scss",
    includePaths: [ "src/main/sass" ],
    outFile: "src/main/css",
    outputStyle: "nested",
    sourceComments: true,
    sourceMap: true,
    importer: function(url)
    {
        return { file: url };
    }
},
function(error, result)  // >= v3.0.0
{
    if (error)
    {
        console.log(error);
    }
    else
    {
        console.log("Result path: " + result.path);
        console.log(result.stats);
//~         console.log(result.css.toString());
//~         console.log(result.map.toString()); // or console.log(JSON.stringify(result.map));
    }
});

When I run it, it displays no errors:

> node node-sass-run.js

{ file: 'philhosoft-base' }
Result path: undefined
{ entry: 'C:\\PersonnelPhilippeLhoste\\PhiLhoSoft\\Web\\Playground\\src\\main\\sass\\playground.scss',
  start: 1427190066028,
  includedFiles:
   [ 'C:/PersonnelPhilippeLhoste/PhiLhoSoft/Web/Playground/src/main/sass/_philhosoft-base.scss',
     'C:/PersonnelPhilippeLhoste/PhiLhoSoft/Web/Playground/src/main/sass/playground.scss' ],
  end: 1427190066050,
  duration: 22 }

Cool. Except I find no CSS file in the src/main/css folder. I thought the outFile parameter was used as destination... I also tried with an absolute path.
That's where it is either a bug against the non-functioning outFile, or against the doc failing to indicate what this parameter is for... 😄

Ah, I see mentioned in the docs that maybe we should output the result.css and result.map to a file. If that's the way to go, I suggest to be a bit more explicit for people like me knowing nothing about Node.js scripting, and showing how it can be done.

After that, I tried another approach, with the following script:

"build:styles": "node-sass --source-comments --source-map --output-style nested --include-path src/main/sass --output src/main/css src/main/sass/playground.scss",

but I get an error:

> npm run build:styles

> [email protected] build:styles C:\Dev\Web\Playground
> node-sass --source-comments --source-map --output-style nested --include-path src/main/sass --output src/main/css src/main/sass/playground.scss

path.js:111
      throw new TypeError('Arguments to path.resolve must be strings');
            ^
TypeError: Arguments to path.resolve must be strings
    at Object.win32.resolve (path.js:111:13)
    at run (C:\Dev\Web\Playground\node_modules\node-sass\bin\node-sass:208:32)
    at Object.<anonymous> (C:\Dev\Web\Playground\node_modules\node-sass\bin\node-sass:253:3)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3

Argh.
I get the same error if instead of node-sass I put node node_modules/node-sass/bin/node-sass.
If I do the script:

"nsv": "node node_modules/node-sass/bin/node-sass -v"

it works without problems. So the issue seems to be with the paths I give in the parameters.
If I put single quotes around the paths, I get the same error. If I put double quotes, node-sass complains: "Provide a Sass file to render".

I report the issue as I am starting to run out of ideas / workaround attempts... 😸
Thanks.

@PhiLhoSoft PhiLhoSoft changed the title Unable to get it working Unable to get it working on Windows Mar 24, 2015
@am11
Copy link
Contributor

am11 commented Mar 24, 2015

Hello,

As indicated in docs: https://github.com/sass/node-sass/#outfile, outFile option is for source-maps to emit correct file member.

Node-Sass v2 brought this breaking change, where we don't write anything to filesystem, but let the API implementer do whatever they want with data. Why? because writing to filesystem is not the only use case. You may want to output the result to stream, store in db or do something else with it. In those cases, writing to file is an overhead and node-sass is supposed to act like an API.

However, we do write to file with CLI usage.

v3 example (API):

require('node-sass').render({
  data: '.selector { property: value }',
  outFile: 'my/css/file/path/name.css',
  sourceMap: true
}, function (err, result) {
  if (err) {
    throw err;  // since err is instanceof Error
    // or you can do something else with err and then return within if-block
    // either way no need for else{}
  }

  console.log(result.css.toString());
  // or you may want to
  fs.writeFileSync(this.options.outFile, result.css, 'utf8');
  // also note that result.css and result.map are of type Buffer,
  // so you may need to use toString, see more details under example in README
  // some functions like fs.writeFile*() and JSON.stringify(), accept buffers as is,
  // so you do not need to cast it explicitly for those.
});

@PhiLhoSoft
Copy link
Author

Thanks for the quick answer.

So I guessed right about the need to write the result to a file ourselves. As said, giving a working example of such output for strangers to the Node.js ecosystem / API would be nice, to get your users quickly up and running.

And the point about not being able to run the command line version on Windows remains.

@PhiLhoSoft
Copy link
Author

Ah, I finally went into bin/node-sass source, looking at line 208 (per the error message) and I see it is related to the source-map option. If I remove it from the command line, I get a CSS as expected! Problem half resolved (how do I get a source map, now?).

@PhiLhoSoft
Copy link
Author

OK, reading more of the source, I see that apparently the --source-map option expects a parameter (not obvious from the readme) which apparently can be a path, or "true".
So my final script is: "build:styles": "node-sass --source-comments --source-map=true --output-style nested --include-path src/main/sass --output src/main/css src/main/sass/playground.scss" and it outputs both a CSS and a source map!
Joy.

I don't close the issue as I feel it might be solved by adding some information to the documentation.

@am11
Copy link
Contributor

am11 commented Mar 24, 2015

Aside:
As an outsider/stranger to node.js ecosystem and getting familiar to it by minute, would you like composing an example, which you think will fit for new comers to node.js mini-world? I am kind of spoiled by javascript so I don't know how to zoom out and relive that beginner's moment. (-8

@am11
Copy link
Contributor

am11 commented Mar 24, 2015

--output src/main/css src/main/sass/playground.scss, note that this part is not correct:

-o, --output               Output directory',

At least this bit should be clear from the CLI usage help..

@am11
Copy link
Contributor

am11 commented Mar 24, 2015

I don't close the issue as I feel it might be solved by adding some information to the documentation.

Feel free to send the pull request.

@am11 am11 added this to the Unknown milestone Mar 24, 2015
@PhiLhoSoft
Copy link
Author

"note that this part is not correct:"
According to the doc:
node-sass [options] <input.scss> [<output.css>]
So --output src/main/css is part of the options, and src/main/sass/playground.scss is the <input.scss> part, no?
I have to give the path to the .scss file, as apparently it isn't taken from the include-path (which is understandable).

@PhiLhoSoft
Copy link
Author

"Feel free to send the pull request."
Of course, I thought about it, but I am not sure I fully understood everything, enough to be able to provide a valuable edit.

"would you like composing an example"
My pleasure. It is half done above, but missing the writing part.
I see fs.writeSync(result.css.toString()) in your comment above, which is helpful, but I don't know how to create a fs object, alas. I suppose I have to import something, create the object by giving it a path, but I lack some details.
In my first steps I searched a working example on GitHub and elsewhere, but failed to find one.

@am11
Copy link
Contributor

am11 commented Mar 24, 2015

output option is for directory. For output path, you need to pass it without any flag:

:: this is cmd

C:\temp>notepad foo.scss

C:\temp>type foo.scss
test {

  one: 1;

  two: 2;
  three: 3;
}

C:\temp>npm install node-sass@alpha
:: boring output

C:\temp>node_modules\.bin\node-sass --version
3.0.0-alpha.0

C:\temp>node_modules\.bin\node-sass foo.scss blah.css
Rendering Complete, saving .css file...
Wrote CSS to C:\temp\blah.css

C:\temp>type blah.css
test {
  one: 1;
  two: 2;
  three: 3; }

@am11
Copy link
Contributor

am11 commented Mar 24, 2015

but I don't know how to create a fs object

require('fs').renderFileSync(this.options.outFile, result.css, 'utf8')

or

var fs = require('fs');
fs.renderFileSync(this.options.outFile, result.css, 'utf8');

fs is node.js core filesystem API: https://nodejs.org/api/fs.html.

@PhiLhoSoft
Copy link
Author

Meanwhile, based on your information, I did some searches, and ended with this script which seems to work:

var sass = require("node-sass");
var fs = require("fs");

var sassPath = "src/main/sass";
var cssPath = "src/main/css";
sass.render(
{
    file: sassPath + "/playground.scss",
    includePaths: [ sassPath ],
    outFile: cssPath,
    outputStyle: "nested",
    sourceComments: true,
    sourceMap: true,
    importer: function(url)
    {
        return { file: url };
    }
},
function(error, result)  // >= v3.0.0
{
    if (error)
    {
        console.log(error);
    }
    else
    {
        console.log("Result path: " + result.path);
        console.log(result.stats);
        fs.writeFileSync(cssPath + "/playground.css", result.css.toString());
        fs.writeFileSync(cssPath + "/playground.css.map", result.map.toString());
    }
});

@am11
Copy link
Contributor

am11 commented Mar 24, 2015

Congrats! 😎
You can try writeFileSync without .toString() part, I think that would work as well. Probably you would need to set third parameter to 'utf8' (encoding):

fs.writeFileSync(cssPath + "/playground.css", result.css.toString());
fs.writeFileSync(cssPath + "/playground.css.map", result.map.toString());

to

fs.writeFileSync(cssPath + "/playground.css", result.css);
fs.writeFileSync(cssPath + "/playground.css.map", result.map);

// or

fs.writeFileSync(cssPath + "/playground.css", result.css, 'utf8');
fs.writeFileSync(cssPath + "/playground.css.map", result.map, 'utf8');

@PhiLhoSoft
Copy link
Author

I confirm it works with your improved version.

Thanks for the feedback, information and help (and patience!).

Hey, at least, this thread can hopefully be useful to people hitting the same issues. 😄

My final version:

var sass = require("node-sass");
var fs = require("fs");

var fileName = "playground";
var sassPath = "src/main/sass/";
var cssPath = "src/main/css/";
sass.render(
{
    file: sassPath + fileName + ".scss",
    includePaths: [ sassPath ],
    outFile: cssPath,
    outputStyle: "nested",
    sourceComments: true,
    sourceMap: true,
    importer: function(url)
    {
        return { file: url };
    }
},
function(error, result)  // >= v3.0.0
{
    if (error)
    {
        console.log(error);
    }
    else
    {
        console.log("Result path: " + result.path); // Always undefined...
        console.log(result.stats);
        fs.writeFileSync(cssPath + fileName + ".css", result.css, "utf8");
        fs.writeFileSync(cssPath + fileName + ".css.map", result.map, "utf8");
    }
});

@am11
Copy link
Contributor

am11 commented Mar 24, 2015

Glad to help! :)
There are always new stuff to learn on GitHub!

@am11 am11 closed this as completed Mar 27, 2015
@xzyfer xzyfer removed this from the Unknown milestone Sep 17, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants