Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for a "cool-down" period before triggering a regeneration. #559

Closed
veleek opened this issue Jun 7, 2019 · 18 comments
Closed
Labels
bug: lite Debatable whether or not this is a bug. I mean, it’s not great but it’s not really broken either. enhancement

Comments

@veleek
Copy link
Contributor

veleek commented Jun 7, 2019

I have a site which contains multiple uniquely styled sub-pages which each have their own SASS files. When running eleventy alongside gulp, when I save a single SASS file, gulp regenerates all of the css files which triggers eleventy to regenerate. Unfortunately, the first file change triggers a regeneration, and the second file change queues up another one. So as any css file causes eleventy to regenerate everything twice which really slows down iteration.

For example, given this super basic site example:

/site
    /events
        /birthday
            index.md
            style.scss
            /media
                thing.ttf, etc.
        /christmas
            index.md
            style.scss
            etc.

I have a gulp task that processes all the .scss files to produce style.css in the same folder. The actual sub-sections are relatively complicated but self-contained and they include things like fonts, images, additional sub-pages etc. Moving all the styles and images to folders outside of the root site would make it difficult to manage each of these sites independently so I would like to keep everything self-contained if possible.

I would love if there was some sort of configurable delay that would wait after receiving a file modification event before regenerating the site. The more complex version would be don't regenerate until X ms after the last file change event, so if my gulp task is long running each generated file would keep pushing back the regeneration time a little bit until everything was done.

This is similar to the awaitWriteFinish property in chokidar which I manually enabled in Eleventy.js and was hoping would work by queuing up file change events quickly enough to cause only a single eleventy rebuild, but no luck.

@miklb
Copy link

miklb commented Jun 7, 2019

are you running the gulp tasks in a series or parallel ? Seems you should be able to control it there unless I'm misunderstanding.

@veleek
Copy link
Contributor Author

veleek commented Jun 8, 2019

Both gulp and eleventy are running in parallel using the following npm scripts:

"scripts": {
        "dev": "npm-run-all --parallel dev:eleventy dev:gulp",
        "dev:eleventy": "eleventy --serve",
        "dev:gulp": "gulp"
}

Both eleventy --serve and gulp run in watch mode, so gulp watches for changes to CSS files and recompiles them, eleventy watches for changes to Markdown an Nunjucks files and re-complies them when they change. Neither one of the tasks is exiting and restarting, so there's no way to run them in serial (because they never exit).

@miklb
Copy link

miklb commented Jun 8, 2019

"dev": "npm-run-all --parallel dev:eleventy dev:gulp" can you swap the order here and run them --series

untested

"dev": "npm-run-all --series dev:gulp dev:eleventy"

in theory that will run the gulp task first, then eleventy which I think is what you were asking.

@veleek
Copy link
Contributor Author

veleek commented Jun 8, 2019

You can't run them in series. Gulp is being run in watch mode (watching for changes) so it never exits and series waits until the first task exits before running the second. If I don't run gulp in watch mode then it won't recompile scss changes. And the same is true for eleventy. Its running in watch mode and never exits because its running the local test web server.

@miklb
Copy link

miklb commented Jun 8, 2019

Gotcha. Sorry for misunderstanding your configuration.

@danfascia
Copy link

I have this same problem with my 11ty tailwind starter.

PostCSS is watching and rebuilding the CSS and Eleventy Serve is watching the *.md but the problem imho is that 11ty blocks the command execution chain.

The only solutions I could think of both involved relying on only one of the processes to do all of the watching and rebuilding:

  1. I could setup eleventy to run postcss and compile tailwind on every build from within config but that would be slow

  2. I could use gulp to do it all but personally I don't know how to make it watch for *.md changes

@miklb
Copy link

miklb commented Jun 11, 2019

Here is how I’m using Gulp with Jekyll to watch files https://github.com/miklb/jekyll-indieweb/blob/b313ce907b03eb34d59164eaef60bf3fc03fa90f/gulpfile.js#L78

I also use Gulp to run Jekyll which I’m sure could be adapted for Eleventy . Not saying it’s the most elegant solution however

@zachleat
Copy link
Member

Some discussion for this is also happening at the PR: #564

@zachleat zachleat added the needs-discussion Please leave your opinion! This request is open for feedback from devs. label Jun 12, 2019
@veleek
Copy link
Contributor Author

veleek commented Jun 12, 2019

