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 beforeBuild and afterBuild events #1143

Merged
merged 1 commit into from
Jun 2, 2020

Conversation

Snugug
Copy link
Contributor

@Snugug Snugug commented May 1, 2020

While looking for a way to run code after a build has completed, either from watch or from a normal build, I came across beforeWatch code in the codebase. This extends that pattern to output beforeBuild and afterBuild events, too. Usecase for afterBuild is to trigger events only after Eleventy has run, for instance live reloading from a third-party server, or building a search index.

I'm also going to make a corresponding PR 11ty-website to document this functionality and beforeWatch (#1042)

@georges-gomes
Copy link

Would be nice to have this to avoid being depend on gulp or other build tools.

But it seems that the promise (let promise = this.writer.write(); ) is resolve before all the files are physically written to disk.

For example in watch I have
Watching… Writing 'file' from 'file'.
And Console.log('Watching...') is done after write await.

I did had time to investigated yet but wanted to report.
Maybe @zachleat can confirm/deny.

@zachleat zachleat merged commit d3dfcec into 11ty:master Jun 2, 2020
@zachleat
Copy link
Member

zachleat commented Jun 2, 2020

Thank you!

@zachleat zachleat added this to the Eleventy v1.0.0 milestone Jun 2, 2020
@zachleat
Copy link
Member

zachleat commented Jun 2, 2020

@georges-gomes seems ok here?

image

image

@georges-gomes
Copy link

Can't reproduce. Looks good thanks 👍

@MoritzLost
Copy link

MoritzLost commented Sep 4, 2020

Hey everyone, I'm currently trying to build some functionality using the afterBuild event, but what I'm missing is how to do some post-processing on files generated during the build. In particular, how do I access the directory options like the output directory inside an event listener? I'm currently trying to get some functionality working that needs to find some of the generated files in the output directory and generate some additional files. As far as I can tell, the event listener only has access to the eleventyConfig object, and that doesn't include the dir options from the configuration.

Maybe the afterBuild event should receive an argument with information on the finished build (the output directory would suffice, actually)? Is that even possible? Or is there a better approach to write some reusable functionality that is guaranteed to run after every other file has been generated (this is why I can't just use a normal template) and has access to the build directory?

@lasar
Copy link

lasar commented Sep 4, 2020

The way I understand it you define your afterBuild event inside your .eleventy.js file, which is also where you set the output directory.

(Untested) example code cobbled together from snippets in the documentation:

module.exports = function(eleventyConfig) {
  let myConfig = {
    dir: {
      output: "_my_site_dir"
    }
  };

  eleventyConfig.on('afterBuild', () => {
    console.log('You can now work on', myConfig.dir.output);
  });

  return myConfig;
};

I don't know how you'd figure out the output directory if you stick to the default. It's defined as _site in node_modules/@11ty/eleventy/src/defaultConfig.js but I don't know how you'd (properly) retrieve that information.

@MoritzLost
Copy link

@lasar Thanks! That will definitely work in a project setting. But what about plugins? Each plugin has it's own .eleventy.js, so in a plugin the config defined in the project's .eleventy.js would not be accessible. Of course it would be possible to make the plugin configurable with that information, so the importer would have to pass the output path to the plugin. But it would be cool if that stuff could be somehow retreived from eleventy in the afterBuild callback, or passed to it.

@georges-gomes
Copy link

I'm also struggling with the use of afterBuild.

I agree, the output dir is quite important for a afterBuild event.
Passing the eleventyConfig to the afterBuild would solve this issue and maybe other in the future.

Another challenge for the use of afterBuild is that it is asynchronous. In case of --watch the browser is reloaded before the processing required in afterBuild is finished. I think the event model is not good for what we want to do here.

@zachleat what would be the perfect way to create these "pre-build" and "post-build" synchronous "hooks" ? I really want them, I can contribute, but I don't want to waist my time (and yours :D) going in the wrong direction.

@Ryuno-Ki
Copy link
Contributor

@MoritzLost @georges-gomes I'd suggest to fill a new issue with these requests.
I doubt, a merged PR will work as a good reminder ;-)

@zachleat zachleat modified the milestones: Planning for Eleventy v1.0.0, Eleventy v0.11.1 Oct 22, 2020
@zachleat
Copy link
Member

Swapping to ship this with 0.11.1.

We’ll look a little closer at running async/sync hooks with 1.0. Some work for this has been completed at #1359 if you’d like to follow along there!

@georges-gomes
Copy link

Awesome, thanks @zachleat subscribed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants