unenv icon indicating copy to clipboard operation
unenv copied to clipboard

ENOTDIR: not a directory with `whatwg-url.mjs/webidl2js-wrapper`

Open hermesalvesbr opened this issue 9 months ago • 1 comments

Environment

Environment

Operating System: Linux (Ubuntu)
Node Version: v22.14.0
Nuxt Version: 3.16.1
Nitro Version: 2.11.7
Package Manager: [email protected] (also tested with [email protected])
Preset: cloudflare-pages
Compatibility Date: 2025-03-12 (also tested with 2025-03-20)

Reproduction

Nuxt 3.16.1 with Nitro 2.11.7 ℹ Building for Nitro preset: cloudflare-pages ✔ Generated public dist [nitro] ℹ Building Nuxt Nitro server (preset: cloudflare-pages, compatibility date: 2025-03-12) [nitro] ERROR Error: ENOTDIR: not a directory, stat '/home/hermes/Projetos-linux/cidadeMobile/node_modules/nitropack/node_modules/unenv/dist/runtime/npm/whatwg-url.mjs/webidl2js-wrapper' undefined [ERROR] ENOTDIR: not a directory, stat '.../unenv/dist/runtime/npm/whatwg-url.mjs/webidl2js-wrapper' error: script "build" exited with code 1

Describe the bug

When building a Nuxt 3.16.1 project with Nitro 2.11.7 using the cloudflare-pages preset, the build fails with the following error:

[nitro] ERROR Error: ENOTDIR: not a directory, stat '.../node_modules/nitropack/node_modules/unenv/dist/runtime/npm/whatwg-url.mjs/webidl2js-wrapper'

The error occurs during the "Building Nuxt Nitro server" step, indicating that unenv (via nitropack) is attempting to treat webidl2js-wrapper as a directory when it should be a file, or the file is missing/corrupted in the [email protected] structure. This happens consistently both locally (Ubuntu, Node 22.14.0, Bun 1.2.7 or npm 10.9.2) and on Cloudflare Pages deployment. The issue persists despite forcing [email protected] in resolutions and excluding whatwg-url/webidl2js-wrapper in nitro.externals.inline.

I suspect this is a bug in how [email protected] structures or resolves whatwg-url.mjs/webidl2js-wrapper for the cloudflare-pages preset. I’m happy to submit a PR if guided on where to start—thanks!

Additional context

