-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Parcel 2: Specific resolvers per file type #3492
Comments
Now thinking of possibly adjusting this slightly to use an new Worker('foo.js') // relative -> ./foo.js
new Worker('npm:foo') // node_modules/foo @import "foo.css"; /* relative -> ./foo.css */
@import "npm:foo"; /* node_modules/foo */
@import "npm:foo/bar.css"; /* node_modules/foo/bar.css */ <script src="foo.js"></script> <!-- ./foo.js -->
<script src="npm:foo"></script> <!-- node_modules/foo --> |
Also probably dropping extensionless import and index file support for Worker, service worker, etc. (JS dependencies other than ESM and CommonJS). This is also more compatible with the way those APIs would work natively in browsers. CSS and HTML also would not support those features. |
Allowing users to customise the meaning for {
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~*": ["./src/*"]
}
} |
That is possible even with the current architecture |
@micopc strange, does it require additional setup though? I couldn't find it documented, and by only declaring it on |
I meant: it is already possible to create a resolver plugin that uses tsconfig (without the changes to the plugin architecture as describes in this issue). |
I don't understand this point. Likewise |
The problem is script and link elements in the browser resolve bare specifiers (without |
Makes sense. Following the nomenclature of |
The way Parcel currently resolves all files is the same across all file types, whether that be JS, CSS, HTML, or anything else, but sometimes it makes sense for there to be differences. For Parcel 2, we are considering making resolvers configurable per file type. Something like this:
These would run as pipelines, similar to other plugin types (e.g. transformers, optimizers, etc.). Each resolver would run, and the result if any would be passed to the next resolver and so on. Allowing resolvers to be configured this way would allow different languages to resolve slightly differently, and for users to adjust smaller aspects of the resolution more easily than rewriting the entire default resolver plugin.
The proposed resolver plugins above are the following:
@parcel/resolver-url
- resolves URL specifiers to file paths, e.g. from CSS and HTML.@parcel/resolver-path
- resolves file path specifiers to absolute, e.g. tilde, relative, etc.@parcel/resolver-alias
- resolves aliases defined in package.json@parcel/resolver-node
- resolves node_modules.The actual resolution algorithms for each language are described in the following sections.
JavaScript
The JS resolution algorithm is a modified version of the Node resolution algorithm. It also supports Parcel's tilde and absolute paths, aliases, and a few other main fields like
source
,browser
andmodule
. This is essentially the same as how Parcel 1 resolved modules.One change from Parcel 1 is to begin treating ES module import specifiers are URLs rather than file paths. This means resolving with URL semantics rather than platform specific path semantics, and allowing things like query strings and percent escaping. See also #3477.
Some examples:
Extensionless specifiers are allowed, but only for the following extensions:
'.js', '.jsx', '.mjs', '.json', '.ts', '.tsx', '.coffee'
. This is different from Parcel 1, which allowed importing any extension supported by Parcel without specifying it. This was slow since Parcel needed to check for every possible extension as it searched for files. Also in Parcel 2 there is no definitive list of extensions that are supported, as we use globs to match files instead, and I don't think it was really ever expected to be able to import non-JS without specifying the extension anyway. It is mostly for compatibility with the Node CommonJS ecosystem.There are a few exceptions, where resolution is treated differently. These are for JS features that produce dependencies other than ES modules and CommonJS, which are generally treated as URLs. Examples include workers, service workers, etc.
The main difference with these specifiers is that they are always treated as URLs, and bare specifiers are resolved as relative by default but fall back to node_modules. See #670. I'm still debating whether extensionless specifiers should be supported here. We could support them only for relative paths and not bare specifiers, or as above at all times. Would like feedback here.
CSS
The resolution algorithm for CSS is similar to the JS one, but has some additional restrictions. It still allows relative, tilde, and absolute path specifiers, but all specifiers are treated as URLs. This means that in addition to allowing query params, percent encoding, etc., relative URLs are allowed without prefixing with
./
. Unfortunately, this conflicts withnode_modules
resolution, but that's less expected than in JS. For CSS, we will first check whether a relative path exists for a bare specifier, and if not, check if anode_modules
path exists.Some examples:
Extensionless imports are not allowed (unlike JS, unlike Parcel 1), and directory index imports are also not allowed (e.g. no
foo/index.css
). This more closely matches the CSS spec, which treats imports are URLs.When resolving from
node_modules
, thepackage.json#style
field is considered as an entry point. Other entry fields are mostly JS specific, so are not supported for CSS.HTML
The resolution algorithm for HTML is much simpler than for JS and CSS.
node_modules
resolution is not generally needed or expected in HTML, so it is not supported by default. That just leaves relative, tilde, and absolute paths, and URLs.Some examples:
Extensionless imports and directory index imports are not supported. All specifiers are treated as URLs, and are resolved with URL semantics. Bare specifiers are treated as relative URLs, just like normal HTML.
Other languages
Other languages generally use their own import semantics and are handled by the individual transformer plugins. A few have Parcel specific extensions:
The text was updated successfully, but these errors were encountered: