UNPKG

dependency-cruiser

Version:

Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.

46 lines (38 loc) 4.47 kB
# JSX in dependency-cruiser: mplementation rationale I've tried three options to implement cruising jsx. I've chosen to go with acorn_loose (the third option) - here's the rationale, so those who want to make another implementation for it don't have to do the same digging. ## Alternative: babel (not chosen - possibility for later) - For this I introduced jsx as a new alt-js language - with babel-core as the transpiler. - babel-core needs plugins to be able to do anything. For react there is: - `babel-plugin-transform-react-jsx` - this should suffice for purely jsx additions to no-frills javascript (sorta es3). Most react projects uses fancier javascript (es6 or better, with classes, proper module support etc), so without the plugins supporting those the transpilation would fail. - `babel-preset-react` - this is a collection of plugins. It contains transform-react-jsx, and some nice stuff for typical react projects (a.o. es6+ support). - The philosophy of dependency-cruiser is to use the already available transpiler. While babel-core is likely to be part of the project, neither `babel-preset-react` nor `babel-plugin-transform-react-jsx` are guaranteed to be available _or even used_: - react-native projects typically use a different set of plugins - projects have complete liberty to use whatever plugins they want and there's no fixed set that's going to work for all projects. - Alternatively I could _damn the philosophy_ and package a superset of babel plugins with dependency-cruiser. But even that won't cover all cases - and the cost (in download size) is not small- (7.2Mb for the core-js library, 1.1Mb for babel-core and a few bits and bobs for plugins & other deps). **=> not a viable option for the short term** More react research: - `babel` and `babel-preset-react` seem to be the prevalent way to get from jsx to something digestible, but... - is it the only one (probably not)? - nope: `https://github.com/facebookincubator/create-react-app` uses its own `babel-preset-react-app`. But this also installs `babel-preset-react` as a dependency => we're good on this one. - nope: https://www.npmjs.com/package/node-jsx Deprecated. points to babel => good on this one as well. - nope: react native uses `babel-preset-react-native`; https://github.com/facebook/react-native/tree/master/babel-preset is used => :heavy_multiplication_x: - if not: is it worth while supporting other options? - react native seems useful - do the various options have a common denominator (e.g. `babel-plugin-jsx` - maybe another one?) - `babel-plugin-transform-react-jsx` seems to be a reasonable common denominator. It just doesn't work on its own in most react project I've used it on. ## Alternative: acorn with acorn-jsx (not chosen) - For this I introduced acorn-jsx in the extraction step. It's a relatively elegant solution; .js is correctly parsed without hitches, as is .jsx. In the latter case abstract syntax tree contains JSXxxx nodes. Also acorn-jsx is the 'official' jsx parser used by facebook. And babel. However ... - ... for extracting dependencies from the syntax tree I use the tree-walker included in acorn. This - understandably - chokes on the new-fangled JSXxxx nodes acorn-jsx uses. There's some solutions available for this - use the `acorn-jsx-walk` package. It isn't updated for quite a long time, and doesn't seem to have a lot of traction (in downloads, stars or otherwise). It also uses quite a lot of dependencies (biggish) and the code base didn't seem as one I'd like to adopt. - filter/ transform the parsed tree so it doesn't contain JSXxxx nodes anymore - I'm not interested in those anyway. My estimation is that this will be non-trivial to do right. **=> not a viable option for the short term** ## Alternative: acorn_loose Observing - ... in jsx dependencies typically (and sometimes from language/ listing rules) occur on the top. - ... I'm not interested in jsx expressions - only imports, exports & requires and their ilk - ... acorn_loose will in most sane cases pluck out the correct dependencies - especially when they occur at the top (and likely also when they occur below jsx statements) - ... acorn_loose is - already part of acorn, and an existing dependency of dependency-cruiser - fast & stable - ... implementing & testing this is a doddle ... **=> acorn_loose it is for now** ; maybe later an elegant solution for one of the above (plugin? passing babelrc?)