Skip to content
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

amp-date-picker: restore rrule support #28887

Merged
merged 15 commits into from
Jul 1, 2020
Merged

Conversation

samouri
Copy link
Member

@samouri samouri commented Jun 15, 2020

summary
Reverts #25230, fixes #24682 and #25244. This PR replaces #28842.

We need rrule in order to support a couple of features within amp-date-picker. rrule imports luxon which has circular deps which breaks Google Closure Compiler.

Even though luxon is marked as an optional dependency of rrule within its package.json, it statically imports luxon making it essentially required. If Closure Compiler had the same notion of "externals" that webpack has we could potentially get around it by declaring luxon as external.

short term fix: patch datewithzone.js within node_modules.
long term fix: find a better solution: e.g. a timezone-less esm output target for rrule.

rrule in action
Screen Shot 2020-06-15 at 2 32 41 PM

cc @caroqliu

@amp-owners-bot amp-owners-bot bot requested a review from kristoferbaxter June 15, 2020 18:12
@samouri samouri removed the request for review from kristoferbaxter June 15, 2020 18:13
@samouri samouri self-assigned this Jun 15, 2020
@samouri samouri requested a review from caroqliu June 15, 2020 18:34
@caroqliu
Copy link
Contributor

One thing to consider here: I believe the original motivation for putting rrule directly in the node_modules is so it would get opted into auto version upgrades with renovate bot. If we want to use some modified unchanging version like rrule-without-luxon we should be able to place it in third_party/ instead of forking from your repo. /cc @rsimha

@samouri
Copy link
Member Author

samouri commented Jun 23, 2020

After testing, I've learned that the esm version of rrule adds 12.01KB whereas the es5 version adds 12.68KB.
I was surprised by how well the es5 version minifies based on usage (from 50kb!). It opens up another possibility for us to upstream a fix and use the built es5 version.

Testing this out now here jkbrzt/rrule#410

@samouri samouri changed the title amp-date-picker: restore rrule support, via a fork amp-date-picker: restore rrule support Jun 25, 2020
.renovaterc.json Outdated Show resolved Hide resolved
@samouri
Copy link
Member Author

samouri commented Jun 25, 2020

@rsimha: do you have any preference between using a fork of rrule that lives within third_party vs. patching it within the update_packages command?

@samouri samouri force-pushed the rrule branch 2 times, most recently from 3f1c0c6 to aa04c4c Compare June 29, 2020 16:42
@rsimha
Copy link
Contributor

rsimha commented Jun 29, 2020

@rsimha: do you have any preference between using a fork of rrule that lives within third_party vs. patching it within the update_packages command?

Sorry about the late reply. My preference is to patch node_modules/rrule/ during gulp update-packages for two reasons: a) there is precedent for doing so, and b) we'll benefit from regular updates to rrule and still retain the ability to patch the JS file.

If you check in a copy to third_party, there's a risk that it will bit-rot over time, and if there ever are security vulnerabilities, we will never be alerted. (This is why we moved to node_modules in the first place.)

@samouri
Copy link
Member Author

samouri commented Jun 29, 2020

Oh no, while this works in uncompiled mode (browserify), when its compiled (cc) I get errors that I haven't been able to debug:
Screen Shot 2020-06-29 at 1 56 07 PM

Also, @rsimha, re the second point:

b) we'll benefit from regular updates to rrule and still retain the benefit of being able to patch the JS file.

This is still suboptimal because an rrule update may break the patch. I don't see a good answer here without an upstreamed fix or manually periodically updating rrule.

@rsimha
Copy link
Contributor

rsimha commented Jun 29, 2020

This is still suboptimal because an rrule update may break the patch. I don't see a good answer here without an upstreamed fix or manually periodically updating the src.

Yeah. Hopefully your patch is targeted enough that it will always work. Perhaps you could make the replacement optional and print a non-blocking warning if it's missing, so that if a future version stops importing luxon, we'll get to know without breaking compilation.

Edit: I should mention this is why we have Renovate. All subsequent rrule updates are tested, and if a breaking change is detected, we'll have a chance to fix it before updating the version used by AMP. (This is what we do today for closure compiler updates, many of which are potentially breaking.)

@samouri
Copy link
Member Author

samouri commented Jun 30, 2020

print a non-blocking warning if it's missing

I'm not sure this makes sense considering we run update-packages more often than we reinstall the local node_modules, which is why they use writeIfModified (on most runs, the node_modules have already been patched so no work is necessary).


Separately, something interesting I ran in to is that browserify and cc seem to deal with es6 imports of cjs modules differently. Namely that CC pretends everything is a default import, whereas browserify is flattened one level.

So this is valid in cc:

import * as rrule from 'rrule'
const rrulestr = rrule.default.rrulestr;

And this is a working representation in browserify:

import * as rrule from 'rrule'
const rrulestr = rrule.rrulestr;

@samouri
Copy link
Member Author

samouri commented Jun 30, 2020

@caroqliu / @rsimha: this is ready for a review now :)

Copy link
Contributor

@rsimha rsimha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

build-system/tasks/update-packages.js Outdated Show resolved Hide resolved
@@ -42,6 +42,7 @@ const COMMON_GLOBS = [
'node_modules/intersection-observer/intersection-observer.install.js',
'node_modules/promise-pjs/package.json',
'node_modules/promise-pjs/promise.mjs',
'node_modules/rrule/dist/es5/rrule.min.js',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OMG, you got this to work!

giphy-downsized

Copy link
Contributor

@caroqliu caroqliu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 🔥 🔥

import {requireExternal} from '../../../src/module';

const rrulestr = rrule.default.rrulestr || rrule.rrulestr; // CC imports into .default, browserify flattens a layer.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Please move this into tryParseRrulestr.

Copy link
Member Author

@samouri samouri Jun 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes more sense where it is, considering ideally it would even be import {rrulestr} from 'rrule';. We can discuss and i'd be happy to move it in a teeny future PR if it makes the most sense / I misunderstood the reasoning

@samouri
Copy link
Member Author

samouri commented Jun 30, 2020

sidebar: i realized that amp-date-picker currently accepts dates that are not the ISO 8601. We should either change the documentation or make the code more strict.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

amp-date-picker highlighted/blocked attributes do not work
6 participants