@danfascia, re: option 2, making gulp to everything could potentially work, but since I'm using eleventy as the web server I would have to have an instance of eleventy running as the server (and not processing any files) and a second instance executed by gulp whenever any input files change. And then I would need to go through all the work of duplicating a bunch of eleventy config into gulp in order to make sure it was watching the same files in the same places as eleventy already is.

@miklb, the reason that this works is that you're manually running browserSync and the thing that watches the files (gulp in this case). In the eleventy case, eleventy --serve runs both the eleventy file watcher and the browser sync. The specific behavior that I'm looking for is that I want eleventy to wait until after all files have been changed before executing, and the only way to do that would be to have some control over those parts individually, which either means pulling the server portion out of eleventy, or pulling the template processing part out so I can choose when to run them. This behavior is already supported in gulp (see here, https://gulpjs.com/docs/en/getting-started/watching-files#delay) because of the same reason I want it in eleventy - to avoid starting too early when multiple files are being changed at once.

Additionally, it looks like you have a bug in your script here (https://github.com/miklb/jekyll-indieweb/blob/b313ce907b03eb34d59164eaef60bf3fc03fa90f/gulpfile.js#L81) where this line is calling gulp.series(...) but it's not doing anything with the task, so this specific instance isn't doing anything. The only thing that gets executed when any of the CSS files change is the css task, never the browserSync one.

@danfascia
Copy link

@veleek yes actually you're right, the fact that 11ty is also the webserver scuppers it. However in my 11ty starter I use lightserver as the webserver instead of the built in one since it is nice to decouple processes.

I feel like you have to do it one of 2 ways ...

  1. Everything, all in on 11ty config/npx eleventy --serve
  2. Decouple all parts into build processes

It's the only way you can not block the render chain with eleventy --serve

@zachleat zachleat added bug: lite Debatable whether or not this is a bug. I mean, it’s not great but it’s not really broken either. enhancement and removed needs-discussion Please leave your opinion! This request is open for feedback from devs. labels Jan 17, 2020
@zachleat zachleat added this to the Eleventy v0.11.0 milestone Mar 5, 2020
@zachleat
Copy link
Member

zachleat commented Mar 5, 2020

Fixed by 5ee0cde Please also see my comment on #696

This will ship with 0.11.0

@zachleat zachleat closed this as completed Mar 5, 2020
@jeromecoupe
Copy link

jeromecoupe commented Mar 29, 2020

Just adding my 2 cents here.

  • I never run Eleventy in watch mode when using Gulp or NPM scripts
  • IMHO, when using a build tool, that build tool should orchestrate everything (file generation and server / browsersync)
  • in this case it should watch files and run Eleventy when appropriate

When using Gulp, I generally make it watch njk and md files and use child process to run Eleventy. That way, you can control pretty much everything in terms of tasks and subtasks order.

Here is a simple .gulpfile as an example.

@veleek
Copy link
Contributor Author

veleek commented Apr 6, 2020

Thanks @jeromecoupe. I tried switching over to a similar gulpfile and everything seems to be working well (after working around a few issues with childprocess on Windows; the cross-spawn package is your friend!).

I'm pretty happy with this solution so I'll probably keep it, but I approve of having the cool-down period in eleventy even if it's only useful for the small subset of people who might only use eleventy and not any other external build tool.

@jeromecoupe
Copy link

Sure @veleek, sorry if I came across as not supporting the feature request. Was just detailing an approach that would sidestep the need for a delay.

@veleek
Copy link
Contributor Author

veleek commented Apr 6, 2020

:) No worries, that's not what I thought you were trying to do. I just wish I'd know how easy it was to do it your way before!

@jeromecoupe
Copy link

As a side note, setting the shell option to true with child process. Might be worth a try to dispense with the cross.spawn package

const cp = require("child_process");

// Eleventy
function eleventyBuild() {
  return cp.spawn("npx", ["eleventy", "--quiet"], {
    stdio: "inherit", shell: true
  });
}

@veleek
Copy link
Contributor Author

veleek commented Apr 10, 2020

Aaaaaah, so THAT'S how you do it! Thanks.

@zachleat
Copy link
Member

Note also that this was included to solve a few problems in --incremental, not specifically for this gulp issue. Two birds, one stone!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug: lite Debatable whether or not this is a bug. I mean, it’s not great but it’s not really broken either. enhancement
Projects
None yet
5 participants