-
-
Notifications
You must be signed in to change notification settings - Fork 615
Description
-
Rollup Plugin Name:
node-resolve,commonjs,json -
Rollup Plugin Version:
latest@ all
Adding support for full ES-Node interop
An important functionality for Rollup I believe is the ability to bundle ES modules which depend on Node packages, as this is a highly common development scenario. Interop with Node typically requires the inclusion of three plugins (above) which I will call the Node compatibility suite, and it presently has 86% coverage over the top ~100 NPM packages and the modules they depend on. Node interop is really the only reason I have ever needed to reach for Webpack anymore, and it would be nice to get us to the finish line on this.
Unfortunately, because a failure at any point in a dependency tree is disastrous to the developer experience, this risk compounds rapidly, and even 99% coverage is insufficient - however, I think it would be relatively easy to get 100% coverage over the top 1000 NPM packages within 30 days, as most issues seem to be caused by a few isolated issues.
Link: Node-Rollup Test Suite [PRs extremely welcome]
There are two types of errors that can occur with Node-Rollup interop:
- There is a build-time failure, i.e. the output bundle cannot be generated.
- There is a run-time failure, i.e. the output bundle does not behave in the same way as the source¹.
Some build-time headaches this team is already familiar with include the notable fsevents issue, which I would honestly place as a principal issue, if only because it actually prevents Rollup from bundling its own API via import { rollup } from rollup, which is incredibly depressing. As I understand it, chokidar can only bundle because a chokidar-specific wrapper was added, but this is insufficient for the obvious reason that it does not actually solve the problem - a better option would be adding the ability to ignore optionalDependencies, or even making them opt-in and ignore by default (what I would recommend), which is a future-proof and more general solution that will cover all packages.
¹ In the test suite, this is lazily evaluated as "if both fail, pass; if both exit 0, pass" when comparing source and bundle exit codes. Nonzero exits are generalized as "equivalent" for the purposes of these tests. This check can get more aggressive once we have 100% coverage, i.e. making sure console.log is 1:1 and so on.
Expected Behavior / Situation
It should be virtually impossible to find an NPM package which will not bundle and execute as expected.
Actual Behavior / Situation
Of the test sample (n=1303), 17 (1.3%) produce build-time errors, and 176 (13.5%) fail the runtime test, bringing total coverage to ~85.3%. Honestly, I would say this is pretty good coverage going into this issue.
Modification Proposal
Any adjustments could likely be limited to just the node-resolve plugin, and adding the could be enabled with an option flag like node-resolve plugin to your build would just imply commonjs and jsonnodeResolve({ legacyMode: true }).
Fix build-time failures
-
Add opt-in/opt-out ignore of
optionalDependenciesto handlefsevents-like scenarios. Preferred solution is to ignoreoptionalDependenciesby default and add a flag for including them. -
✅ Fix hashbang directory issue Bundle fails for form require('../#/folder') due to hashbang-only directory #528 (in-progress at fix(babel): strip hash and query param in extension filter #533), which breaks for
es5-extpackage (and packages in the top 100 that depend on it, specificallyd gulp es6-iterator es6-symbol es6-weak-map gulp gulp-cli last-run semver-greatest-satisfied-range sver-compat, see config/exclude.txt). [Update 11/13/20: This is fixed (presumably) with fix(babel): strip hash and query param in extension filter #533.] -
Fix other build-time errors produced by the packages in
config/exclude.txt. There's a "return outside of function" in there and a few other issues, but I have not bothered logging the build-time errors in theresults/dir yet as the runtime errors are much harder to test and outnumber them 10:1.
Packages which cannot build are added to config/exclude.txt so that the tests will build, any package in the test sample which refuses to build is listed in there.
Fix run-time failures
The following two issues cause 50% of the run-time errors:
-
util.inheritstranspilations will fail in certain cases and get called with a null second argument (admittedly need help debugging this one), causing the errorTypeError [ERR_INVALID_ARG_TYPE]: The "superCtor" argument must be of type function. Received undefinedto be one of the two most common runtime errors, occurring for 64 packages that were tested for runtime errors (36% of build-time failures). See bundles/argparse.js:983:util.inherits(ArgumentGroup, action_container). This error seems most frequently produced by packages that rely onreadable-stream. -
__filenameand__dirnameshims are needed as CJS Node modules make use of these. I considered thenode-polyfillsplugin, but it completely conflicts withnode-resolveand makes the build process unworkable. Errors due to__filenameand__dirnamebeing rolled into ES output cause 25 packages to fail (14% of build-time failures). This support will need to be added in a more native manner, see [commonjs] Output contains references to __filename #523.
I am happy to help as much as I can with this process, but I am a little out of my depth here and I would really appreciate support from the Rollup team in reaching 100% Node coverage.