-
Notifications
You must be signed in to change notification settings - Fork 30.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
doc: add source community condition definition #43376
Conversation
Review requested:
|
But what if the original source isn't runnable, like TypeScript? Is the expectation that |
This is something npm should handle, not node, with the package distributions RFC. |
I'm not going to lie, I don't know if this is something I'd want to encourage. Specifically, I think this exact thing will dramatically increase total bundle sizes resulting in both increased size on disk for end-users (I care more about the total disk usage on personal/work computers, not servers where stuff is running) and it will globally increase install times. IMO the issues I mentioned are 100% because the npm registry does not provide a way to offer multiple distributions of the same version of a package (I've had this discussion many times with @ljharb, begging him to drop tests from his modules). I would genuinely love it if they did (then I wouldn't have to have @ljharb's and others' tests in my IMO this isn't a bad feature and I wouldn't be upset if it shipped, but I think there are more direct solutions that are better for the ecosystem and don't introduce features that we'll have deprecate/change/teach not to use as a part of best practices later. |
I actually use this pattern on a TypeScript codebase myself, and the benefit during development is only having to run
Can you explain how npm should handle this in more detail, or link to the source? I'm not aware of these efforts and it is definitely worth comparing the pros and cons here more carefully.
Here's one way to frame it - should it be possible to edit files in node_modules to debug an application? And should that ability stop npm package authors from publishing well-optimized packages? Let's perhaps focus on the problem before shooting down solutions, without understanding what these costs are being weighed against.
I would be grateful for links / resources further. |
So should |
I personally recommend the following workflow for performance and ease of development:
Where the I then use the following package.json file: {
"exports": {
"source": "./lib/index.js",
"default": "./dist/index.js"
}
} During development, I run TSC compilation through the simple TSC watcher and run tests and example applications with the When publishing to npm, I only then run the optimization, and use the fact that When linking the package into another dependency using npm link or otherwise, it can be useful to attach the same dev workflow to original sources in the same way which then all works out. I think we need to treat original sources as a very important supply chain security property of the npm ecosystem, and actively protect that. I hope we at least agree on that! |
I believe @ljharb was referring to this RFC which does not do exactly what he/I would want, but conceptually gets close: npm/rfcs#519
Conceptually, I believe that the npm Registry should allow you to publish multiple distributions (the specific name doesn't matter, distributions is just a somewhat accurate representation) for the same version. For example:
This has a some nice benefits:
My personal perspective is that enabling this within the existing publishing structure (as this PR aims to do) does solve the problem but in a way that is less optimal than the underlying platform itself supporting the use case. Definitely want to note that I'm not blocking this or trying to toss out the proposed solution, just want to surface my recommendation that this be done at the registry level rather than the Node.js level for what I think would be a more robust solution to the (extremely valid!) problem. |
It's difficult to come up with a single solution to this problem of maintaining the original JS source supply chain on npm - I think rather than trying to point to some future proposal which will fix everything it can be better to think in terms of primitives that can enable use cases. As an interpreted language that is also optimized, this is a uniquely JS problem. I see different approaches at the package management and source levels being able to work together and compose and depend on eachother's behaviours. I do think that As the future points towards optimized packages being published to npm as a potential best-practise, I think we need to work to create these primitives, and not hinder work that will help keep JS having the properties that we all know and love. Another approach might just be for a GitHub clone of the original repo to have a direct workflow something like the convention:
One issue with these though is since they are additive to existing workflows, it is very hard to get alignment on such things and in practice most packages end up needing custom steps. This is where |
* `"source"` - can be used to reference unminified / unoptimized source versions | ||
to use for debugging workflows, that will behave identically to any non-source | ||
variants. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* `"source"` - can be used to reference unminified / unoptimized source versions | |
to use for debugging workflows, that will behave identically to any non-source | |
variants. | |
* `"source"` - can be used to reference unminified, unoptimized, _runnable_ | |
source JavaScript files. These can be used for debugging workflows, that will | |
behave identically to any other variants. |
I’m not sure if source
is the best name for this, since many people might assume that source
should refer to original TypeScript or other before-building files. Perhaps pretty
, to correspond with DevTools pretty printing minified source files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only other word I can think of off-hand that captures the same meaning might be "unoptimized"
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"pretty"
is close, but it's not just unminification, it's also having separated source files structured by the author.
I also think that a single “source” would replicate the disaster that is the RN ecosystem to the rest of JS - where folks rely on an arbitrary build process/config to compile their node_modules and things randomly break when authored with another one in mind. This isn’t node’s problem to solve. |
This proposal does not imply any build process for
As a community condition definition this is not a Node.js feature, it is a conditional exports shared ecosystem convention space that Node.js is still stewarding in its documentation for now. |
Right, but the community hasn’t defined this one. Node should be documenting community conventions, not dictating them. |
Sure, I can go ahead with the condition in my own tooling and come back to the definition once there is more usage. |
I'd like to propose a new
"source"
condition in the"exports"
field.Currently, Node.js applications tend to assume that what is published to npm and imported from
node_modules
should be readable JS code and generally isn't minified and optimized by default.In Node.js this is because minification and optimization doesn't provide a huge benefit for runtime performance.
On the other hand, when running JS code in the browser, minification and single-file optimizations are an absolute necessity.
When specifying a
"browser"
exports condition in the package.json, there's then a sort of implicit assumption that one should reference a minified source file, in contrast to an unminified version for Node.js.This disparity is something package authors often have to wrestle with in making individual decisions for environments in this way.
A
"source"
condition would be defined as the uncompiled version of the code that runs the original source directly, useful for debugging workflows. By permitting packages to define this condition, we are encouraging packages to publish their original sources beyond just questionable source maps support, but actually in a form that can allow debugging back to the original readable code in all environments, while still being able to publish optimized JS code to npm.The existing
"development"
and"production"
conditions don't capture this condition because they refer to the execution mode, not the execution performance. Things like single-file-optimizations, minification and removing comments can be seen as optimizations that apply to both builds.By using a
"source"
condition over a"optimized"
condition or otherwise, we make it clear that the default mode for sources should really be to publish the most optimized version, and that switching back into a source condition is something that is done under special circumstances.I've found this pattern incredibly useful for local development, running local tests via both
node test/test.js
andnode -C source test/test.js
when source maps are not sufficient to trace the error, and live code editing to add comments or further analysis is needed directly on the original sources to track the bug.//cc @nodejs/modules