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

Use a unique querystring package instead of three different ones #8300

Merged
merged 4 commits into from
Aug 1, 2018

Conversation

youknowriad
Copy link
Contributor

This PR updates our code base to use a unique querystring package instead of three different ones. I settled on http-build-query because it's the PHP compliant one.

Testing instructions

  • Check the term selectors
  • Check the latest posts block
  • Check the embeds
  • Check the page attributes panel (parent page)
  • Check adding links (autocompletion)

@youknowriad youknowriad added the [Type] Code Quality Issues or PRs that relate to code quality label Jul 30, 2018
@youknowriad youknowriad self-assigned this Jul 30, 2018
@youknowriad youknowriad requested a review from a team July 30, 2018 15:36
@aduth
Copy link
Member

aduth commented Jul 30, 2018

I settled on http-build-query because it's the PHP compliant one.

What is different about how PHP encodes a querystring than what these other packages are offering?

aduth
aduth previously requested changes Jul 30, 2018
Copy link
Member

@aduth aduth left a comment

Choose a reason for hiding this comment

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

A few things:

  • Almost every single one of these instances would be better off using addQueryArgs from the @wordpress/url package.
  • On that note, addQueryArgs uses the url built-in to format, which itself adopts the behavior of the querystring built-in, so we still have inconsistency.
  • On that note, the url shim used by Webpack (node-url) is much larger than we probably want to be loading in the browser (source). We could consider updating this to use a querystring encoder directly as well.

"lodash": "^4.17.10",
"memize": "^1.0.5",
"querystring": "^0.2.0",
Copy link
Member

Choose a reason for hiding this comment

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

Aside: querystring is a built-in, so we never should have been defining it as a dependency.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, it's not black or white here because depending on the bundler used by the packages consuming this package, we should define it or not.

Copy link
Member

@aduth aduth Jul 30, 2018

Choose a reason for hiding this comment

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

Hmm, an interesting point. I'm still not sure it's needed, since what's published to npm should be targeting Node (CommonJS, built-ins), even if ultimately it's consumed in a web context through a bundler.

@youknowriad
Copy link
Contributor Author

What is different about how PHP encodes a querystring than what these other packages are offering?

The difference is the way arrays are passed in query strings. The ServerSideRender component had a bug because of that and now has a unit test to check this. #7339

@aduth
Copy link
Member

aduth commented Jul 30, 2018

The difference is the way arrays are passed in query strings. The ServerSideRender component had a bug because of that and now has a unit test to check this. #7339

Would be good if we could communicate this somehow. Maybe not as part of this pull request, but ideally we should consolidate most all use to use addQueryArgs, then somewhere in the file / function include an inline code comment explaining the distinction.

@chrisvanpatten
Copy link
Member

chrisvanpatten commented Jul 30, 2018

The @wordpress/url addQueryArgs would need to be rewritten to use http-build-query (or an inlined version of that code). Not a big deal, but just worth noting.

Would also likely need to rebuild the parse method since I expect node's URL parser also wouldn't correctly interpret PHP-style query strings.

@aduth
Copy link
Member

aduth commented Jul 30, 2018

The @wordpress/url addQueryArgs would need to be rewritten to use http-build-query

Yes, I suspect it will, and further suggest that it'd be a good thing for us to do so.

@youknowriad youknowriad dismissed aduth’s stale review July 31, 2018 08:38

Good call, updated to use @wordpress/url

@youknowriad
Copy link
Contributor Author

I updated the @wordpress/url package. It now relies on the widely used qs package which is also php compatible. I prefered this one because we need both parsing and serializing with PHP compatible querystrings.

@gziolo
Copy link
Member

gziolo commented Jul 31, 2018

How nice, love this change ❤️

