Skip to content
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

Add a strict option for path resolution #13

Open
matthieusieben opened this issue Oct 13, 2016 · 2 comments
Open

Add a strict option for path resolution #13

matthieusieben opened this issue Oct 13, 2016 · 2 comments

Comments

@matthieusieben
Copy link

As i understand it, the resolve mechanism is as follows:

  1. resolve the name relative to the file making the import
  2. if that fails, resolve from the path's

I would like to add a "strict" mode so that the first strategy only applies to path starting with either /, ./ or ../.

I currently have a problem with file names (e.g. events) conflicting with node modules, causing A module cannot import itself errors.

@matthieusieben
Copy link
Author

As a workaround, I wrote my own extension. I post it here so that you understand the logic I meant:

        {
            resolveId (file, origin) {
                if (file.charAt(0) === '/') {
                    return file
                } else if (file.charAt(0) === '.') {
                    const basePath = path.dirname(origin)
                    return fileExists(path.join(basePath, file))
                        || fileExists(path.join(basePath, file + '.js'))
                } else {
                    return fileExists(path.join(__dirname, 'src', file))
                        || fileExists(path.join(__dirname, 'src', file + '.js'))
                        || fileExists(path.join(__dirname, 'src', file, 'index.js'))
                }
                function fileExists (file) {
                    try {
                        let stat = fs.statSync(file);
                        return stat.isFile() && file || null;
                    } catch (e) {
                        return null;
                    }
                }
            }
        }

my options for includepaths would be as follows

includepaths({
  external: [],
  paths: [ 'src' ],
  relativeStrict: true,
  extensions: [ '.js', '.json', '.html' ]
}),

@darlanalves
Copy link
Member

I've been thinking about this issue and it seems a bit complicated to cover all cases.

What if you have both cases in the same project? e.g a file called events.js in the root folder (src) and another file trying to use the builtin events module. If both use the same import name ('events'), is impossible to determine which is which.

If you prepend the file with a slash ('/events') that would in turn shadow imports with an absolute path if the logic changes.
If you only resolve files starting with ./ or ../, you have to "hardcode" the entire path to "events.js" somehow.

Correct me if I'm wrong, but this confusion is caused by a "sloppiness" in the way Node.JS resolves the file paths.
ES6 module syntax should always include the file extension in the module path ("events.js"). I'm not sure if that resolves all cases, but I think in your case you should use the file extension to differentiate between a file import ('events.js') and a builtin module import ('events'), rather than changing the resolution logic.

What do you think?

@darlanalves darlanalves pinned this issue Jul 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants