builder icon indicating copy to clipboard operation
builder copied to clipboard

"isolated-vm import error" on Vercel with Nuxt

Open 20x-dz opened this issue 9 months ago • 8 comments

Describe the bug I see the following errors in the Vercel log after visiting a builder.io page (the page seems to render fine though):

[Builder.io]:  isolated-vm import error. Error: Cannot find module 'isolated-vm'
Require stack:
- /var/task/node_modules/@builder.io/sdk-vue/lib/node/index-551oCh4n.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1140:15)
    at Module._load (node:internal/modules/cjs/loader:981:27)
    at /opt/rust/nodejs.js:1:11508
    at Function.Qt (/opt/rust/nodejs.js:1:11878)
    at Q.e.<computed>.K._load (/opt/rust/nodejs.js:1:11478)
    at Module.require (node:internal/modules/cjs/loader:1231:19)
    at require (node:internal/modules/helpers:177:18)
    at getIvm (file:///var/task/node_modules/@builder.io/sdk-vue/lib/node/index-551oCh4n.js:318:15)
    at runInNode (file:///var/task/node_modules/@builder.io/sdk-vue/lib/node/index-551oCh4n.js:350:13)
    at chooseBrowserOrServerEval (file:///var/task/node_modules/@builder.io/sdk-vue/lib/node/index-551oCh4n.js:391:108) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/var/task/node_modules/@builder.io/sdk-vue/lib/node/index-551oCh4n.js'
  ]
}

followed by

[Builder.io]:  Failed code evaluation: [Builder.io]: could not import `isolated-vm` module for safe script execution on Node server.
    
    In certain Node environments, the SDK requires additional initialization steps. This can be achieved by 
    importing and calling `initializeNodeRuntime()` from "@builder.io/sdk-react/node/init". This must be done in
    a server-only execution path within your application.

    Please see the documentation for more information: https://builder.io/c/docs/integration-tips#enabling-data-bindings-in-node-environments
     {
  code: 'var __awaiter=function(e,t,n,r){return new(n||(n=Promise))((function(i,o){function a(e){try{c(r.next(e))}catch(e){o(e)}}function u(e){try{c(r.throw(e))}catch(e){o(e)}}function c(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,u)}c((r=r.apply(e,t||[])).next())}))},__generator=function(e,t){var n,r,i,o,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function u(o){return function(u){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(i=2&o[0]?r.return:o[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!(i=(i=a.trys).length>0&&i[i.length-1])&&(6===o[0]||2===o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]<i[3])){a.label=o[1];break}if(6===o[0]&&a.label<i[1]){a.label=i[1],i=o;break}if(i&&a.label<i[2]){a.label=i[2],a.ops.push(o);break}i[2]&&a.ops.pop(),a.trys.pop();continue}o=t.call(e,a)}catch(e){o=[6,e],r=0}finally{n=i=0}if(5&o[0])throw o[1];return{value:o[0]?o[1]:void 0,done:!0}}([o,u])}}};function main(){return __awaiter(this,void 0,void 0,(function(){var e,t,n;return __generator(this,(function(r){return Builder.isServer,Builder.isBrowser&&(e=document.getElementById("toggleSwitch"),t=document.getElementById("price"),n=document.getElementById("membership-link"),e.addEventListener("change",(function(){this.checked?(t.textContent="0000",n.href="https://example.com"):(t.textContent="0000",n.href="https://example.com")}))),[2]}))}))}var _virtual_index=main();return _virtual_index'
}

The link provided in the 2nd error message only provides a solution for Next.js (React), not for Nuxt (Vue).

To Reproduce Steps to reproduce the behavior:

  1. Visit our page
  2. see the errors in the log

Expected behavior No errors in the logs?

Screenshots image

Additional context Happens on @builder.io/sdk-vue v1.0.22 as well as v1.0.27 (latest version) on the current Nuxt3 release.

Our main page template ([...slug].vue) loading the content:

<template>
  <div>
    <div v-if="content || isPreviewing()">
      <Content
        model="page"
        :can-track="false"
        :content="content"
        :api-key="builderApiKey"
        :custom-components="REGISTERED_COMPONENTS" />
    </div>
  </div>
</template>

<script setup>
import { Content, fetchOneEntry, isPreviewing } from "@builder.io/sdk-vue";
import FaqItems from "~/components/block/FaqItems.vue";
import Drawer from "~/components/builder.io/Drawer.vue";
import { useCustomHead } from "~/composables/useCustomHead";

// Register your Builder components
const REGISTERED_COMPONENTS = [
  {
    canHaveChildren: false,
    component: FaqItems,
    inputs: [
      {
        name: "faqItems",
        required: true,
        type: "object",
      },
      {
        name: "title",
        type: "text",
      },
    ],
    name: "BlockFaqItems",
  },
  {
    canHaveChildren: true,
    component: Drawer,
    inputs: [
      {
        name: "id",
        required: true,
        type: "text",
      },
    ],
    name: "Drawer",
  },
];

const config = useRuntimeConfig();
const builderApiKey = ref(config.public.builderApiToken);
const isDev = import.meta.dev;
// the app url is also set to example.com on preview environments
const isStaging = config.public.appUrl === "https://example.com";

const route = useRoute();

// fetch builder content data
const { data: content } = await useAsyncData("builderData", () =>
  fetchOneEntry({
    apiKey: builderApiKey.value,
    model: "page",
    options: {
      includeUnpublished: isPreviewing() || isDev || isStaging,
    },
    userAttributes: {
      urlPath: route.path,
    },
  }),
);

if (content.value === null) {
  throw createError({
    fatal: true,
    statusCode: 404,
    statusMessage: "Page Not Found",
  });
}

useCustomHead({
  metaDescription: content.value.data.description,
  metaImage: {
    data: {
      attributes: {
        url: content.value.data.previewImage,
      },
    },
  },
  metaTitle: content.value.data.title,
});
</script>

20x-dz avatar May 10 '24 10:05 20x-dz

Thanks for filing. We will investigate and let you know when we have a fix.

samijaber avatar May 14 '24 15:05 samijaber

Sorry for the ping, any updates on this @samijaber ? Still seeing this logs even with the latest vue-sdk:

[Builder.io]:  isolated-vm import error. Error: Cannot find module 'isolated-vm'
Require stack:
- /var/task/node_modules/@builder.io/sdk-vue/lib/node/index-xwOams1O.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1145:15)
    at Module._load (node:internal/modules/cjs/loader:986:27)
    at /opt/rust/nodejs.js:1:11508
    at Function.$t (/opt/rust/nodejs.js:1:11878)
    at K.e.<computed>.J._load (/opt/rust/nodejs.js:1:11478)
    at Module.require (node:internal/modules/cjs/loader:1233:19)
    at Hook._require.Module.require (/var/task/node_modules/require-in-the-middle/index.js:167:34)
    at require (node:internal/modules/helpers:179:18)
    at getIvm (file:///var/task/node_modules/@builder.io/sdk-vue/lib/node/index-xwOams1O.js:314:15)
    at runInNode (file:///var/task/node_modules/@builder.io/sdk-vue/lib/node/index-xwOams1O.js:346:13) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/var/task/node_modules/@builder.io/sdk-vue/lib/node/index-xwOams1O.js'
  ]
}
[Builder.io]:  Failed code evaluation: [Builder.io]: could not import `isolated-vm` module for safe script execution on Node server.
    
    In certain Node environments, the SDK requires additional initialization steps. This can be achieved by 
    importing and calling `initializeNodeRuntime()` from "@builder.io/sdk-react/node/init". This must be done in
    a server-only execution path within your application.

    Please see the documentation for more information: https://builder.io/c/docs/integration-tips#enabling-data-bindings-in-node-environments
     {
  code: 'var __awaiter=function(t,e,n,r){return new(n||(n=Promise))((function(a,o){function i(t){try{u(r.next(t))}catch(t){o(t)}}function l(t){try{u(r.throw(t))}catch(t){o(t)}}function u(t){var e;t.done?a(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(i,l)}u((r=r.apply(t,e||[])).next())}))},__generator=function(t,e){var n,r,a,o,i={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return o={next:l(0),throw:l(1),return:l(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function l(o){return function(l){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(a=2&o[0]?r.return:o[0]?r.throw||((a=r.return)&&a.call(r),0):r.next)&&!(a=a.call(r,o[1])).done)return a;switch(r=0,a&&(o=[2&o[0],a.value]),o[0]){case 0:case 1:a=o;break;case 4:return i.label++,{value:o[1],done:!1};case 5:i.label++,r=o[1],o=[0];continue;case 7:o=i.ops.pop(),i.trys.pop();continue;default:if(!(a=(a=i.trys).length>0&&a[a.length-1])&&(6===o[0]||2===o[0])){i=0;continue}if(3===o[0]&&(!a||o[1]>a[0]&&o[1]<a[3])){i.label=o[1];break}if(6===o[0]&&i.label<a[1]){i.label=a[1],a=o;break}if(a&&i.label<a[2]){i.label=a[2],i.ops.push(o);break}a[2]&&i.ops.pop(),i.trys.pop();continue}o=e.call(t,i)}catch(t){o=[6,t],r=0}finally{n=a=0}if(5&o[0])throw o[1];return{value:o[0]?o[1]:void 0,done:!0}}([o,l])}}};function main(){var t,e,n,r,a;return __awaiter(this,void 0,void 0,(function(){var o,i;return __generator(this,(function(l){return Builder.isServer,Builder.isBrowser&&((o=null===(a=null===(r=null===(n=null===(e=null===(t=state.margit.data)||void 0===t?void 0:t.attributes)||void 0===e?void 0:e.avatar)||void 0===n?void 0:n.data)||void 0===r?void 0:r.attributes)||void 0===a?void 0:a.url)?(i="https://example.com".concat(o),console.log(i)):console.error("Avatar URL is not available")),[2]}))}))}var _virtual_index=main();return _virtual_index'
}

And builder support is not very helpful in this regard… 😅

20x-dz avatar Jul 11 '24 09:07 20x-dz

If it helps anyone: A workaround for me was to wrap the BuilderContent in <client-only></client-only>.

Crease29 avatar Jul 15 '24 06:07 Crease29

If it helps anyone: A workaround for me was to wrap the BuilderContent in <client-only></client-only>.

This sadly isn't an option for us because we would lose all the SSR advantages.

20x-dz avatar Jul 19 '24 08:07 20x-dz

If it helps anyone: A workaround for me was to wrap the BuilderContent in <client-only></client-only>.

This sadly isn't an option for us because we would lose all the SSR advantages.

Understandable. For me it was enough to only wrap that one component into client-only that was causing the issue.

Crease29 avatar Jul 19 '24 09:07 Crease29

This is still an issue. I tried to apply the react suggestions somehow, but to no avail, as isolated-vm does not seem to be available on vercel as I get the following error:

[info] ✓ 544 modules transformed.
Error:  x Build failed in 6.[48](https://github.com/<redacted>/<redacted>/actions/runs/10474377917/job/29009054444#step:5:49)s
Error:  Nuxt Build Error: Could not resolve "./out/isolated_vm" from "./out/isolated_vm?commonjs-external"
file: ./out/isolated_vm?commonjs-external
  file: ./out/isolated_vm?commonjs-external
  at getRollupError (node_modules/rollup/dist/es/shared/parseAst.js:392:41)
  at error (node_modules/rollup/dist/es/shared/parseAst.js:388:42)
  at ModuleLoader.handleInvalidResolvedId (node_modules/rollup/dist/es/shared/node-entry.js:19071:24)
  at node_modules/rollup/dist/es/shared/node-entry.js:19031:26
Error: Command "npm run build" exited with 1

when trying to load isolated-vm conditionally using a composable, e.g.

import { Builder } from "@builder.io/sdk-vue";

export async function useIsolatedVm(): void {
  if (Builder.isServer) {
    await import("isolated-vm");
  }
}

@samijaber any hints?

20x-dz avatar Aug 20 '24 15:08 20x-dz

And trying import { initializeNodeRuntime } from "@builder.io/sdk-vue/node/init"; doesn't work either because [plugin:vite:import-analysis] Missing "./node/init" specifier in "@builder.io/sdk-vue" package

20x-dz avatar Aug 21 '24 07:08 20x-dz

importing isolated-vm doesn't work locally either… NODE_OPTIONS=--no-node-snapshot npm run dev on node v20.15.1:

✘ [ERROR] Could not resolve "./out/isolated_vm"

    node_modules/isolated-vm/isolated-vm.js:1:25:
      1 │ module.exports = require('./out/isolated_vm').ivm;
        ╵                          ~~~~~~~~~~~~~~~~~~~


 ERROR  error while updating dependencies:                                                                                                     09:42:25
Error: Build failed with 1 error:
node_modules/isolated-vm/isolated-vm.js:1:25: ERROR: Could not resolve "./out/isolated_vm"
    at failureErrorWithLog (/Users/me/project/frontend/node_modules/esbuild/lib/main.js:1472:15)
    at /Users/me/project/frontend/node_modules/esbuild/lib/main.js:945:25
    at /Users/me/project/jupiter/frontend/node_modules/esbuild/lib/main.js:1353:9
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

20x-dz avatar Aug 21 '24 07:08 20x-dz

@20x-dz please tell me which package manager you use?

maxsolovev avatar Sep 02 '24 17:09 maxsolovev

@20x-dz please tell me which package manager you use?

npm

20x-dz avatar Sep 03 '24 09:09 20x-dz

npm

I use bun and had the same problem. Solved it by adding packages to trustedDependencies (https://bun.sh/guides/install/trusted). Maybe npm has something similar.

maxsolovev avatar Sep 03 '24 10:09 maxsolovev

Thx. This seems to be more of a security measure from bun:

Unlike other npm clients, Bun does not execute arbitrary lifecycle scripts for installed dependencies, such as postinstall and node-gyp builds. These scripts represent a potential security risk, as they can execute arbitrary code on your machine.

To my knowledge npm just executes everything… 😅

And locally (or in a dockerized) we don't have any issues, just on vercel… And vercel support doesn't know anything about this dependency either, which makes everything super frustrating.

20x-dz avatar Sep 03 '24 10:09 20x-dz

Maybe you can try something like this https://github.com/nuxt/vercel-builder/issues/371#issuecomment-804474999

maxsolovev avatar Sep 03 '24 10:09 maxsolovev

Thank you very much for the suggestion, but that seems to be for Nuxt 2 unfortunately.

20x-dz avatar Sep 06 '24 14:09 20x-dz

DEPT® has also reproduced this issue w/ Node v20 and Salesforce's Managed Runtime Environment for their Commerce Cloud B2C PWA Kit solution. Specifically in SSR contexts.

sholsinger avatar Sep 30 '24 14:09 sholsinger

@sholsinger thanks for filing. This github issue is specifically about isolated-vm import error with Nuxt 3, which means using the @builder.io/sdk-vue Vue SDK.

Since you're on PWA Kit, I assume you are installing @builder.io/sdk-react? If so, have you used the initializeNodeRuntime helper that takes care of importing isolated-vm correctly? See https://github.com/BuilderIO/builder/blob/main/packages/sdks/output/react/CHANGELOG.md#1021

samijaber avatar Oct 01 '24 15:10 samijaber

Hello, @samijaber

  • "@builder.io/sdk-react": "^2.0.13",

When we try to use examples from current documentation: image

We got an error, apparently, this is an import error of initializeNodeRuntime

Also in console, I see these errors

I hope this is a common problem and you can tell us what it is?

    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/webpack/lib/Compilation.js:2100:28
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/webpack/lib/NormalModuleFactory.js:904:13
    at eval (eval at create (/Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:10:1)
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/webpack/lib/NormalModuleFactory.js:341:22
    at eval (eval at create (/Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:9:1)
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/webpack/lib/NormalModuleFactory.js:518:22
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/webpack/lib/NormalModuleFactory.js:151:11
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/webpack/lib/NormalModuleFactory.js:776:25
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/webpack/lib/NormalModuleFactory.js:988:8
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/webpack/lib/NormalModuleFactory.js:1118:5
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/neo-async/async.js:6883:13
    at Array.<anonymous> (/Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/webpack/lib/NormalModuleFactory.js:1093:14)
    at arrayEachFunc (/Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/neo-async/async.js:2517:19)
    at Object.parallel (/Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/neo-async/async.js:6858:9)
    at NormalModuleFactory._resolveResourceErrorHints (/Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/webpack/lib/NormalModuleFactory.js:1016:12)
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/webpack/lib/NormalModuleFactory.js:948:18
    at finishWithoutResolve (/Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/enhanced-resolve/lib/Resolver.js:567:11)
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/enhanced-resolve/lib/Resolver.js:656:15
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/enhanced-resolve/lib/Resolver.js:718:5
    at eval (eval at create (/Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:16:1)
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/enhanced-resolve/lib/Resolver.js:718:5
    at eval (eval at create (/Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:27:1)
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:89:43
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/enhanced-resolve/lib/Resolver.js:718:5
    at eval (eval at create (/Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/enhanced-resolve/lib/Resolver.js:718:5
    at eval (eval at create (/Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:16:1)
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/enhanced-resolve/lib/Resolver.js:718:5
    at eval (eval at create (/Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:16:1)
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/enhanced-resolve/lib/Resolver.js:718:5
    at eval (eval at create (/Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:27:1)
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:89:43
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/enhanced-resolve/lib/Resolver.js:718:5
    at eval (eval at create (/Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:16:1)
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/enhanced-resolve/lib/Resolver.js:718:5
    at eval (eval at create (/Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
    at /Users/antonbabilia/Documents/work/DEPT/ecomm-pwa/node_modules/enhanced-resolve/lib/DirectoryExistsPlugin.js:41:15
    at processTicksAndRejections (node:internal/process/task_queues:81:21)```

ababilia-joann avatar Oct 07 '24 15:10 ababilia-joann

@ababilia-joann Please create a new issue as this one has been resolved. And you're using a different stack. thank you very much.

20x-dz avatar Oct 08 '24 09:10 20x-dz

@ababilia-joann I know that my teammate is speaking to you via other channels, but I will leave this for context for other users.

We have added information on how to import this helper in the following resources:

  • https://www.builder.io/c/docs/integration-tips#enabling-data-bindings-in-node-environments
  • https://github.com/BuilderIO/builder/blob/main/packages/sdks/output/react/CHANGELOG.md#1021
  • https://github.com/BuilderIO/builder/blob/main/packages/sdks/src/functions/evaluate/node-runtime/init.ts#L19-L28

As explained in these resources, you must make sure to import this helper in such a way that it only executes on the server. The exact location will vary depending on your meta-framework and webapp configuration.

I see that you have performed this import in the module scope of a file. This will not get the job done, as this file is imported by the client as well.

We are currently investigating how to utilize this helper in the context of PWAKit to successfully initialize the VM, and will communicate that to you directly once we have that information.

samijaber avatar Oct 08 '24 14:10 samijaber