Git Product home page Git Product logo

sass-graph's Introduction

Sass Graph

Parses Sass files in a directory and exposes a graph of dependencies

Build Status Coverage Status npm version Dependency Status devDependency Status

Install

Install with npm

npm install --save-dev sass-graph

Usage

Usage as a Node library:

var sassGraph = require('./sass-graph');

Usage as a command line tool:

The command line tool will parse a graph and then either display ancestors, descendents or both.

$ ./bin/sassgraph --help
Usage: bin/sassgraph <command> [options] <dir> [file]

Commands:
  ancestors    Output the ancestors
  descendents  Output the descendents

Options:
  -I, --load-path   Add directories to the sass load path
  -e, --extensions  File extensions to include in the graph
  -j, --json        Output the index in json
  -h, --help        Show help
  -v, --version     Show version number

Examples:
  ./bin/sassgraph descendents test/fixtures test/fixtures/a.scss
  /path/to/test/fixtures/b.scss
  /path/to/test/fixtures/_c.scss

API

parseDir

Parses a directory and builds a dependency graph of all requested file extensions.

parseFile

Parses a file and builds its dependency graph.

Options

loadPaths

Type: Array Default: [process.cwd]

Directories to use when resolved @import directives.

extensions

Type: Array Default: ['scss', 'sass']

File types to be parsed.

follow

Type: Boolean Default: false

Follow symbolic links.

exclude

Type: RegExp Default: undefined

Exclude files matching regular expression.

Example

var sassGraph = require('./sass-graph');
console.log(sassGraph.parseDir('test/fixtures'));

//{ index: {,
//    '/path/to/test/fixtures/a.scss': {
//        imports: ['b.scss'],
//        importedBy: [],
//    },
//    '/path/to/test/fixtures/b.scss': {
//        imports: ['_c.scss'],
//        importedBy: ['a.scss'],
//    },
//    '/path/to/test/fixtures/_c.scss': {
//        imports: [],
//        importedBy: ['b/scss'],
//    },
//}}

Running Mocha tests

You can run the tests by executing the following commands:

npm install
npm test

Authors

Sass graph was originally written by Lachlan Donald. It is now maintained by Michael Mifsud.

License

MIT

sass-graph's People

Contributors

adnelson avatar akiran avatar alan-agius4 avatar char0n avatar dosentmatter avatar elxx avatar greenkeeperio-bot avatar jorrit avatar kevin-smets avatar kiskoza avatar lox avatar ludwiktrammer avatar marcelrobitaille avatar martinheidegger avatar nervo avatar nightwolfz avatar niksy avatar ohiekkar avatar patricksmms avatar pleunv avatar realityking avatar robrichard avatar vegetableman avatar xzyfer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sass-graph's Issues

yarn still picking up unpublished 2.2.0 version

I realize version 2.2.0 was unpublished, but yarn still insists on installing it for some reason.

I've filed an issue against yarn for this (yarnpkg/yarn#3274), but in the meantime, I was hoping that you might consider releasing a new version of 'sass-graph' on npm to get people like me out of this mess...

Thanks

Global dependencies?

Can we use this module to track global, load order-based dependencies?

For example, if I have files ordered like:

A defines vars
B defines mixins
C contains output styles 
D imports A, B, C

and I change a mixin definition in B, C may or may not be affected. I could follow the import chain from B to D and then back into A and C, but A will never be affected because of load order.

To add to the complexity, from what I see there's no way to tell if a file, although imported, actually contains a var/function/mixin. I'm not sure if that's even possible with current Sass.

Thanks.

sass-graph should prefer cwd over loadPaths for @imports

I ran into an issue running sass-graph on a larger project. There are two modules within this project that contain a "_base.scss". All scss files in module 1 that imported _base worked correctly, but when it was time to compile scss files in module 2, their @import statements were resolving the _base.scss from module 1 instead of the one in the CWD.

mod1/_a.scss
mod1/b.scss
   @import "a";
mod2/_a.scss
mod2/b.scss    
   @import "a";  // graph.index['mod2/b.scss'].imports === ['mod1/_a.scss']

By default, I believe Sass will look for imports in the CWD and then look in any include paths from there

Sass looks for other Sass files in the current directory, and the Sass file directory under Rack, Rails, or Merb. Additional search directories may be specified using the :load_paths option, or the --load-path option on the command line. - Source

I'm opening up a PR that I think will fix the issue, curious to hear your feedback.

Imports aren't properly resolved

Not sure if it's intended but if I specify loadsPaths: ['./src', './node_modules'] and parse directory src I dont get any imports/importedBy paths. If I specify paths as ['./'] it resolves them fine.
My folder structure would be:

node_modules/.....
src/.....

so in reality I include both paths that are included by './' either way, but the result is different.

Sass-graph fails on compass imports

@import "compass";
@import "compass/reset";

Defining this in your scss will cause sass-graph to fail silently. Each and every compass import starts with compass, so maybe these could be whitelisted?

Can we avoid calling fs.realpathSync(filepath) if filepath is already an absolute path?

I ran into an issue trying to use this plugin in my gulp watch task.

I have this code:

const gulp = require('gulp');
const sassGrapher = require('sass-graph');
const touch = require('touch');

const sassGraph = sassGrapher.parseDir('./app/assets/stylesheets');

gulp.task(
  'watch',
  () => {
    // ... (additional watch statements)

    // Trigger recompilation of stylesheet entry points when their dependencies are modified
    gulp.watch([buildStylesTask.watchFiles], (event) => {
      sassGraph.visitAncestors(event.path, (parent) => {
        if (parent.includes('stylesheets/packs')) {
          touch.sync(parent);
        }
      });
    });
  }
);

For the most part, this works pretty well, except if event.path refers to a watched file that was deleted. In that case, the watch task crashes with:

Error: ENOENT: no such file or directory, lstat '/Users/rmacklin/src/m/app/assets/stylesheets/components/tooltip.scss'
    at Object.realpathSync (fs.js:1657:15)
    at Graph.visit (/Users/rmacklin/src/m/node_modules/sass-graph/sass-graph.js:117:17)
    at Graph.visitAncestors (/Users/rmacklin/src/m/node_modules/sass-graph/sass-graph.js:101:8)
    at gulp.watch (/Users/rmacklin/src/m/lib/tasks/assets/watch.js:18:56)
    at Gaze.<anonymous> (/Users/rmacklin/src/m/node_modules/glob-watcher/index.js:18:14)
    at emitTwo (events.js:126:13)
    at Gaze.emit (events.js:214:7)
    at Gaze.emit (/Users/rmacklin/src/m/node_modules/glob-watcher/node_modules/gaze/lib/gaze.js:129:32)
    at /Users/rmacklin/src/m/node_modules/glob-watcher/node_modules/gaze/lib/gaze.js:389:18
    at Array.forEach (<anonymous>)

