thomas-darling / 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.
15 stars 5 forks source link

Is it possible to do incremental builds with single file entry? #8

Closed asolopovas closed 3 years ago

asolopovas commented 3 years ago

Hi, I am trying to make the incremental sass build to work with single entry, is it possible to achieve with your library? in my case app.scss has one import but if I change contents of the imported file it does not compile the build. This does not work for me:

let config = {
    ".scss": {
        parserSteps: [
            /^\s*@import\s+(.+?);/gm,
            function (text) { return text.split(","); },
            /"([^"]+)"|'([^']+)'/m
        ],
        prefixes: ['_'],
        postfixes: ['.scss', '.sass'],
        basePaths: [],
    }
};

task('incrementalSass', () => {
    return src('src/app.scss')
        .pipe(cached('sass'))
        .pipe(dependents(config, {logDependents: true}))
        .pipe(sass())
        .pipe(dest('dest/css'))
})

It only does work if I do the following:

task('incrementalSass', () => {
    return src('src/*.scss')
        .pipe(cached('sass'))
        .pipe(dependents(config, {logDependents: true}))
        .pipe(sass())
        .pipe(dest('dest/css'))
})
thomas-darling commented 3 years ago

No, I don't believe that would work - this plugin needs to process each individual file, in order to build its dependency graph.

To make the scenario you describe work, the plugin would have to, as it parses each import statement, actually go and read the imported file from disk itself. As currently implemented, that's not what happens - instead it assumes that Gulp will pipe in all the files during the initial run. There's a note about it hiding in here.


If I understand your use case correctly though, your goal is to structure your styles in multiple files, but produce only a singe file as output - and you try to achieve that by piping in a single file, which then contains import statements that pull everything else into that file, correct?

It's been a few years, but if I remember correctly, what we did to achieve this, was to name all those imported files with an underscore prefix, which is a hint to the Sass compiler that it should not produce any output for that file.

From the Sass docs:

Partials

You can create partial Sass files that contain little snippets of CSS that you can include in other Sass files. This is a great way to modularize your CSS and help keep things easier to maintain. A partial is a Sass file named with a leading underscore. You might name it something like _partial.scss. The underscore lets Sass know that the file is only a partial file and that it should not be generated into a CSS file. Sass partials are used with the @use rule.

https://sass-lang.com/guide

asolopovas commented 3 years ago

Thanks for your reply. I am building a similar tool to laravel mix, it simplifies the configuration of webpack and sass for end-user and looks something like this.

dev.js(srcJs, destJs, options).sass(srcSass, destSass, options).sass(srcSass2, destSass2, options)

Behind the scenes, it dynamically creates gulp tasks and streams them to browserync. I can pass postCss plugins into the option section of sass. The problem is that in my use-case I need to generate a different configuration for tailwind postcss plugin for each of the sass methods, but the build is a bit long as tailwind in its full capacity is around 5mb and build takes 3s-5s, by having two I double the execution of those tasks and by changing one dependent file make recompilation very lengthy. I potentially could create two folders for each sass tasks but would make it look a bit messy.

thomas-darling commented 3 years ago

I see - in that case, I'm not sure this plugin is ideal for your use case :-/

I haven't looked at this code in a long time, but I think it would require quite a bit of rework to support reading and parsing the imported files, instead of waiting for them to be piped in by Gulp. It's quite a different approach to the problem, and it would actually introduce additional overhead for the used case this plugin was designed for, as all the files would be read from disk twice - both by this plugin and by Gulp. That's actually the reason it was originally designed this way.

Therefore, I think supporting this falls outside the scope of what this plugin should do - you're more than welcome to copy code from here though, if you end up building something yourself :-)