Skip to content

[adapter-vercel] Page visits return 500: INTERNAL_SERVER_ERROR possibly due to missing modules that are marked as external for esbuild #4247

Closed

Description

@kelvindecosta

Describe the bug

When using a module that doesn't play well with esbuild, (eg: html-minifier), deploying to Vercel is technically successful but results in failing page visits.

In my case, I've used the html-minifier package to write a simple handle hook that minifies html.

The deploys were previously showing warnings that certain relative paths needed to be marked as external for esbuild.
All of these warnings had ties to uglify-js, a dependency of html-minifier.
These warnings disappeared when html-minifier was marked as external

Reproduction

Here is a link to a reproduction.

Here are the steps I took to create the reproduction:

  • Start with default skeleton with all extras enabled.
  • Install html-minifier and create a simple handle hook that minifies html.
    At this point, I got the following warnings on Vercel:
Warnings on Vercel deployment log
▲ [WARNING] "../lib/utils.js" should be marked as external for use with "require.resolve"

    node_modules/.pnpm/uglify-js@3.15.2/node_modules/uglify-js/tools/node.js:4:20:
      4 │     require.resolve("../lib/utils.js"),
        ╵                     ~~~~~~~~~~~~~~~~~

▲ [WARNING] "../lib/ast.js" should be marked as external for use with "require.resolve"

    node_modules/.pnpm/uglify-js@3.15.2/node_modules/uglify-js/tools/node.js:5:20:
      5 │     require.resolve("../lib/ast.js"),
        ╵                     ~~~~~~~~~~~~~~~

▲ [WARNING] "../lib/transform.js" should be marked as external for use with "require.resolve"

    node_modules/.pnpm/uglify-js@3.15.2/node_modules/uglify-js/tools/node.js:6:20:
      6 │     require.resolve("../lib/transform.js"),
        ╵                     ~~~~~~~~~~~~~~~~~~~~~

▲ [WARNING] "../lib/parse.js" should be marked as external for use with "require.resolve"

    node_modules/.pnpm/uglify-js@3.15.2/node_modules/uglify-js/tools/node.js:7:20:
      7 │     require.resolve("../lib/parse.js"),
        ╵                     ~~~~~~~~~~~~~~~~~

▲ [WARNING] "../lib/scope.js" should be marked as external for use with "require.resolve"

    node_modules/.pnpm/uglify-js@3.15.2/node_modules/uglify-js/tools/node.js:8:20:
      8 │     require.resolve("../lib/scope.js"),
        ╵                     ~~~~~~~~~~~~~~~~~

▲ [WARNING] "../lib/compress.js" should be marked as external for use with "require.resolve"

    node_modules/.pnpm/uglify-js@3.15.2/node_modules/uglify-js/tools/node.js:9:20:
      9 │     require.resolve("../lib/compress.js"),
        ╵                     ~~~~~~~~~~~~~~~~~~~~

▲ [WARNING] "../lib/output.js" should be marked as external for use with "require.resolve"

    node_modules/.pnpm/uglify-js@3.15.2/node_modules/uglify-js/tools/node.js:10:20:
      10 │     require.resolve("../lib/output.js"),
         ╵                     ~~~~~~~~~~~~~~~~~~

▲ [WARNING] "../lib/sourcemap.js" should be marked as external for use with "require.resolve"

    node_modules/.pnpm/uglify-js@3.15.2/node_modules/uglify-js/tools/node.js:11:20:
      11 │     require.resolve("../lib/sourcemap.js"),
         ╵                     ~~~~~~~~~~~~~~~~~~~~~

▲ [WARNING] "../lib/mozilla-ast.js" should be marked as external for use with "require.resolve"

    node_modules/.pnpm/uglify-js@3.15.2/node_modules/uglify-js/tools/node.js:12:20:
      12 │     require.resolve("../lib/mozilla-ast.js"),
         ╵                     ~~~~~~~~~~~~~~~~~~~~~~~

▲ [WARNING] "../lib/propmangle.js" should be marked as external for use with "require.resolve"

    node_modules/.pnpm/uglify-js@3.15.2/node_modules/uglify-js/tools/node.js:13:20:
      13 │     require.resolve("../lib/propmangle.js"),
         ╵                     ~~~~~~~~~~~~~~~~~~~~~~

▲ [WARNING] "../lib/minify.js" should be marked as external for use with "require.resolve"

    node_modules/.pnpm/uglify-js@3.15.2/node_modules/uglify-js/tools/node.js:14:20:
      14 │     require.resolve("../lib/minify.js"),
         ╵                     ~~~~~~~~~~~~~~~~~~

