11ty / eleventy

A simpler site generator. Transforms a directory of templates (of varying types) into HTML.

Home Page:https://www.11ty.dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Eleventy serverless generated function will not include all dependencies from package.json

omoki opened this issue · comments

commented

I had trouble deploying eleventy serverless functions due to the fact a module (firebase-admin) was missing from the generated functions folder. The culprit was the eleventy generated file called eleventy-app-config-modules.js It looks like any require statements that reside within the source directory or .eleventy.js will receive an entry into this file require statements.

I also learned that netlify will not install all dependencies from the top-level package.json, but rather, look for require statements within the functions folder. This is the reason why firebase-admin wasn't getting installed during deploy at least within the functions folder.

I ended up putting a require statement at the top of the .eleventy.js file. And eleventy generated require statements for these dependencies within the aforementioned file.

This may or may not be a bug. It looks like the generated file includes even the packages that are not needed for the function. So perhaps it might be better to simply parse the package.json file for dependencies rather than to go through the source folder? In any case, I think documentation of this fact would be very helpful.

For more information, please see discord thread: Netlify Function + Firebase Admin Investigations!

commented

Looking at my .eleventy.js, I created an entry for copy like so:

    eleventyConfig.addPlugin(EleventyServerlessBundlerPlugin, {
      name: "members",
      functionsDir: "./netlify/functions",
      copy: ['utils/firebase'] // <!--- this is the folder which resides outside of the source folder
    });

Since I specified the directory to copy in the config, perhaps the generator could include these files before producing the require statements.

There is a hard 50MB AWS limit on these serverless functions, which is why a bundler is used to determine the subset of dependencies used. If everything was bundled automatically, it’d hit that limit so quickly. Rather than adding the require() dep to your .eleventy.js file I believe you can also put it in your serverless function file too index.js.

Another option here is to use the esbuild bundler instead: https://www.netlify.com/blog/2021/04/02/modern-faster-netlify-functions/

commented

Thank you @zachleat. I think it would be helpful to document how the generator requires packages. I might be wrong here, but right now, by default, eleventyConfig.addPlugin seems to copy the entire source directory to the functions directory and requires all packages in the source directory and .eleventy.js. I see the following config options from the eleventy repo:

 options = Object.assign(
    {
      name: "",
      functionsDir: "./functions/",
      copy: [],

      // https://www.npmjs.com/package/recursive-copy#usage
      copyOptions: {},

      // Dependencies explicitly declared from configuration and global data can be excluded and hidden from bundler.
      // Excluded from: `eleventy-app-config-modules.js` and `eleventy-app-globaldata-modules.js`
      excludeDependencies: [],

      // Add automated redirects (appends or creates, avoids duplicate entries)
      // Also accepts a custom callback function(name, outputMap)
      redirects: "netlify-toml",

      // Useful for local develop to disable all bundle copying
      copyEnabled: true,
    },
    options
  );

Having two additional options may be helpful:

  1. includeDependencies -- to only include specific dependencies
  2. ignoreDir or includeDir -- not sure if this is the best way, but when the source gets bigger, then it might come useful

I think the main question about the serverless function is whether you want the users to mainly rely on the generated function (which work well for simple endpoints). But I suppose this wouldn't be an issue if I simply wanted to copy over the generated function and modify it for my needs.

Anyway, now that I've resolved my issue, the serverless function is working very well. So thanks for implementing this feature!

commented

One more thing: putting the require statement within serverless function's index.js fails when deploying to netlify with module not found error. In fact, I know this because I've tried this as part of my solution before learning about the eleventy generated eleventy-app-config-modules.js file. Is it possible that eleventy is removing this during build? As instructed, I've added lines into my .gitignore so that index.js is the only thing committed to the repo in the functions directory.

Hey, I believe this is the same issue as #2288, which was fixed for the upcoming 2.0.0-canary.5!

We will bundle deps declared in your config file and template/directory data files starting in 2.0.0-canary.5.

Thank you!