import { fileURLToPath } from 'node:url'
import vuetify from 'vite-plugin-vuetify'
import svgLoader from 'vite-svg-loader'

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  runtimeConfig: {
    alibabaApiKey: import.meta.env.NUXT_ALIBABA_API_KEY,
    public: {
      API_BASE_URL: import.meta.env.NUXT_PUBLIC_API_BASE_URL || 'http://localhost:8055',
    },
  },
  features: {
    inlineStyles: false,
  },
  app: {
    head: {
      titleTemplate: '%s - Cidade Transparente',
      title: 'Softagon',

      link: [{
        rel: 'icon',
        type: 'image/x-icon',
        href: `/favicon.ico`,
      }],
    },
  },

  devtools: {
    enabled: false,
  },

  css: [
    '@core/scss/template/index.scss',
    '@styles/styles.scss',
    '@/plugins/iconify/icons.css',
    'notivue/notification.css', // Added Notivue notification styles
    'notivue/animations.css', // Added Notivue animations styles
    '@mdi/font/css/materialdesignicons.css', // Adicionado para suportar ícones MDI
  ],

  components: [
    {
      path: '@/@core/components',
      pathPrefix: false,
    },
    {
      path: '~/components/global',
      global: true,
    },
    {
      path: '~/components',
    },
  ],

  plugins: ['@/plugins/vuetify/index.ts', '@/plugins/iconify/index.ts'],

  imports: {
    dirs: ['./@core/utils', './@core/composable/', './plugins/*/composables/*'],
  },

  experimental: {
    typedPages: true,
  },

  typescript: {
    tsConfig: {
      compilerOptions: {
        paths: {
          '@/*': ['../*'],
          '@themeConfig': ['../themeConfig.ts'],
          '@layouts/*': ['../@layouts/*'],
          '@layouts': ['../@layouts'],
          '@core/*': ['../@core/*'],
          '@core': ['../@core'],
          '@images/*': ['../assets/images/*'],
          '@styles/*': ['../assets/styles/*'],
          '@validators': ['../@core/utils/validators'],
          '@db/*': ['../server/fake-db/*'],
          '@api-utils/*': ['../server/utils/*'],
        },
      },
    },
  },

  vue: {
    compilerOptions: {
      isCustomElement: tag => tag === 'swiper-container' || tag === 'swiper-slide',
    },
  },

  vite: {
    define: { 'process.env': {} },

    resolve: {
      alias: {
        '@': fileURLToPath(new URL('.', import.meta.url)),
        '@themeConfig': fileURLToPath(new URL('./themeConfig.ts', import.meta.url)),
        '@core': fileURLToPath(new URL('./@core', import.meta.url)),
        '@layouts': fileURLToPath(new URL('./@layouts', import.meta.url)),
        '@images': fileURLToPath(new URL('./assets/images/', import.meta.url)),
        '@styles': fileURLToPath(new URL('./assets/styles/', import.meta.url)),
        '@configured-variables': fileURLToPath(new URL('./assets/styles/variables/_template.scss', import.meta.url)),
        '@db': fileURLToPath(new URL('./server/fake-db/', import.meta.url)),
        '@api-utils': fileURLToPath(new URL('./server/utils/', import.meta.url)),
      },
    },

    plugins: [
      svgLoader(),
      vuetify({
        styles: {
          configFile: 'assets/styles/variables/_vuetify.scss',
        },
      }),
    ],

    // Optimização do build para remover componentes relacionados ao layout horizontal
    build: {
      rollupOptions: {
        external: [
          '@layouts/components/HorizontalNav.vue',
          '@layouts/components/HorizontalNavGroup.vue',
          '@layouts/components/HorizontalNavLayout.vue',
          '@layouts/components/HorizontalNavLink.vue',
          '@layouts/components/HorizontalNavPopper.vue',
        ],
      },
    },
  },

  build: {
    transpile: ['vuetify'],
  },

  modules: ['@vueuse/nuxt', '@nuxtjs/i18n', '@nuxtjs/device', '@pinia/nuxt', 'notivue/nuxt'],
  i18n: {
    bundle: {
      optimizeTranslationDirective: false,
    },
  },
  notivue: {
    pauseOnHover: true,
    pauseOnTouch: true,
    pauseOnTabChange: true,
    enqueue: true,
    limit: 3,
    position: 'top-center',
    notifications: {
      global: {
        duration: 2500,
      },
    },
  },
  nitro: {
    preset: 'cloudflare-pages',
    prerender: {
      crawlLinks: true,
      routes: ['/'],
      ignore: ['/api', '/servicos/**'],
    },
    externals: {
      inline: ['canva', 'whatwg-url', 'unenv/runtime/npm/whatwg-url', 'webidl2js-wrapper'],
    },
    minify: false,
    buildDir: '.output',
    publicAssets: [
      {
        dir: '.output/public',
        maxAge: 60 * 60 * 24 * 365,
      },
    ],
  },
  compatibilityDate: '2025-03-20',
})

{
  "name": "cidade-transparente",
  "type": "module",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "dev": "nuxt dev",
    "build": "nuxt build",
    "lint": "eslint . -c .eslintrc.cjs --fix --ext .ts,.js,.cjs,.vue,.tsx,.jsx",
    "build:icons": "tsx plugins/iconify/build-icons.ts",
    "postinstall": "nuxt prepare && npm run build:icons",
    "generate": "nuxt generate",
    "gen:types": "node directus/scripts/genTypes.ts"
  },
  "dependencies": {
    "@casl/ability": "^6.7.3",
    "@casl/vue": "^2.2.2",
    "@directus/sdk": "^19.1.0",
    "@floating-ui/dom": "^1.6.13",
    "@formkit/drag-and-drop": "^0.4.2",
    "@mdi/font": "^7.4.47",
    "@nuxthub/core": "^0.8.22",
    "@nuxtjs/i18n": "^9.4.0",
    "@sindresorhus/is": "^7.0.1",
    "@tiptap/extension-highlight": "^2.11.6",
    "@tiptap/extension-image": "^2.11.6",
    "@tiptap/extension-link": "^2.11.6",
    "@tiptap/extension-placeholder": "^2.11.6",
    "@tiptap/extension-table": "^2.11.6",
    "@tiptap/extension-table-cell": "^2.11.6",
    "@tiptap/extension-table-header": "^2.11.6",
    "@tiptap/extension-table-row": "^2.11.6",
    "@tiptap/extension-text-align": "^2.11.6",
    "@tiptap/extension-underline": "^2.11.6",
    "@tiptap/pm": "^2.11.6",
    "@tiptap/starter-kit": "^2.11.6",
    "@tiptap/vue-3": "^2.11.6",
    "@vue-pdf-viewer/viewer": "^2.3.1",
    "@vueuse/core": "^13.0.0",
    "@vueuse/math": "^13.0.0",
    "@vueuse/nuxt": "^13.0.0",
    "cookie-es": "^2.0.0",
    "destr": "^2.0.3",
    "echarts": "^5.6.0",
    "eslint-plugin-regexp": "^2.7.0",
    "jsdom": "^26.0.0",
    "jwt-decode": "^4.0.0",
    "maska": "^3.1.1",
    "next-auth": "4.24.11",
    "notivue": "^2.4.5",
    "nuxt": "^3.16.1",
    "ofetch": "^1.4.1",
    "openai": "^4.90.0",
    "pinia": "^3.0.1",
    "roboto-fontface": "^0.10.0",
    "shepherd.js": "^14.5.0",
    "swiper": "^11.2.6",
    "ufo": "^1.5.4",
    "unpdf": "^0.12.1",
    "unplugin-vue-define-options": "^3.0.0-beta.7",
    "vue-echarts": "^7.0.3",
    "vue-flatpickr-component": "^12.0.0",
    "vue3-perfect-scrollbar": "^2.0.0",
    "vuetify": "^3.7.19",
    "webfontloader": "^1.6.28"
  },
  "devDependencies": {
    "@antfu/eslint-config": "^4.11.0",
    "@directus/types": "^13.1.0",
    "@iconify-json/bx": "^1.2.2",
    "@iconify-json/fa": "^1.2.1",
    "@iconify-json/mdi": "^1.2.3",
    "@iconify-json/tabler": "^1.2.17",
    "@iconify/tools": "^4.1.2",
    "@iconify/utils": "^2.3.0",
    "@iconify/vue": "^4.3.0",
    "@intlify/unplugin-vue-i18n": "^6.0.5",
    "@nuxtjs/device": "^3.2.4",
    "@pinia/nuxt": "^0.10.1",
    "@sidebase/nuxt-auth": "^0.10.1",
    "@stylistic/stylelint-config": "^2.0.0",
    "@stylistic/stylelint-plugin": "^3.1.2",
    "@types/jsdom": "^21.1.7",
    "@types/node": "^22.13.14",
    "@types/webfontloader": "^1.6.38",
    "@typescript-eslint/eslint-plugin": "^8.28.0",
    "@typescript-eslint/parser": "^8.28.0",
    "directus-typeforge": "^0.10.2",
    "eslint": "^9.23.0",
    "eslint-import-resolver-typescript": "^4.3.1",
    "eslint-plugin-import": "^2.31.0",
    "eslint-plugin-vue": "^10.0.0",
    "postcss-html": "^1.8.0",
    "postcss-scss": "^4.0.9",
    "sass": "^1.86.0",
    "stylelint": "^16.17.0",
    "stylelint-config-standard-scss": "^14.0.0",
    "tsx": "^4.19.3",
    "typescript": "^5.8.2",
    "vite": "^6.2.3",
    "vite-plugin-vuetify": "^2.1.0",
    "vite-svg-loader": "^5.1.0"
  },
  "overrides": {
    "postcss": "^8"
  },
  "resolutions": {
    "postcss": "^8"
  }
}

Logs

Below is the output from running `bun run build` on my project with Nuxt 3.16.1, Nitro 2.11.7, and `[email protected]` forced via `resolutions`. The error occurs during the Nitro server build step with the `cloudflare-pages` preset:


bun update v1.2.7 (5c0fa6dc)

$ nuxt prepare && bun run build:icons
✔ Types generated in .nuxt                                                       nuxi  8:33:07 PM
$ tsx plugins/iconify/build-icons.ts
Saved CSS to /home/hermes/Projetos-linux/cidadeMobile/plugins/iconify/icons.css!

↑ eslint-import-resolver-typescript 4.2.7 → 4.3.1
+ [email protected]

ℹ Prerendered 17 routes in 15.808 seconds                                        nitro 8:35:50 PM
✔ Generated public dist                                                          nitro 8:35:50 PM
[nitro 8:35:50 PM] ℹ Building Nuxt Nitro server (preset: cloudflare-pages, compatibility date: 2025-03-12)
node_modules/openai/core.mjs (1:30): The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten
node_modules/openai/core.mjs (1:38): The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten
node_modules/openai/core.mjs (7:30): The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten
node_modules/openai/core.mjs (7:38): The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten

[nitro 8:35:52 PM]  ERROR  Error: ENOTDIR: not a directory, stat '/home/hermes/Projetos-linux/cidadeMobile/node_modules/nitropack/node_modules/unenv/dist/runtime/npm/whatwg-url.mjs/webidl2js-wrapper'

undefined

[8:35:52 PM]  ERROR  ENOTDIR: not a directory, stat '/home/hermes/Projetos-linux/cidadeMobile/node_modules/nitropack/node_modules/unenv/dist/runtime/npm/whatwg-url.mjs/webidl2js-wrapper'

[8:35:52 PM]  ERROR  ENOTDIR: not a directory, stat '/home/hermes/Projetos-linux/cidadeMobile/node_modules/nitropack/node_modules/unenv/dist/runtime/npm/whatwg-url.mjs/webidl2js-wrapper'

error: script "build" exited with code 1


This log shows the build failing at the Nitro step, with the `ENOTDIR` error pointing to `unenv/dist/runtime/npm/whatwg-url.mjs/webidl2js-wrapper`. The same error occurs with npm (`npm run build`) and on Cloudflare Pages deployment.

hermesalvesbr avatar Mar 30 '25 00:03 hermesalvesbr

The latest versions of both nuxt and nitro use unenv v2. why are you forcing 1.10?

Also, can you please share a minimal reproduction?

pi0 avatar Mar 31 '25 09:03 pi0

The latest versions of both nuxt and nitro use unenv v2. why are you forcing 1.10?

Also, can you please share a minimal reproduction?

I used version 1 just for testing. Yes, I will send a reproduction.

hermesalvesbr avatar Mar 31 '25 10:03 hermesalvesbr

Hi @pi0,

I've been facing the same issue recently too. Here's a minimal reproduction repo: https://github.com/RyanCasas/nuxt-jsdom-issue-minimal

Essentially, if you install jsdom or anything that depends on it, and then use it, nuxt build fails with the cloudflare-pages preset. When testing with the default node preset it will build without an issue.

I've been able to reproduce this on Ubuntu LTS 24.04.2, Windows 11 and Cloudflare Pages CI/CD.

Here's the latest trace from trying to build on Windows 11 with the repo I've shared:

 *  Executing task: pnpm run build 
> nuxt-app@ build C:\Users\jryan\www\nuxt-cf-repro
> nuxt build

Nuxt 3.17.1 with Nitro 2.11.11                                                                                                                                                                                                   nuxi 13:13:55  
ℹ Building for Nitro preset: cloudflare-pages                                                                                                                                                                                   nuxi 13:13:56   
ℹ Building client...                                                                                                                                                                                                                 13:13:57   
ℹ vite v6.3.4 building for production...                                                                                                                                                                                             13:13:57   
ℹ ✓ 131 modules transformed.                                                                                                                                                                                                         13:13:58   
ℹ .nuxt/dist/client/manifest.json                   1.86 kB │ gzip:  0.35 kB                                                                                                                                                         13:13:58   
ℹ .nuxt/dist/client/_nuxt/error-500.CHxnrNOZ.css    1.88 kB │ gzip:  0.72 kB                                                                                                                                                         13:13:58   
ℹ .nuxt/dist/client/_nuxt/error-404.DF1whAaY.css    3.56 kB │ gzip:  1.10 kB                                                                                                                                                         13:13:58   
ℹ .nuxt/dist/client/_nuxt/entry.C_1PimOg.css       12.41 kB │ gzip:  2.57 kB                                                                                                                                                         13:13:58   
ℹ .nuxt/dist/client/_nuxt/C66aXqMb.js               3.39 kB │ gzip:  1.53 kB                                                                                                                                                         13:13:58   
ℹ .nuxt/dist/client/_nuxt/Bjhnyc-0.js               9.49 kB │ gzip:  3.78 kB                                                                                                                                                         13:13:58   
ℹ .nuxt/dist/client/_nuxt/BYJxjD3l.js             243.04 kB │ gzip: 72.19 kB                                                                                                                                                         13:13:58   
ℹ ✓ built in 1.21s                                                                                                                                                                                                                   13:13:58   
✔ Client built in 1221ms                                                                                                                                                                                                             13:13:58   
ℹ Building server...                                                                                                                                                                                                                 13:13:58   
ℹ vite v6.3.4 building SSR bundle for production...                                                                                                                                                                                  13:13:58   
ℹ ✓ 69 modules transformed.                                                                                                                                                                                                          13:13:59   
ℹ ✓ built in 726ms                                                                                                                                                                                                                   13:13:59   
✔ Server built in 734ms                                                                                                                                                                                                              13:13:59   

 WARN  [cloudflare] Node.js compatibility is not enabled.                                                                                                                                                                       nitro 13:13:59  

✔ Generated public dist                                                                                                                                                                                                        nitro 13:13:59   
ℹ Building Nuxt Nitro server (preset: cloudflare-pages, compatibility date: 2024-11-01)                                                                                                                                        nitro 13:13:59   

[nitro 13:14:03]  ERROR  Error: Cannot resolve "C:/Users/jryan/www/nuxt-cf-repro/node_modules/.pnpm/[email protected]/node_modules/unenv/dist/runtime/npm/whatwg-url.mjs/webidl2js-wrapper" from "C:\\Users\\jryan\\www\\nuxt-cf-repro\\node_modules\\.pnpm\\[email protected]\\node_modules\\jsdom\\lib\\jsdom\\living\\interfaces.js" and externals are not allowed!


undefined


[13:14:03]  ERROR  Cannot resolve "C:/Users/jryan/www/nuxt-cf-repro/node_modules/.pnpm/[email protected]/node_modules/unenv/dist/runtime/npm/whatwg-url.mjs/webidl2js-wrapper" from "C:\\Users\\jryan\\www\\nuxt-cf-repro\\node_modules\\.pnpm\\[email protected]\\node_modules\\jsdom\\lib\\jsdom\\living\\interfaces.js" and externals are not allowed!

    at Object.resolveId (/C:/Users/jryan/www/nuxt-cf-repro/node_modules/.pnpm/[email protected]_@[email protected]/node_modules/nitropack/dist/rollup/index.mjs:2013:17)
    at async PluginDriver.hookFirstAndGetPlugin (/C:/Users/jryan/www/nuxt-cf-repro/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:22075:28)
    at async resolveId (/C:/Users/jryan/www/nuxt-cf-repro/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:20557:26)
    at async ModuleLoader.resolveId (/C:/Users/jryan/www/nuxt-cf-repro/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:20993:15)
    at async PluginDriver.hookFirstAndGetPlugin (/C:/Users/jryan/www/nuxt-cf-repro/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:22075:28)
    at async resolveId (/C:/Users/jryan/www/nuxt-cf-repro/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:20557:26)
    at async ModuleLoader.resolveId (/C:/Users/jryan/www/nuxt-cf-repro/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/node-entry.js:20993:15)
    at async /C:/Users/jryan/www/nuxt-cf-repro/node_modules/.pnpm/@[email protected][email protected]/node_modules/@rollup/plugin-commonjs/dist/es/index.js:797:16
    at async Promise.all (index 3)
    at async /C:/Users/jryan/www/nuxt-cf-repro/node_modules/.pnpm/@[email protected][email protected]/node_modules/@rollup/plugin-commonjs/dist/es/index.js:789:32



[13:14:03]  ERROR  Cannot resolve "C:/Users/jryan/www/nuxt-cf-repro/node_modules/.pnpm/[email protected]/node_modules/unenv/dist/runtime/npm/whatwg-url.mjs/webidl2js-wrapper" from "C:\\Users\\jryan\\www\\nuxt-cf-repro\\node_modules\\.pnpm\\[email protected]\\node_modules\\jsdom\\lib\\jsdom\\living\\interfaces.js" and externals are not allowed!

 ELIFECYCLE  Command failed with exit code 1.

RyanCasas avatar May 02 '25 11:05 RyanCasas

Have same issue, wit for bug being fixed

webmaasteriv avatar May 06 '25 10:05 webmaasteriv

I am also facing this issue and have no solution for this, which is really problematic for my project...

thomas-fortin avatar May 22 '25 21:05 thomas-fortin

PR more than welcome. We need to update here and here

pi0 avatar May 22 '25 21:05 pi0