I'm a junior web developer. My current work is on a form-based server side web application. It was set up using jQuery. I'm now the primary person working on it. In a previous job, which was more front-end-centric, they decided to move away from jQuery. It was not needed anymore.* I heard it elsewhere as well. But I sometimes feel like I would like to write my own abstractions for DOM queries and operations.
e.g. quering
var theElement = document.querySelector('.ImTheOneYoureLookingFor')
if (theElement == null) {
throw new Error('query failed: .ImTheOneYoureLookingFor')
}
// do things
I thought an abstraction would be a good idea. Maybe someting like
/** @global */
function webQuery(selector) {
// throw if not 1 found
}
But this feels like writing my own jQuery. Is this good practice? Should I care less about my code going "straight" (no detours)?
[ADDITION] *(like Greg Brughardt noted in a comment) the reason to move away from jQuery were simpler and standardized added browser API's.
2 Answers 2
Custom abstractions should feel custom. That is, they should take advantage of knowing your particular needs. Without that you’re simply replacing a well known library with an obscure one that has little support.
Code reuse is a fine goal but must always be tempered with the goal of readability. Unfamiliar code comes with a cost. Be sure you find some way to make up for that.
As the "primary person" working on this the best thing you can do is find someone else to review the code. Preferably someone who may end up supporting it one day. Do this while you’re still willing to change your mind.
-
(I know I'm not allowed to write this kind of comments, but) thank you. These are valuable things to keep in mind. I'll resist my clear code tempation.pikachu– pikachu2022年10月08日 09:51:18 +00:00Commented Oct 8, 2022 at 9:51
-
@pikachu don’t resist. Temper. Get feedback early. Sometimes that nagging thought you’re trying to ignore is actually a good idea.candied_orange– candied_orange2022年10月08日 13:26:26 +00:00Commented Oct 8, 2022 at 13:26
What I did: (We'll see whether this was the right choice.)
1. Research on DOM API's
There's more than I knew of:
// jQuery => DOM pseudocode
const jQueryMapping = {
toggleClass(el, className, shouldBePresent) => el.classList.toggle(className, shouldBePresent),
parents(el, selector) ≈> el.closest(selector)
}
A good overview is found here: https://youmightnotneedjquery.com/ (from this answer's comments.)
(also note: you can use different methods for the same result: e.g. see parents
mapping above.)
2. Use utils for still oft repeated functions:
I kept 2 extra DOM functions I kept repeating. I felt it would increase conciseness. I added them under <file:./Shared/DOMUtils.js>
on the object const Shared_DOMUtils
. (We're not using JS modules).
const Shared_DOMUtils = {
/** throws if not found with an error message containing the selector. */
querySelectorSingle(parentElement, selector) => ...
/** returns as array instead of NodeList. */
querySelectorArray(parentElement, selector) => ...
}
- I changed the name from
webQuery
querySelectorX
like the native browser functions in order to ensure clarity for others. When there was no similar DOM - I also used
/** double asterisk comments */
in order to give a description in code editors. - To limit the length of the "pseudo-module" object and to signal these are custom methods, I use it like this:
(function () {
let my = Shared_DOMUtils
...
my.querySelectorSingle(...)
})()
createItemList(...)
ordisableInapplicableFields(...)
orshowHintForInputField(...)
. Something that has more direct connection to what your application is doing. 1/2