▲ [WARNING] "./exports.js" should be marked as external for use with "require.resolve"

    node_modules/.pnpm/uglify-js@3.15.2/node_modules/uglify-js/tools/node.js:15:20:
      15 │     require.resolve("./exports.js"),
         ╵                     ~~~~~~~~~~~~~~
  • Install the adapter-vercel and specify html-minifier as an external module.

Logs

Here's an example log for functions that are invoked when a user visits the deployed site:

ERROR	Cannot find module 'html-minifier'
      Did you forget to add it to "dependencies" in `package.json`?
      Runtime exited with error: exit status 1

System Info

System:
    OS: Linux 5.10 Manjaro Linux
    CPU: (8) x64 Intel(R) Core(TM) i7-4700HQ CPU @ 2.40GHz
    Memory: 2.90 GB / 15.52 GB
    Container: Yes
    Shell: 5.8 - /usr/bin/zsh
  Binaries:
    Node: 14.18.1 - ~/.nvm/versions/node/v14.18.1/bin/node
    Yarn: 1.22.10 - ~/.nvm/versions/node/v14.18.1/bin/yarn
    npm: 6.14.15 - ~/.nvm/versions/node/v14.18.1/bin/npm
  Browsers:
    Brave Browser: 96.1.32.115
    Firefox: 95.0
  npmPackages:
    @sveltejs/adapter-vercel: next => 1.0.0-next.46 
    @sveltejs/kit: next => 1.0.0-next.294 
    svelte: ^3.46.4 => 3.46.4

Severity

blocking an upgrade

Additional Information

I think I might be missing some configuration.

Any help is appreciated!
Thank you for your time!

Activity

  1. added this to the 1.0 milestone on Mar 6, 2022
  2. removed this from the 1.0 milestone on Mar 16, 2022
  3. benmccann commented on Mar 16, 2022

    @benmccann
    Member

    I've used the html-minifier package to write a simple handle hook that minifies html.

    This seems unlikely to me to be a performance enhancement if you're doing it at runtime. I'd recommend doing it only during prerendering as demonstrated here: https://kit.svelte.dev/docs/migrating#integrations-html-minifier

  4. kelvindecosta commented on Mar 20, 2022

    @kelvindecosta
    Author

    Hey @benmccann

    Thank you for sharing that snippet!

    I've realized that minifying all HTML responses may not be ideal.
    Like you suggested, I've set the hook to run only during pre-rendering like so:

    import { Handle } from '@sveltejs/kit';
    import { sequence } from '@sveltejs/kit/hooks';
    import { minify } from 'html-minifier';
    
    import { prerendering } from '$app/env';
    
    const minifyHtml: Handle = async ({ event, resolve }) =>
      await resolve(event, {
        transformPage: ({ html }) =>
          prerendering
            ? minify(html, {
                collapseBooleanAttributes: true,
                collapseWhitespace: true,
                decodeEntities: true,
                minifyCSS: true,
                minifyJS: true,
                removeAttributeQuotes: true,
                removeComments: true,
                removeRedundantAttributes: true,
                removeScriptTypeAttributes: true,
                removeStyleLinkTypeAttributes: true,
                sortAttributes: true,
                sortClassName: true
              })
            : html
      });
    
    export const handle = sequence(minifyHtml);

    Now, prerendered pages are minified as expected and work flawlessly!

    Unfortunately, the issue still exists, and pages that are not prerendered return 500: INTERNAL_SERVER_ERROR.

    My guess is that packages that don't work well with vite / esbuild, like uglify-js (a dependency of html-minifier), are causing the issue.
    In my case I had to add html-minifier to adapter-vercel's external to stop build errors.

    Is there a way to bundle these dependencies for adapter-vercel?

    Thank you again for your help with this issue!

  5. homerjam commented on Apr 23, 2022

    @homerjam

    Did you get anywhere with this? I have the same issue, an "external" dependency not found, using sveltekit/vercel/pnpm. In my case I'm external-ising svg2img which loads a .node file (unsupported by esbuild afaik). Also of possible importance - I'm getting this problem in an endpoint.

  6. Rich-Harris commented on May 17, 2022

    @Rich-Harris
    Member

    This will hopefully be fixed by #4969

  7. Rich-Harris commented on Jul 15, 2022

    @Rich-Harris
    Member

    Going to assume this was fixed by #4969 and close it — feel free to open a new issue if it's still happening with current versions of everything

  8. kelvindecosta commented on Jul 17, 2022

    @kelvindecosta
    Author

    I can confirm that this issue is resolved!
    Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions