FredKSchott / snowpack

ESM-powered frontend build tool. Instant, lightweight, unbundled development. ✌️
https://www.snowpack.dev
MIT License
19.5k stars 919 forks source link

[BUG] plugin-run-script not waiting for eleventy to finish during build #3095

Open andreasphil opened 3 years ago

andreasphil commented 3 years ago

Bug Report Quick Checklist

Describe the bug

Hello! I'm building a small site with 11ty and Snowpack based on app-template-11ty. The only change I made to the template is to add the eleventy output in _output to .gitignore, because I prefer not to commit auto generated files.

Everything works fine during development.

When I deploy the page all eleventy generated files are missing from the result. I noticed that @snowpack/plugin-run-script doesn't seem to execute eleventy during snowpack build. I do get a log output [snowpack] starting eleventy run() workers, but the contents of _output remain unchanged, i.e. remain in whatever state they were when I last ran snowpack dev.

To Reproduce

  1. npx create-snowpack-app 11ty-test --template @snowpack/app-template-11ty
  2. rm -r _output
  3. snowpack build
  4. Result: build only contains_snowpack and dist folders, but no eleventy stuff

Expected behavior

snowpack build should behave like snowpack dev and run eleventy.

Anything else?

The description of the plugin and this issue suggest that the above indeed the intended behavior. What confuses me a bit is that if that's true, why include _output in the template repository in the first place?

Workaround: Changing the npm build script to eleventy && snowpack build


Either way thanks for all the work you put into this, all in all snowpack is a joy to use! ☺️

chrisparsons83 commented 3 years ago

I'm running into this error too, though I discovered it through building from scratch. I can indeed recreate this with the above steps though.

I'd add one correction that might illuminate the possible solution though. On step 2, you don't need to actually remove rm -r _output, you can just empty the folder and leave it there. The result will be the same.

What's looking to be happening is the eleventy compilation is finishing after snowpack is done, so the eleventy files eventually end up there, but Snowpack is already done with its work and isn't waiting on eleventy to be finished. If you were to run snowpack build twice, it would work as the eleventy files would have been built as well from the first build.

Also, seconding the "snowpack is a joy to use!" sentiment.

andreasphil commented 3 years ago

Thanks for sharing @chrisparsons83! You're right, eleventy does seem to run. I tried it again a few times since posting and I always get one of the following results on the first run (i.e. when _output is empty like you suggested, or doesn't exist at all):

  1. Eleventy doesn't produce any output at all
  2. Eleventy produces some incomplete output
  3. It actually works (but happens very rarely, the other two are the most common)

On the second run, it's usually (3), but sometimes still (2). I should add that it's a small site with few dependencies at this point, so both Snowpack and eleventy are done very very quickly.

I agree that sounds like a race condition where Snowpack doesn't wait for eleventy to finish, so you'll get whatever happens to be in _output at the time the build process reaches that stage.

willans commented 3 years ago

I was trying to get to the bottom of a potentially similar bug after looking at a different starter project while rolling my own. And I ended up here.

I found the culprit to be the version of snowpack. Up to version 3.0.13 worked fine. 3.1.x, 3.2.x stopped it working as expecting (in my situation, it was still compiling 11ty files, but wouldn't live reload).

andreasphil commented 3 years ago

@willans Good catch! Can confirm downgrading to 3.0.13 does the trick for me.

I did some digging through the diffs since v3.0.13. As far as I can tell the logic for building has since been moved from commands/build.ts to commands/dev.ts. The older version of build had this bit below the plugin execution (runJob is the promise returned by the plugin):

// Wait for the job to complete before continuing (unless in watch mode)
if (!isDev) {
  await runJob;
}

This or something equivalent is missing from the current version of dev.ts, which seems to cause the behavior I observed, and perhaps the issues others have reported as well.

I tried the naive fix of just adding it again in dev.ts here. But that leads to other troubles with mounting later on in the build pipeline:

[20:34:47] [snowpack] ! clearing cache...
[20:34:47] [eleventy] Copied 1 file / Wrote 4 files in 0.13 seconds (v0.12.1)
[20:34:47] [eleventy] Command completed.
[20:34:47] [snowpack] ! building files...
[20:34:47] [snowpack] Not Found (/index.html)
[20:34:47] [snowpack] Error: Not Found (/index.html)
    at Object.loadUrl (/Users/andreas/Projects/snowpack/snowpack/lib/commands/dev.js:534:23)
    at flushFileQueue (/Users/andreas/Projects/snowpack/snowpack/lib/commands/build.js:148:44)
    at build (/Users/andreas/Projects/snowpack/snowpack/lib/commands/build.js:176:11)
    at async Object.command (/Users/andreas/Projects/snowpack/snowpack/lib/commands/build.js:261:9)
    at async cli (/Users/andreas/Projects/snowpack/snowpack/lib/index.js:172:9)

index.html is in output, which is mounted to /, so it should be there. Haven't found the time yet to wrap my head around how mounting works under the hood but I'd be happy to give this a try. If anyone can point me in the right direction though that'd be greatly appreciated 😀

ojdx commented 3 years ago

not a fix for this but another workaround is to add this to the package.json

"prestart": "npx @11ty/eleventy --watch &",
"start": "snowpack dev",
"prebuild": "npx @11ty/eleventy",
"build": "snowpack build",
poupryc commented 3 years ago

Same issue here with a from-scratch project using eleventy. Downgrading snowpack to 3.0.x did the trick for me. I have to say that this is a rather worrying issue and fortunately I came across this bug.

andreasphil commented 3 years ago

Quick update: I managed to resolve the mounting error I mentioned above by delaying mounting until after the plugins have finished (here). I'm not sure if this fix will work for all plugins because I don't know if plugins can make use of mounting themselves, but I didn't see anything so far.

That solves the snowpack build issue for me in the case of my simple project as well as in the 11ty app template.

However after updating my fork with the latest version from upstream I now have a similar problem with snowpack dev. First time I start the dev server with an empty output folder, no eleventy output will work until I restart the server.

I have the same behavior in my website project with the unchanged snowpack version, so it isn't caused by my changes. With 3.2.2 everything is fine with snowpack dev, so this must have happened somewhere between 3.2.2 and the current latest version 3.3.5. So that's what I'll have a look at next ...

davidbwaters commented 3 years ago

Quick update: I managed to resolve the mounting error I mentioned above by delaying mounting until after the plugins have finished (here). I'm not sure if this fix will work for all plugins because I don't know if plugins can make use of mounting themselves, but I didn't see anything so far.

That solves the snowpack build issue for me in the case of my simple project as well as in the 11ty app template.

However after updating my fork with the latest version from upstream I now have a similar problem with snowpack dev. First time I start the dev server with an empty output folder, no eleventy output will work until I restart the server.

I have the same behavior in my website project with the unchanged snowpack version, so it isn't caused by my changes. With 3.2.2 everything is fine with snowpack dev, so this must have happened somewhere between 3.2.2 and the current latest version 3.3.5. So that's what I'll have a look at next ...

would love to see this working with dev

davidbwaters commented 3 years ago

This issue is clear on dev in my repo also. Reload works with the index, but if you edit a page with shortcodes like content/work/fitbux, http://localhost:8080/work/fitbux does not reload to reflect changes clear in build output, even with workaround, around rerunning the command is only option.

edit: sorry, forgot to link repo https://github.com/davidbwaters/mainello i've since worked around based on suggestion from the 11st-starter repo's issue on this and use browsersync serving and just build assets with snowpack. my old failing setup is can be tested using the package.json.old and snowpack.config.old and the workaround is in my current setup