Skip to content

Commit

Permalink
Release 1.2.0
Browse files Browse the repository at this point in the history
Changed project to use the Visual Studio Code.
Fixed bug causing incorrect tracking when using base paths.
  • Loading branch information
thomas-darling committed Feb 1, 2017
1 parent 2c54aa2 commit c358d45
Show file tree
Hide file tree
Showing 37 changed files with 379 additions and 3,165 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
21 changes: 4 additions & 17 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
## Ignore files and folders created by the OS

# Windows
$RECYCLE.BIN/
Thumbs.db

# OSX
.DS_STORE/

## Ignore files and folders created by the IDE
## Ignore package folders

.vs/
.ntvs_analysis.dat
bin/
obj/
dist/
**/node_modules/

## Ignore package folders
## Ignore build artifacts

node_modules/
/lib/
16 changes: 16 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## Ignore source files

/src/

## Ignore example files

/example/

## Ignore config files

/.git/
/.vscode/
.gitattributes
.gitignore
.npmignore
tsconfig.json
18 changes: 18 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Place your settings in this file to overwrite default and user settings.
{
// Configure glob patterns for excluding files and folders.
"files.exclude": {
".vscode": true,
".gitattributes": true,
".gitignore": true,
".npmignore": true,
"lib": true,
"**/node_modules": true
},

// When enabled, will trim trailing whitespace when you save a file.
"files.trimTrailingWhitespace": true,

// Use the TypeScript version specified in package.json.
"typescript.tsdk": "./node_modules/typescript/lib"
}
10 changes: 10 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
"command": "tsc",
"isShellCommand": true,
"args": ["-p", "."],
"showOutput": "silent",
"problemMatcher": "$tsc"
}
21 changes: 0 additions & 21 deletions LICENSE

This file was deleted.

147 changes: 143 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,145 @@
# gulp-dependents
gulp-dependents
===============
Gulp plugin that tracks dependencies between files and adds any files that depend
on the files currently in the stream, thus enabling incremental build of `less`,
`scss` and `sass` files, with extensibility points to support other file types.
on the files currently in the stream, thus enabling incremental build of `pcss`,
`less`, `scss` and `sass` files, with extensibility points to support other file
types.

See `readme.md` in the `gulp-dependents` folder for more info.
## Problem
Gulp makes it easy to build all your files, but as the code base grows, so does
the build time, significantly slowing down your workflow. The solution is
incremental building - i.e. to rebuild only the files that have actually changed.
Unfortunately Gulp is agnostic about the depenencies between your files, making
it hard to incrementally build files that depend on other files - it doesn't know,
that when a dependency changes, so does the files that depend on it.

## Solution
This plugin tracks the dependencies of all the files that pass trough it, building
and maintaining an in-memory dependency tree describing the dependencies between
the files. For each file that passes through, it will add any files that directly
or indirectly depend on that file to the stream, thus ensuring that they will also
be rebuild. Combined with e.g. the [gulp-cached](https://www.npmjs.com/package/gulp-cached)
plugin, or the "since last run" option in Gulp 4, this enables fast and reliable
incremental builds.

## Usage
This example shows how the plugin may be used to watch and incrementally build
`less` files. The `gulp-cached` plugin will pass all files through on the first
run, thus allowing `gulp-dependents` to set up the initial dependency graph. On
subsequent runs, only changed files will be passed through, and `gulp-dependents`
will then ensure that any dependent files are also pulled into the stream.

```javascript

var gulp = require('gulp'),
less = require('gulp-less'),
cached = require('gulp-cached'),
dependents = require('gulp-dependents');

gulp.task('watch', function() {
gulp.watch('src/**/*.less', ['build']);
});

gulp.task('build', function() {
return gulp
.src('src/**/*.less')
.pipe(cached('less'))
.pipe(dependents())
.pipe(less())
.pipe(gulp.dest('dist'))
});

```

Note that `gulp-cached` and `gulp-changed` have different behavior - `gulp-changed`
will *not* nessesarily pass all files through on first run. Instead, it compares the
timestamps of the source and destination files, and only pass through those that appear
to be different. This means, that you must clean your output folder every time your
watch task starts, as this plugin needs to process all files at least once, in order to
determine the initial dependency tree - it won't know a file depends on another,
until it has parsed its dependency statements at least once.

## Support and limitations
Out of the box, this plugin supports `pcss`, `less`, `scss` and `sass` files, including
things like comma-separated path lists, import statements spanning multiple lines
and `url(...)` paths. For `sass`, which is the indent-based variant of the `scss`
syntax, support is limited to single-line statements. Also note, that due to the
way tracking is implemented, it is currently not be possible to support dependency
statements with glob patterns, referencing e.g. all files in a folder.

## Configuration
For the file types supported out of the box, there's generally no need to
configure anything, but should the need arise, a parser configuration may be
passed to the plugin function. Note that the options are merged into the
default configuration, so if you only wish to override e.g. the `basePaths`
option for `scss` files, then simply specify only that property.

The parser will apply each `RegExp` or `function` in the `parserSteps` array in
sequence, such that the first receives all the file content and may e.g. extract
whole dependency statements, and the second one may then extract the paths from
those statements. This design enables parsing of complex statements that e.g.
list multiple, comma-separated file paths. It also enables the use of externa
parsers, by specifying a function, which simply invokes the external parser to
get the dependency paths.

```javascript

// The parser configuration, in which keys represents file name
// extensions, including the dot, and values represent the config
// to use when parsing the file type.
var config = {

".scss": {

// The sequence of RegExps and/or functions to use when parsing
// dependency paths from a source file. Each RegExp must have the
// 'gm' modifier and at least one capture group. Each function must
// accept a string and return an array of captured strings. The
// strings captured by each RegExp or function will be passed
// to the next, thus iteratively reducing the file content to an
// array of dependency file paths.
parserSteps: [

// PLEASE NOTE:
// The parser steps shown here are only meant as an example to
// illustrate the concept of the matching pipeline.
// The default config used for scss files is pure RegExp and
// reliably supports the full syntax of scss import statements.

// Match the import statements and capture the text
// between '@import' and ';'.
/^\s*@import\s+(.+?);/gm,

// Split the captured text on ',' to get each path.
function (text) { return text.split(","); },

// Match the balanced quotes and capture only the file path.
/"([^"]+)"|'([^']+)'/m
],

// The file name prefixes to try when looking for dependency
// files, if the syntax does not require them to be specified in
// dependency statements. This could be e.g. '_', which is often
// used as a naming convention for mixin files.
prefixes: ['_'],

// The file name postfixes to try when looking for dependency
// files, if the syntax does not require them to be specified in
// dependency statements. This could be e.g. file name extensions.
postfixes: ['.scss', '.sass'],

// The additional base paths to try when looking for dependency
// files referenced using relative paths.
basePaths: [],
}
};

// Pass the config object to the plugin function.
.pipe(dependents(config))

// You can also pass a second config argument to enable logging.
.pipe(dependents(config, { logDependents: true }))

```

Enjoy, and please report any issues in the issue tracker :-)
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
var gulp = require("gulp");
var cached = require("gulp-cached");
var dependents = require("../../gulp-dependents");
var dependents = require("../../");
var debug = require("gulp-debug");

