Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
hermesalvesbr opened this issue Mar 30, 2025 · 2 comments
Open
Labels
bug Something isn't working needs reproduction

Comments

@hermesalvesbr
Copy link

Environment

Environment

Operating System: Linux (Ubuntu)
Node Version: v22.14.0
Nuxt Version: 3.16.1
Nitro Version: 2.11.7
Package Manager: npm@10.9.2 (also tested with Bun@1.2.7)
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 unenv@1.10.0 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 unenv@1.10.0 in resolutions and excluding whatwg-url/webidl2js-wrapper in nitro.externals.inline.

I suspect this is a bug in how unenv@1.10.0 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 `unenv@1.10.0` 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
+ unenv@1.10.0

ℹ 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 hermesalvesbr added the bug Something isn't working label Mar 30, 2025
@pi0 pi0 changed the title ENOTDIR: not a directory with whatwg-url.mjs/webidl2js-wrapper in Cloudflare Pages preset (Nuxt 3.16.1, Nitro 2.11.7) ENOTDIR: not a directory with whatwg-url.mjs/webidl2js-wrapper Mar 31, 2025
@pi0
Copy link
Member

pi0 commented Mar 31, 2025

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?

@hermesalvesbr
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs reproduction
Projects
None yet
Development

No branches or pull requests

2 participants