diff --git a/CHANGES.md b/CHANGES.md index 9039fd525..0b213deef 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,11 +6,13 @@ #### Other - Add ES2015 module build ([#152]) +- Use query-string module instead of qs to save on bytes ([#121]) [HEAD]: /~https://github.com/rackt/history/compare/latest...HEAD [#146]: /~https://github.com/rackt/history/pull/146 [#152]: /~https://github.com/rackt/history/pull/152 [#167]: /~https://github.com/rackt/history/pull/167 +[#121]: /~https://github.com/rackt/history/issues/121 ## [v1.13.1] > Nov 13, 2015 diff --git a/docs/QuerySupport.md b/docs/QuerySupport.md index 9cf0b68dd..dbf1c627c 100644 --- a/docs/QuerySupport.md +++ b/docs/QuerySupport.md @@ -5,22 +5,24 @@ Support for parsing and serializing [URL queries](Glossary.md#query) is provided ```js import { createHistory, useQueries } from 'history' -// Use the built-in query parsing/serialization. -let history = useQueries(createHistory)() +const history = useQueries(createHistory)() -// Use custom query parsing/serialization. -let history = useQueries(createHistory)({ +history.listen(function (location) { + console.log(location.query) +}) +``` + +If you need custom query parsing and/or serialization, you can override either using the `parseQueryString` and `stringifyQuery` options, respectively. + +```js +const history = useQueries(createHistory)({ parseQueryString: function (queryString) { - return qs.parse(queryString) + // TODO: return a parsed version of queryString }, stringifyQuery: function (query) { - return qs.stringify(query, { arrayFormat: 'brackets' }) + // TODO: return a query string created from query } }) - -history.listen(function (location) { - console.log(location.query) -}) ``` Query-enhanced histories also accept URL queries as trailing arguments to `pushState`, `replaceState`, `createPath`, and `createHref`. diff --git a/modules/useQueries.js b/modules/useQueries.js index 2cc5a5b02..fbe9e30b8 100644 --- a/modules/useQueries.js +++ b/modules/useQueries.js @@ -1,15 +1,25 @@ -import qs from 'qs' +import warning from 'warning' +import { parse, stringify } from 'query-string' import runTransitionHook from './runTransitionHook' import parsePath from './parsePath' const SEARCH_BASE_KEY = '$searchBase' function defaultStringifyQuery(query) { - return qs.stringify(query, { arrayFormat: 'brackets' }).replace(/%20/g, '+') + return stringify(query).replace(/%20/g, '+') } -function defaultParseQueryString(queryString) { - return qs.parse(queryString.replace(/\+/g, '%20')) +const defaultParseQueryString = parse + +function isNestedObject(object) { + for (const p in object) + if (object.hasOwnProperty(p) && + typeof object[p] === 'object' && + !Array.isArray(object[p]) && + object[p] !== null) + return true + + return false } /** @@ -45,6 +55,12 @@ function useQueries(createHistory) { if (!query || (queryString = stringifyQuery(query)) === '') return location + warning( + stringifyQuery !== defaultStringifyQuery || !isNestedObject(query), + 'useQueries does not stringify nested query objects by default; ' + + 'use a custom stringifyQuery function' + ) + if (typeof location === 'string') location = parsePath(location) diff --git a/package.json b/package.json index 1a3558cb0..b58321032 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "dependencies": { "deep-equal": "^1.0.0", "invariant": "^2.0.0", - "qs": "^4.0.0", + "query-string": "^3.0.0", "warning": "^2.0.0" }, "devDependencies": {