-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Avoid parsing require("dep") inside strings in CJS #312
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
Conversation
Nice, this seems great. Yes it could be nice to get some numbers as performance is the primary concern here. It looks like the way things are going is that we could compile modules at install time with the I'd be happy to take this though soon. |
I think this covers really well, in due course we can cater to ES6 template literals in a similar way. The hard part is working out if there are any tricky interaction cases between the three - comments within strings, strings within template literals etc. If we can handle each case based on what is sensible for CommonJS requires I think we can keep to the 99% goals pretty well without tokenizing. Another option would just be to switch to a simple tokenizing system for all this. It would be interesting to see how that compares for performance if we could do all these functions in a single parse. An earlier version of the loader actually did this stuff with tokenizing - Line 49 in 5f46011
|
Extracting and caching dependencies offline seems ideal, as IIUC that'd That said, given that this PR fixes a live issue that prevents the use of Might have some time this eve. |
Yes exactly, so we move towards having a dev loader and a minimal lightweight performant production loader. My only reservation is whether we actually need to be doing tokenizing where strings meet comments. (think But we can always add this in at a later stage. Happy to take this for now. |
Avoid parsing require("dep") inside strings in CJS
Had a play with some completely non-scientific tests on jsperf: http://jsperf.com/cjs-string According to these, assuming I've not screwed up the tests (which would be somewhat astonishing), and assuming jsperf gives valid results, both in Chrome and FF the code after my change performs ~25-30% slower (on a beefy Macbook Pro). Now to put the results in perspective, running this code on the angularjs source takes ~2ms before and ~3ms after the change. Seems generally fast enough, hopefully even on lower spec hardware, that the impact of the change isn't worth worrying about. |
@theefer thanks, and the AngularJS source is pretty big, so this can still handle hundreds of modules pretty easily it seems. |
Fixes #311
Bit of a tedious job as I couldn't find an elegant way to update
cjsRequireRegEx
to check whether/reject if the match is within a string. The solution I arrived to is to strip all strings from the source if they are not prefixed by (require(
). In the absence of lookbehind in JS regex, I have to fallback to an explicit prefix check in the replace function.I've not restricted this to non-minimised files, since I expect the issue would arise even in minimised files.
The only minor worry is whether this operation is too expensive, but hard to judge without a bit of a performance testing harness.