Comments (5)
Thanks for reporting the issue, and as you can likely tell there is quite a bit of complex reasoning for how we got here.
The short answer is that the cases you're talking about supporting like function obj () {}; obj.foo = ...
are all cases where it's impossible to tell foo
is an export before the CommonJS has executed.
The restriction of needing to work out what a CommonJS module will export before we can execute it is one that was imposed by a combination of requirements from the ECMAScript modules spec itself to Node.js requirements, that were all fought and argued extensively.
While it is possible in theory to support these cases via static analysis, the other constraint this project has is to extract the list of exports incredibly quickly so there is no execution slowdown. More advanced code analysis to determine obj
is a function that is later exported, that has properties applied, is simply out of the scope of this project unfortunately.
There are likely simple cases we can improve - eg we don't currently support module.exports = { a: 1 }
, simply because a number on the value side of an object expression isn't yet supported by the parser. So if you hit simpler cases where your eyes don't need to understand JavaScript execution to easily see what is exported (about the level of this project), then we can certainly add support for those.
Let me know if that answers your question and sorry we can't do better than this.
from cjs-module-lexer.
I think it answers my questions and makes sense why an eval is completely out of the question. Further I wondered if we could use the *.d.ts if available to try aid in the populating of exports. I think this could be more efficient than running eval on the js file itself, however still goes against your goals and probably would have perf impact as it's still not just a regex expression. Cutting that as an option as a whole then.
Below you'll find some notes I had per package and why they didn't work based on your answers. This is mostly for anyone who comes to see this issue later. On this, I definitely think there is a bug with the enzyme
scenario and I even added the unit test code in that example. Hopefully it helps you quickly be able to come up with a fix (I think it's related to the module.exports = { a: 1 }
case).
At this point, feel free to close this issue or keep it open to fix the enzyme example I provided. However I think you've answered all my questions so thank you!
chalk
unpkg link to package contents
Reason this library is unable to parse the commonjs contents is because the exports are defined as such module.exports = chalk;
which to your point, requires an eval to determine the values.
However, this package does provide a index.d.ts... which is very complicated and would not be useful. That idea's out the door too.
commander
unpkg link to package contents
Reason this library is unable to parse is because the exports line is as such: exports = module.exports = new Command();
. Effectively same issue as chalk.
glob
unpkg link to package contents
Same as chalk and commander
enzyme
unpkg link to package contents
This one actually should be parseable. The exports are as follows:
module.exports = {
render: _render2["default"],
shallow: _shallow2["default"],
mount: _mount2["default"],
ShallowWrapper: _ShallowWrapper2["default"],
ReactWrapper: _ReactWrapper2["default"],
configure: _configuration.merge,
EnzymeAdapter: _EnzymeAdapter2["default"],
};
I created a unit test for this particular file and found that it's only picking up the first key render
however the rest of the keys seem to be missing.
test("complex values", () => {
const { exports, reexports } = parse(`
var _ReactWrapper = require('./ReactWrapper');
var _ReactWrapper2 = _interopRequireDefault(_ReactWrapper);
var _ShallowWrapper = require('./ShallowWrapper');
var _ShallowWrapper2 = _interopRequireDefault(_ShallowWrapper);
var _EnzymeAdapter = require('./EnzymeAdapter');
var _EnzymeAdapter2 = _interopRequireDefault(_EnzymeAdapter);
var _mount = require('./mount');
var _mount2 = _interopRequireDefault(_mount);
var _shallow = require('./shallow');
var _shallow2 = _interopRequireDefault(_shallow);
var _render = require('./render');
var _render2 = _interopRequireDefault(_render);
var _configuration = require('./configuration');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
module.exports = {
render: _render2['default'],
shallow: _shallow2['default'],
mount: _mount2['default'],
ShallowWrapper: _ShallowWrapper2['default'],
ReactWrapper: _ReactWrapper2['default'],
configure: _configuration.merge,
EnzymeAdapter: _EnzymeAdapter2['default']
};
`);
assert.equal(exports[0], "render");
assert.equal(exports[1], "shallow");
assert.equal(exports[2], "mount");
assert.equal(exports[3], "ShallowWrapper");
assert.equal(exports[4], "ReactWrapper");
assert.equal(exports[5], "configure");
assert.equal(exports[6], "EnzymeAdapter");
assert.equal(exports.length, 7);
});
tslib
unpkg link to package contents
Seems to work as expected which is great!
from cjs-module-lexer.
Agreed it would be nice to parse the enzyme one. There's actually a way we could support this in the parser I think, although it would be an interesting new parser approach... are you interested in working on the parser?
from cjs-module-lexer.
As much as I'd love to I simply wont have time. This is only one of multiple issues I'm running into while trying to move my org to be able to use ESM. Currently hunting and debugging each one to open tickets in all the respective projects (as you can see from the investigation above I'm going package by package) is very time consuming.
I'll try to loop back when time opens up in case it hasn't been tackled but I'd estimate months out at this point.
from cjs-module-lexer.
Ok I've posted #58 which we can leave open to track the specific support for whenever whomever has time! Thanks again for the comments.
from cjs-module-lexer.
Related Issues (20)
- Extending exports object detections HOT 20
- add tag for 1.2.2 HOT 4
- node ES6 import throws this error. HOT 18
- Error selecting connection connect ECONNREFUSED 127.0.0.1:5432
- Function call changes in TypeScript 4.4 seem to be breaking detection of named exports HOT 7
- Can't export when enumerable is "!0"
- When trying to build with snowpack this error is thrown HOT 4
- Not work well with TypeScript export default as output HOT 2
- exports can be detected in hashbang
- Feature Request: Also detect esbuild Re-exports HOT 1
- Bug: cannot detect exported numbers HOT 5
- Incompatibility with TypeScript (edge case) HOT 3
- Issue with parsing 'react-transition-group' HOT 2
- Rollup ^3.0.0 cjs re-exports edge case with externalLiveBindings: false HOT 8
- Out of bounds memory access HOT 1
- Real world edge case: prettier HOT 1
- Add RISC-V Support HOT 2
- Unable to detect exports from bundled webpack output HOT 6
- Cannot load externalized builtin: "internal/deps/cjs-module-lexer/lexer:/usr/lib/node_modules/cjs-module-lexer/lexer.js". HOT 9
- Allow externalized Wasm build HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cjs-module-lexer.