which is caused by this line (on the current master branch, it's this line):

filepath = fs.realpathSync(filepath);

Since the watched file was removed, fs.realpathSync throws that error. However, the event.path value that gets passed for the filepath parameter is already an absolute path, so it seems like in that scenario it is unnecessary to call fs.realpathSync. Does that seem reasonable? If so, would it be okay to add a guard check like if (!path.isAbsolute(filepath)) before we call fs.realpathSync?

ERROR in scss-tokenizer dependency

Hi,

I am getting the following error when i try to install gulp-sass. I believe it is due to the most recent release of scss-tokenizer as the module was installing properly yesterday.

Please advise on what to do to fix this.

npm version: 2.15.9
node version: 4.5.0
npm i gulp-sass
npm ERR! Darwin 15.6.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "i" "gulp-sass"
npm ERR! node v4.5.0
npm ERR! npm  v2.15.9
npm ERR! code ETARGET

npm ERR! notarget No compatible version found: scss-tokenizer@'>=0.2.3 <0.3.0'
npm ERR! notarget Valid install targets:
npm ERR! notarget ["0.0.1","0.1.0","0.1.1","0.1.2","0.2.0","0.2.1"]
npm ERR! notarget 
npm ERR! notarget This is most likely not a problem with npm itself.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.
npm ERR! notarget 
npm ERR! notarget It was specified as a dependency of 'sass-graph'
npm ERR! notarget 

Upgrade to yargs 16.2.0

Yargs 13.3.2 is currently using y18n 4.0.0 which has a pollution issue that shows up on vulnerability scans

Would it be possible to upgrade yargs to 16.2.0 which uses y18n 5.0.5 which fixes this?

Lodash vulnerability

There's a security vulnerability in the version of loadash used here.

Using the latest seems to solve the issue.

Could someone bump the version and publish it to npm, please?

Much appreciated ๐Ÿ™

SASS includes

SASS includes can be used without quotes:

@import includes/_header.sass
@import includes/_content

These includes aren't processed by SASS-graph (filter doesn't match imports without quotes).

Checking all load paths in resolveSassPath can lead to false positives

In my file I declare @import 'test';

But if test.scss is not located here, but for example in imports/test.scss

This will result in a false import statement in the graph.

Why are all load paths being checked instead of the just the one path from the import?

This also blocks me from properly resolving #16

Maybe this should not be fixed as the file will not actually compile? Still, it's rather unexpected behaviour in my opinion.

includePaths to resolve import path

Hi there. I don't know if it's an issue, but it could be nice to have an includePaths option, like node-sass.

In my case, I have to import sass files from some modules, in my node_modules folder, but sass-graph seems to not detect them at all.

In this exemple, I have :

@import "lib/foo";
@import "foo-module/foo"; // In ./node_modules/foo-module/foo.scss

But sass-graph only detect the file in lib/foo. Not the file in node_modules/foo-module, which isn't a surprise, because it have no way to detect that foo-module/foo.scss is in my node_modules folder.

Could we have an elegant solution for this case, or I am it doing wrong ?

Awesome project btw, save me hours of headache.

resolveSassPath ignores explicit file names.

I just updated sass-loader in my project and can't get my project built. I've narrowed it down to this...

This is where the problem is:

var sassPathName = sassPath.replace(/\.\w+$/, '');
  ...
var scssPath = path.normalize(loadPaths[i] + "/" + sassPathName + ".scss");

Can we make it take the sassPath directly when normalizing? then when not found attempt to add known extensions?

In the project referenced above I have several font imports that are just simple css files:

@import "../fonts/fontname/index.css"

Error while running node-sass on babel6

When running node-sass on a project using babel 6, the command fails with the following error -

/mnt1/jenkins/workspace/edge-ui-all-build-deploy/node_modules/scss-tokenizer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:126
      if (!option) this.log.error("Unknown option: " + alias + "." + key, ReferenceError);
                           ^

TypeError: Cannot read property 'error' of undefined
    at OptionManager.mergeOptions (/mnt1/jenkins/workspace/edge-ui-all-build-deploy/node_modules/scss-tokenizer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:126:28)
    at OptionManager.addConfig (/mnt1/jenkins/workspace/edge-ui-all-build-deploy/node_modules/scss-tokenizer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:107:10)
    at OptionManager.findConfigs (/mnt1/jenkins/workspace/edge-ui-all-build-deploy/node_modules/scss-tokenizer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:168:35)
    at OptionManager.init (/mnt1/jenkins/workspace/edge-ui-all-build-deploy/node_modules/scss-tokenizer/node_modules/babel-core/lib/transformation/file/options/option-manager.js:229:12)
    at compile (/mnt1/jenkins/workspace/edge-ui-all-build-deploy/node_modules/scss-tokenizer/node_modules/babel-core/lib/api/register/node.js:117:22)
    at normalLoader (/mnt1/jenkins/workspace/edge-ui-all-build-deploy/node_modules/scss-tokenizer/node_modules/babel-core/lib/api/register/node.js:199:14)
    at Object.require.extensions.(anonymous function) [as .js] (/mnt1/jenkins/workspace/edge-ui-all-build-deploy/node_modules/scss-tokenizer/node_modules/babel-core/lib/api/register/node.js:216:7)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Module.require (module.js:366:17)

It seems like the dependency scss-tokenizer is using babel5 so is unable to read the .babelrc written in the main project(which is in babel6).

Environment -
node - 4.2.2
npm - 3.8.1

[Feature Request] `--depth` option?

Can there be a --depth option to limit how many levels of imports we go down?

I think the implementation would be in this part of code. I think you can keep track of the current depth in the arguments and +1 each time you recurse by calling addFile(). And in that if statement, don't recurse if you have hit the maximum depth. Is this correct?

Option can be added to yargs and passed to parseDir().

npm audit high vulnerability

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ High          โ”‚ Prototype Pollution                                          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Package       โ”‚ lodash                                                       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Dependency of โ”‚ node-sass                                                    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Path          โ”‚ node-sass > sass-graph > lodash                              โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ More info     โ”‚ https://npmjs.com/advisories/782                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

sass-graph doesn't parse .sass files

Most sass parsers parse .sass file ("indented syntax") as well as .scss syntax. I create a branch โ€” https://github.com/averyvery/sass-graph/blob/parse-sass-filetypes/ โ€” that modifies sass-graph to allow for this.

Error: Cannot find module 'scss-tokenizer'

Hi,

Over a trusty linux system (so not the latest node/npm versions, 4.8.2/4.5.0), I keep receiving the following issue when running sass-graph.js:

module.js:327
    throw err;
    ^

Error: Cannot find module 'scss-tokenizer'
    at Function.Module._resolveFilename (module.js:325:15)
    at Function.Module._load (module.js:276:25)
    at Module.require (module.js:353:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (/opt/stack/contrail/contrail-webui-third-party/node_modules/node-sass/node_modules/sass-graph/parse-imports.js:1:79)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Module.require (module.js:353:17)

Seems like a straight forward thing and unrelated to this module, but the scss-tokenizer module is there. I even tried installing it globally, still, parse-imports is not able to find it.

Any hint please, will be much appreciated.

Thanks.

resolveSassPath misses nested dependencies with the same name

Having an unusual issue with sass-graph:

  • I have a components/_index.scss that imports nav/index and overlay/index
  • Both overlay/_index.scss and nav/_index.scss import files (in their respective directories) named _wrapper.scss
  • Both index files are included in the graph, but only ONE _wrapper.scss is included in the graph. The resolveSassPath method seems to count nav/_wrapper.scss twice instead of counting overlay/_wrapper.scss
  • This seems to be happening because resolveSassPath returns the first match for a filename + loadPath that it finds.

I've recreated this as a test case in a branch here, and proposed a fix:

CLI usage instructions unclear

I'm trying to use the CLI tool provided with this package, but with no luck.
With the JS API, I can run the following and get the result I want:

const sassGraph = require('sass-graph');
console.log(sassGraph.parseFile(
  'app/packs/entrypoints/publisher-profile.scss',
  {
    loadPaths: ['app/assets/stylesheets'],
  }
));

But I've been unable to replicate this successfully with the CLI tool.
I've tried the following:

  • sassgraph descendents app/packs/entrypoints/publisher-profile.scss
    • Error: Missing directory
  • sassgraph descendents -I app/assets/stylesheets app/packs/entrypoints/publisher-profile.scss
    • Error: Missing directory
  • sassgraph descendents -I app/assets/stylesheets app/assets/stylesheets/ app/packs/entrypoints/publisher-profile.scss
    • Error: Missing directory
  • sassgraph descendents app/assets/stylesheets/ app/packs/entrypoints/publisher-profile.scss
    • No output

Missing license

Hello, is it possible to incorporate the LICENSE file inside the repo and npm package ? Now it's missing. It's implied by MIT license that if licensed under the MIT the source code must be accompanied by full license text. If the license file is not in the repo nor npm package the code is proprietary and the world cannot use it.

Thank you

Consecutive URL imports in CSS cause an error

(mostly) reduced test case: https://github.com/RoyTinker/node-sass-watch-import-css-bug

CSS:

@import url(http://some-site.com/fonts/1);
@import url(something.css);

Error:

/[redacted]/node_modules/sass-graph/parse-imports.js:20
        throw new Error('Encountered invalid @import syntax.');
        ^

Error: Encountered invalid @import syntax.
    at parseImports (/[redacted]/node_modules/sass-graph/parse-imports.js:20:15)
    at Graph.addFile (/[redacted]/node_modules/sass-graph/sass-graph.js:69:17)
    at /[redacted]/node_modules/sass-graph/sass-graph.js:54:13
    at arrayEach (/[redacted]/node_modules/lodash/lodash.js:537:11)
    at Function.forEach (/[redacted]/node_modules/lodash/lodash.js:9359:14)
    at new Graph (/[redacted]/node_modules/sass-graph/sass-graph.js:53:7)
    at Object.module.exports.parseDir (/[redacted]/node_modules/sass-graph/sass-graph.js:156:17)

Wrong Graph object when using node-sass custom importer function supporting glob patterns in sass import statements

PROJECT AND DEPENDENCIES

I have

node v8.11.2
npm v5.8.0

and I am using a create-react-app-typescript app with following relevant packages installed:

"dependencies": {
    "@types/reactstrap": "^6.0.2",
    "bootstrap": "^4.1.3",
    "react": "^16.4.2",
    "react-dom": "^16.4.2",
    "react-scripts-ts": "2.17.0",
    "reactstrap": "^6.3.1",
    ...
  },
...
"devDependencies": {
     ...
    "@types/node": "^10.5.6",
    "@types/react": "^16.4.7",
    "@types/react-dom": "^16.0.6",
    "concurrently": "^4.0.1",
    "node-sass-chokidar": "^1.3.3",
    "node-sass-glob-importer": "^5.2.0",
    "typescript": "^3.0.1"
     ...    
  }.

My relevant scripts in package.json are:

"start": "concurrently \"npm:watch-css\" \"react-scripts-ts start\"",
"build-css": "node-sass-chokidar --importer node_modules/node-sass-glob-importer/dist/cli.js src/ -o src/",
"watch-css": "npm run build-css && node-sass-chokidar --watch --recursive --importer node_modules/node-sass-glob-importer/dist/cli.js src/ -o src/"

SASS ARCHITECTURE

I have implemented a 7-1 pattern architecture for my sass files (inside each folder I only have partial files):

image

My main.scss file looks like this:

@charset 'UTF-8';

@import 'abstracts/*';
@import 'vendors/*';
@import 'base/*';
@import 'layout/*';
@import 'components/*';
@import 'pages/*';
@import 'themes/*';
@import '_shame';

THE PROBLEM

node-sass and node-sass-chokidar uses sass-graph to build a Graph object. There is the option --import in node-sass, which allows us to define a custom function as an extension of the importer feature of LibSass.
There are different libraries to use as the importer out there, but I am using particularly node-sass-glob-importer, which allows to write glob patterns in sass' import statements.
This library works perfectly when compiling sass files without watch mode. This is because the imports in any sass file, are parsed by LibSass and then each import statement goes through this library to check if there are some glob patterns in them, if so, the library sends all corresponding paths out of the glob patterns to LibSass again. So far, so good.
In watch mode, node-sass builds a Graph object coming from sass-graph and here is the real problem. A Graph object has an "index" property, which is an object whose keys are the paths of all sass files (partials or not) found under the specified watched directory. The value for each key is an entry with following properties:

- imports: all import paths found in this current sass file
- importedBy: all paths to the files that import this current sass file
- modified: a timestamp with the time this current sass file was modified

For instance, in my sass architecture, the entry object for my _shame.scss file looks like:

{
...
"index": {
   "~/_shame.scss":{
          "imports": [],
          "importedBy": ["~/main.scss"],
          "modified": [some_timestamp]
   }
}
...
}

since main.scss is the only file that imports this file. This is how node-sass realize when to re-render main.scss, either if it was modified directly, or if any file containing its path in the "importedBy" property was modified. And this is working, of course, I modify _shame.scss and I get in the console that "main.scss" was modified and it is re-compiled again.
Now, when I modify any file inside abstracts folder, for instance "abstracts/_variables.scss" partial file, I do not get main.scss re-compiled. So, I checked the entry for this file and it looks like:

...
"index": {
   "~/abstracts/_variables.scss":{
          "imports": [],
          "importedBy": [],
          "modified": [some_timestamp]
   }
}
...

Why is this happening? I started debugging and I got to this point when sass-graph is adding main.scss file into the Graph:

image

When parsing import statements at line 69, glob patterns are not resolved by the parse-imports script. As you can see in the red circle, all imports are still there with the glob pattern.

Where does it break? In line 75, more specifically in line 20 inside resolveSassPath method. If we execute the condition the if is evaluating with

scssPath = "[path_start]/abstracts/*"

it will throw an exception, it will be catched but nothing will be done (exception swallowing). Thus, false will be returned as result and in line 76 a continue statement will skip that import (it will do the same for all imports with glob patterns) and only the _shame.scss file (since it has no glob pattern and can be resolved by resolveSassPath method) will be included in the "imports" property of the main.scss file inside the Graph object. So, the final result will be main.scss not taking into consideration that is importing files specified by the glob patterns and each partial file matching the glob patterns not taking into consideration that is imported by main.scss.

SOLUTION

In my opinion we should come to a common way to parse import statements in node-sass. If watch mode is not specified, it is a LibSass and the (if specified) custom importer function responsibility. If watch mode is specified, then sass-graph parses the imports (not supporting glob patterns). So, whatever I can do with the custom importer is not supported in sass-graph.
A temporary solution would be to modify the parse-imports script to support glob patterns when building the graph, or even better, to use the custom importer function passed to node-sass (we should pass it all along to sass-graph).

I volunteer to contribute to fix this, if the rest of the community see this as a real bug.

Opinions, comments and tips are very well welcomed!

Best,
Max.

sass-graph 2.2.0 and issue with node-sass: Unexpected token import

Hello,

I use node-sass which is a dependency of my project and node-sass use sass-graph with the resolving number: "sass-graph": "^2.1.1".

Since you published a new version 2.2.0, node-sass use now the 2.2.0 version and when I run:

node-sass --include-path demo/digital-style/sass demo/digital-style/sass/style-ss.scss -o demo/app/css/

I have this error:

C:\myRepo\node_modules\scss-tokenizer\lib\entry.js:1
(function (exports, require, module, __filename, __dirname) { import Input from './input';
                                                              ^^^^^^
SyntaxError: Unexpected token import
    at createScript (vm.js:53:10)
    at Object.runInThisContext (vm.js:95:10)
    at Module._compile (module.js:543:28)
    at Module._extensions..js (module.js:580:10)
    at Object.require.extensions.(anonymous function) [as .js] (C:\myRepo\node_modules\scss-tokenizer\node_modules\babel-core\lib\api\register\node.js:214:7)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)

I don't know if it's the good place to report.
Can you help me?

Kind regards.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.