// The parser configuration, in which keys represents file name
// The parser configuration, in which keys represents file name
// extensions, including the dot, and values represent the config
// to use when parsing the file type.
var config =
{
".scss":
{
// The sequence of RegExps and/or functions to use when parsing
// The sequence of RegExps and/or functions to use when parsing
// dependency paths from a source file. Each RegExp must have the
// 'gm' modifier and at least one capture group. Each function must
// accept a string and return an array of captured strings. The
// accept a string and return an array of captured strings. The
// strings captured by each RegExp or function will be passed
// to the next, thus iteratively reducing the file content to an
// array of dependency file paths.
Expand All @@ -25,52 +25,53 @@ var config =
// for scss files is pure RegExp and reliably supports the
// full syntax for import statements.

// Match the import statements and capture the text
// Match the import statements and capture the text
// between "@import" and ";".
/^\s*@import\s+(.+?);/gm,

// Split the captured text on "," to get each path.
// Split the captured text on "," to get each path.
function (text) { return text.split(","); },

// Match the balanced quotes and capture only the file path.
/"([^"]+)"|'([^']+)'/gm
],

// The file name prefixes to try when looking for dependency
// files, if the syntax does not require them to be specified in
// dependency statements. This could be e.g. '_', which is often
// used as a naming convention for mixin files.
prefixes: ["_"],

// The file name postfixes to try when looking for dependency
// files, if the syntax does not require them to be specified in
// dependency statements. This could be e.g. file name extensions.
postfixes: [".scss"],

// The additional base paths to try when looking for dependency
// files referenced using relative paths.
basePaths: [],
basePaths: ["source"],
}
};

gulp.task("watch.styles", function () {

return gulp.watch('styles/**/*.scss', ['build.styles']);
});

gulp.task("build.styles", function () {
gulp.task("build", function ()
{
return gulp

// Get all source files.
.src("styles/**/*.scss")
.src("source/**/*.scss")

// On first run, this will pass through all files.
// On subsequent runs, only changed files will be passed through.
.pipe(cached("scss"))

// Add any dependent files to the stream.
.pipe(dependents(config, { logDependents: true, logDependencyMap: true }))
.pipe(dependents(config, { logDependents: true, logDependencyMap: false }))

// For debugging, just output the name of each file we're about to build.
.pipe(debug({ title: "[build.styles]" }));
.pipe(debug({ title: "[build]" }));
});

gulp.task("watch", function ()
{
return gulp.watch('source/**/*.scss', ['build']);
});
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import "mixin";
@import "lib/mixin";

html, body
{
Expand Down
File renamed without changes.
Loading

0 comments on commit c358d45

Please sign in to comment.