davidmyersdev / vite-plugin-node-polyfills

A Vite plugin to polyfill Node's Core Modules for browser environments.
MIT License
263 stars 17 forks source link

Failed to load url /node_modules/path-browserify/posix #48

Open j4k0xb opened 8 months ago

j4k0xb commented 8 months ago

Reproduction: https://stackblitz.com/edit/vitejs-vite-1axycb?file=main.js Its currently possible to do import { join } from 'path' or import { posix } from 'path' but not these:

import { join } from 'path/posix';
import { join } from 'node:path/posix';

Error:

Failed to load url /node_modules/path-browserify/posix (resolved id: /home/projects/vitejs-vite-1axycb/node_modules/path-browserify/posix) in /home/projects/vitejs-vite-1axycb/main.js. Does the file exist?

(Not sure if that is the correct repo to report it to or https://github.com/niksy/node-stdlib-browser)

davidmyersdev commented 8 months ago

This relates to #16. I think the best approach here is to use the new overrides feature to specify a better polyfill for path that meets your specific use case.

j4k0xb commented 8 months ago

path-browserify already defaults to the posix implementation and my lib gets bundled for both node (without a polyfill) and web (path-browserify), so I can't change the import to just "path" as that would be different on windows pcs.

But the main issue is that there's no way to make vite-plugin-node-polyfills resolve the whole path/posix... instead it concatenates "node_modules/<path polyfill>" + "/posix" and basically no polyfill has this file structure or subpath pattern.

would it be possible to allow overrides like { 'path/posix': 'foo' } or is there a better way?

davidmyersdev commented 8 months ago

Ah, that makes sense. I think fs runs into the same problem with fs/promises not playing well with packages like memfs that do not specify subpath exports. I'll see if I can get something working for subpath patterns. 👍

davidmyersdev commented 6 months ago

I've started looking into this, and I found a temporary workaround. Add a custom alias to your Vite config that points to the corresponding polyfill:

import { defineConfig } from 'vite'
import { nodePolyfills } from 'vite-plugin-node-polyfills'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    nodePolyfills(),
  ],
  resolve: {
    alias: {
      'path/posix': 'path-browserify',
    },
  },
})
j4k0xb commented 6 months ago

That seems to work for the small project I sent earlier but doesn't work for my local one. After a lot of testing I finally found out that it only happens when https://github.com/solidjs/vite-plugin-solid is active, specifically this line: https://github.com/solidjs/vite-plugin-solid/blob/2b37a130f9f2cbece9e27bbdce6b67f16424866f/src/index.ts#L310 So there's a difference between the resolve.alias being an object and an array with find/replace Repro: https://stackblitz.com/edit/vitejs-vite-z8v1wp?file=vite.config.js,main.js

I also found another workaround:

import { posix } from 'path';
const { dirname, join, relative } = posix;
mkilpatrick commented 3 months ago

Bump on this.