aduth
aduth previously requested changes Jul 31, 2018
@@ -65,17 +65,17 @@ const applyWithDispatch = withDispatch( ( dispatch ) => {
const applyWithAPIDataItems = withAPIData( ( { postType, postId } ) => {
const isHierarchical = get( postType, [ 'hierarchical' ], false );
const restBase = get( postType, [ 'rest_base' ], false );
const queryString = stringify( {
const queryString = {
Copy link
Member

Choose a reason for hiding this comment

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

queryString isn't the most accurate name for this variable assignment any longer. Maybe just query.

@@ -19,7 +19,8 @@
"main": "build/index.js",
"module": "build-module/index.js",
"dependencies": {
"@babel/runtime": "^7.0.0-beta.52"
"@babel/runtime": "^7.0.0-beta.52",
Copy link
Member

Choose a reason for hiding this comment

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

Aside: Why is @babel/runtime a dependency for this package?

Copy link
Member

Choose a reason for hiding this comment

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

We put it as a dependency for all packages that have transpiled code published to npm. We didn't find a better solution so far. This is what Babel docs recommend:

NOTE - Production vs. development dependencies

In most cases, you should install @babel/plugin-transform-runtime as a development dependency (with --save-dev).

npm install --save-dev @babel/plugin-transform-runtime

and @babel/runtime as a production dependency (with --save).

npm install --save @babel/runtime

The transformation plugin is typically used only in development, but the runtime itself will be depended on by your deployed/published code. See the examples below for more details.

https://new.babeljs.io/docs/en/next/babel-plugin-transform-runtime.html#installation


return format( { ...parsedURL, query } );
return stringifyURL( { ...parsedURL, search: stringify( query ) } );
Copy link
Member

Choose a reason for hiding this comment

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

I'd be motivated to simplify this function further so we can remove the dependency on url (as mentioned previously, it's quite large).

I think this should work okay?

const search = stringify( args );
const joiner = url.indexOf( '?' ) === -1 ? '?' : '&';
return url + joiner + search;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think there's a difference between the two implementation. In this particular case, we don't overwrite already present args in the url query string, but I think I can update the implementation to avoid the url package and still override existing keys.

@@ -24,6 +24,13 @@ describe( 'addQueryArgs', () => {

expect( addQueryArgs( url, args ) ).toBe( 'https://andalouses.example/beach?night=false&sun=true&sand=false' );
} );

test( 'should update args to an URL with array parameters', () => {
Copy link
Member

Choose a reason for hiding this comment

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

Do we use test or do we use it ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

😅I was not even aware it exists

Copy link
Member

Choose a reason for hiding this comment

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

We use both. I'm more interested in which one we should settle on. I don't care which it is, just that it's consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we use it more, so probably better to settle on this one?

Copy link
Member

Choose a reason for hiding this comment

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

test is default if you check Jest docs 🤷‍♂️

@youknowriad youknowriad dismissed aduth’s stale review July 31, 2018 15:17

It should be fine now.

Copy link
Member

@aduth aduth left a comment

Choose a reason for hiding this comment

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

Looks good 👍

@youknowriad youknowriad merged commit 0c96693 into master Aug 1, 2018
@youknowriad youknowriad deleted the update/querystring branch August 1, 2018 08:49
@danielbachhuber danielbachhuber added this to the 3.5 milestone Aug 1, 2018
@@ -19,7 +19,8 @@
"main": "build/index.js",
"module": "build-module/index.js",
"dependencies": {
"@babel/runtime": "^7.0.0-beta.52"
"@babel/runtime": "^7.0.0-beta.52",
"qs": "^6.5.2s"
Copy link
Member

Choose a reason for hiding this comment

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

See the issue on this line? 😱

We really need to do something to hold ourselves more accountable for published packages working as advertised. This line makes the packages largely unusable, or at least in my attempts to use @wordpress/components on plnkr.co

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wonder how it worked on Calypso :)

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, maybe npm is resilient enough to be allowing the extra character? At least based on the resolved qs in package-lock.json.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Type] Code Quality Issues or PRs that relate to code quality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants