On a second thought, I also don't understand why do npm in two different images, why not just copy the webpack bundles from the builder image into the nginx image ?
For me the cause of the big image size was in
COPY --from=npmpackages /app /app
From your third Dockerfile, it seems replacing the above with the following would have done the trick without adding an extra stage
COPY --from=npmpackages /app/_site/ /usr/share/nginx/html/