11ty / eleventy

A simpler site generator. Transforms a directory of templates (of varying types) into HTML.
https://www.11ty.dev/
MIT License
17.28k stars 495 forks source link

`TemplateWriterWriteError` was thrown #1569

Closed kylesloper closed 2 years ago

kylesloper commented 3 years ago

I keep receiving this error in the cli:

TemplatePassthroughManagerCopyError was thrown

EPERM: operation not permitted, open 'C:\Users\kyles\Desktop\moonface\ _site\static\img\715580bf-9f2c-4e74-b0c5-7649f02ebfa1.webm'

..

Error: EPERM: operation not permitted, open 'C:\Users\kyles\Desktop\moonface\ _site\static\img\715580bf-9f2c-4e74-b0c5-7649f02ebfa1.webm'

Windows 10

tannerdolby commented 3 years ago

What extension is .webm? Is that a valid image format? Maybe you meant to have .webp.

Also, can you include the code from your Eleventy Config file where you are attempting to use passthroughCopy or similar to help us better understand the root of the issue.

kylesloper commented 3 years ago

webm is web optimised video file format. Is this not required?

Sure here it is:

const { DateTime } = require("luxon");
const CleanCSS = require("clean-css");
const UglifyJS = require("uglify-es");
const htmlmin = require("html-minifier");
const eleventyNavigationPlugin = require("@11ty/eleventy-navigation");

module.exports = function(eleventyConfig) {

  // Eleventy Navigation https://www.11ty.dev/docs/plugins/navigation/
  eleventyConfig.addPlugin(eleventyNavigationPlugin);

  // Configuration API: use eleventyConfig.addLayoutAlias(from, to) to add
  // layout aliases! Say you have a bunch of existing content using
  // layout: post. If you don’t want to rewrite all of those values, just map
  // post to a new file like this:
  // eleventyConfig.addLayoutAlias("post", "layouts/my_new_post_layout.njk");

  // Merge data instead of overriding
  // https://www.11ty.dev/docs/data-deep-merge/
  eleventyConfig.setDataDeepMerge(true);

  // Add support for maintenance-free post authors
  // Adds an authors collection using the author key in our post frontmatter
  // Thanks to @pdehaan: https://github.com/pdehaan
  eleventyConfig.addCollection("authors", collection => {
    const blogs = collection.getFilteredByGlob("posts/*.md");
    return blogs.reduce((coll, post) => {
      const author = post.data.author;
      if (!author) {
        return coll;
      }
      if (!coll.hasOwnProperty(author)) {
        coll[author] = [];
      }
      coll[author].push(post.data);
      return coll;
    }, {});
  });

  // Date formatting (human readable)
  eleventyConfig.addFilter("readableDate", dateObj => {
    return DateTime.fromJSDate(dateObj).toFormat("dd LLL yyyy");
  });

  // Date formatting (machine readable)
  eleventyConfig.addFilter("machineDate", dateObj => {
    return DateTime.fromJSDate(dateObj).toFormat("yyyy-MM-dd");
  });

  // Minify CSS
  eleventyConfig.addFilter("cssmin", function(code) {
    return new CleanCSS({}).minify(code).styles;
  });

  // Minify JS
  eleventyConfig.addFilter("jsmin", function(code) {
    let minified = UglifyJS.minify(code);
    if (minified.error) {
      console.log("UglifyJS error: ", minified.error);
      return code;
    }
    return minified.code;
  });

  // Minify HTML output
  eleventyConfig.addTransform("htmlmin", function(content, outputPath) {
    if (outputPath.indexOf(".html") > -1) {
      let minified = htmlmin.minify(content, {
        useShortDoctype: true,
        removeComments: true,
        collapseWhitespace: true
      });
      return minified;
    }
    return content;
  });

  // Don't process folders with static assets e.g. images
  eleventyConfig.addPassthroughCopy("favicon.ico");
  eleventyConfig.addPassthroughCopy("admin");
  eleventyConfig.addPassthroughCopy("static");
  eleventyConfig.addPassthroughCopy("_redirects");
  eleventyConfig.addPassthroughCopy("_includes/assets/");
  eleventyConfig.addPassthroughCopy("email");

  /* Markdown Plugins */
  let markdownIt = require("markdown-it");
  let markdownItAnchor = require("markdown-it-anchor");
  let options = {
    html: true,
    breaks: true,
    linkify: true
  };
  let opts = {
    permalink: false
  };

  eleventyConfig.setLibrary("md", markdownIt(options)
    .use(markdownItAnchor, opts)
  );

  return {
    templateFormats: ["md", "njk", "html", "liquid"],

    // If your site lives in a different subdirectory, change this.
    // Leading or trailing slashes are all normalized away, so don’t worry about it.
    // If you don’t have a subdirectory, use "" or "/" (they do the same thing)
    // This is only used for URLs (it does not affect your file structure)
    pathPrefix: "/",

    markdownTemplateEngine: "liquid",
    htmlTemplateEngine: "njk",
    dataTemplateEngine: "njk",
    dir: {
      input: ".",
      includes: "_includes",
      data: "_data",
      output: "_site"
    }
  };
};
tannerdolby commented 3 years ago

Ah, yes I forgot about .webm. Since that is a valid format for video files, the issue must be caused by something else. I will take a look at your Config file later today and see if I can find anything.

pdehaan commented 3 years ago

Random Q, but does C:\Users\kyles\Desktop\moonface_site\static\img\715580bf-9f2c-4e74-b0c5-7649f02ebfa1.webm exist on your computer? That "EPERM" generally means it's a permissions issue. But I'm unsure if its because you don't have a "moonface_site" directory on your desktop or if the Node process doesn't have the correct permissions for that folder (which is odd).

I found this, but not sure how relevant it is (since I don't use Win10, but there are some lovely screenshots of permissions dialog windows): https://stackoverflow.com/questions/34600932/npm-eperm-operation-not-permitted-on-windows

I didn't see anything obviously wrong with the .eleventy.js config file, although not sure if it's be easier to separate the input and output directories so the output directory isn't nested within input -- but hard to imagine that'd cause this specific issue.

If you can push the "./moonface_site/" directory on GitHub, I can try building it locally on macOS and see if it's an eleventy/config issue or a Windows-vs-everything issue.

kylesloper commented 3 years ago

Random Q, but does C:\Users\kyles\Desktop\moonface_site\static\img\715580bf-9f2c-4e74-b0c5-7649f02ebfa1.webm exist on your computer? That "EPERM" generally means it's a permissions issue. But I'm unsure if its because you don't have a "moonface_site" directory on your desktop or if the Node process doesn't have the correct permissions for that folder (which is odd).

I found this, but not sure how relevant it is (since I don't use Win10, but there are some lovely screenshots of permissions dialog windows): https://stackoverflow.com/questions/34600932/npm-eperm-operation-not-permitted-on-windows

I didn't see anything obviously wrong with the .eleventy.js config file, although not sure if it's be easier to separate the input and output directories so the output directory isn't nested within input -- but hard to imagine that'd cause this specific issue.

If you can push the "./moonface_site/" directory on GitHub, I can try building it locally on macOS and see if it's an eleventy/config issue or a Windows-vs-everything issue.

Yes, the file exists although the folder structure is moonface/_site for some reason the slash is being removed in markdown.

I think the stack article you linked is an error with Mkdir but I'll give it a read.

Sure here is the MoonFace repo

An important thing to mention is that this issue is not persistent and only occurs every now and then. For example right now I am not receiving any error.

pdehaan commented 3 years ago

Worked for me on macOS with a few tweaks:

diff --git a/package.json b/package.json
index 02e6027..29a73b2 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,6 @@
 {
-  "name": "MoonFace | Sites for Creatives",
+  "name": "moonface",
+  "title": "MoonFace | Sites for Creatives",
   "version": "1.0.3",
   "description": "MoonFace is a design studio, building stunning sites for creatives of every kind.",
   "scripts": {
@@ -21,9 +22,12 @@
     "url": "https://github.com/kylesloper/moonface/issues"
   },
   "dependencies": {
+    "@11ty/eleventy": "^0.11.1",
     "@11ty/eleventy-navigation": "^0.1.6",
     "clean-css": "^4.2.1",
     "html-minifier": "^4.0.0",
+    "markdown-it": "^12.0.4",
+    "markdown-it-anchor": "^7.0.0",
     "netlify-cli": "^2.70.0",
     "uglify-es": "^3.3.9"
   }
> moonface@1.0.3 build /private/tmp/moonface
> npx eleventy

Writing _site/accessibility/index.html from ./accessibility.html.
Writing _site/login/index.html from ./login.html.
Writing _site/admin/index.html from ./admin/index.html.
Writing _site/authors/john-appleseed/index.html from ./author.njk.
Writing _site/authors/index.html from ./authors.njk.
Writing _site/tags/christmas/index.html from ./tags.njk.
Writing _site/index.html from ./pages/home.md.
Writing _site/works/index.html from ./pages/about.md.
Writing _site/chat/index.html from ./pages/chat.md.
Writing _site/migrating-from-a-website-builder/index.html from ./pages/migrating-to-moonface.md.
Writing _site/nonprofits/index.html from ./pages/nonprofits.md.
Writing _site/privacy/index.html from ./pages/privacy-policy.md.
Writing _site/status/index.html from ./pages/site-status.md.
Writing _site/blog/index.html from ./pages/blog.md.
Writing _site/pay/index.html from ./pages/pay.md.
Writing _site/rates/index.html from ./pages/rates.md.
Writing _site/posts/christmas-wishes-from-moonface/index.html from ./posts/christmas-wishes-from-moonface.md.
Writing _site/posts/this-is-the-first-example-post/index.html from ./posts/firstpost.md.
Writing _site/posts/this-is-the-fourth-example-post/index.html from ./posts/fourthpost.md.
Writing _site/posts/our-covid-19-response/index.html from ./posts/our-covid-19-response.md.
Writing _site/posts/the-fifth-and-hopefully-final-example-post/index.html from ./posts/the-fifth-and-hopefully-final-example-post.md.
Writing _site/posts/this-is-the-second-example-post/index.html from ./posts/secondpost.md.
Writing _site/posts/this-is-the-third-example-post-which-has-a-slightly-longer-title-than-the-others/index.html from ./posts/thirdpost.md.
Writing _site/404.html from ./404.md.
Writing _site/authors/jane-doe/index.html from ./author.njk.
Writing _site/tags/tech/index.html from ./tags.njk.
Writing _site/authors/the-moonface-team/index.html from ./author.njk.
Writing _site/tags/environment/index.html from ./tags.njk.
Writing _site/authors/john-doe/index.html from ./author.njk.
Writing _site/tags/politics/index.html from ./tags.njk.
Writing _site/tags/sports/index.html from ./tags.njk.
Writing _site/tags/Covid-19/index.html from ./tags.njk.
Writing _site/tags/sport/index.html from ./tags.njk.
Writing _site/tags/authors/index.html from ./tags.njk.
Benchmark (Configuration): "cssmin" Nunjucks Filter took 376ms (25.3%, called 31×, 12.1ms each)
Benchmark (Configuration): "jsmin" Nunjucks Filter took 341ms (23.0%, called 31×, 11.0ms each)

Copied 39 files / Wrote 34 files in 1.28 seconds (37.6ms each, v0.11.1)
pdehaan commented 3 years ago

But none of the tweaks I made would explain the EPERM error you were getting (they just prevented me from running npm install and building the repo locally).

My guess is that it's whatever is thinking you're wanting to write to "moonface_site" instead of "moonface_site".

The most concerning was this though:

"An important thing to mention is that this issue is not persistent and only occurs every now and then. For example right now I am not receiving any error."

Not sure why this would only happen intermittently, unless you're using --watch or --serve and that's somehow related.

Ryuno-Ki commented 3 years ago

Matches my experience with Windows setups, that EPERM errors often get away after a few attempts.

zachleat commented 2 years ago

Is this one still valid or causing a problem?

kylesloper commented 2 years ago

Haven't ran into it recently Zach :)

zachleat commented 2 years ago

Good to know! Let me know if it crops back up!