信息发布→ 登录 注册 退出

jQuery一键移除使前端项目脱离对它的依赖

发布时间:2026-01-11

点击量:
目录
  • 前言
  • 使用方式
    • index.html
    • main.js
    • 先全局下载一下
  • 补充

    前言

    大家好,我是零一。虽然现在很多前端项目都在用Vue、React,但依赖jquery的项目也不少,尤其是年代比较久远的项目,那些还正在维护jquery项目的你,是否想将jquery从你的项目中移除?毕竟这个库那么大,你能用到的代码也就只有15%~30%,而且jquery对各个浏览器的兼容性也做了很大的处理(代码量up up),但其实很多老项目也不会去考虑兼容很边缘的浏览器了,所以其实jquery中兼容处理的代码也没太大必要

    最近新发现了一个有意思的工具,仅上线2周,就有600+的Star,它说能帮助你的项目脱离对jquery的依赖,感觉是个不错的想法,一起来看看吧~

    使用方式

    这个工具的名字叫replace-jquery,据说是能帮你从项目中自动查找所有用到的jquery方法,并生成一套原生js的方法去替代

    先来搞一个极简的jquery项目

    index.html

    main.js

    测试一下页面的功能,是OK的

    接下来我们用 replace-jquery 工具试着移除一下 main.js 中的jquery代码

    先全局下载一下

    npm install -g replace-jquery

    然后在项目目录使用,语法为

    replace-jquery 目标js文件 生成的js文件

    replace-jquery main.js newMain.js

    该工具会自动找到你文件中所有用到的jquery方法。此处有一个确认的步骤,你可以选择想要替换哪些方法(默认是全选的)

    按回车键即可完成替换,并生成新的文件

    export class Utils {
        constructor(selector) {
            this.elements = Utils.getSelector(selector);
            this.element = this.get(0);
            return this;
        }
        on(events, listener) {
            events.split(' ').forEach((eventName) => {
                this.each((el) => {
                    const tNEventName = Utils.setEventName(el, eventName);
                    if (!Array.isArray(Utils.eventListeners[tNEventName])) {
                        Utils.eventListeners[tNEventName] = [];
                    }
                    Utils.eventListeners[tNEventName].push(listener);
                    // https://github.com/microsoft/TypeScript/issues/28357
                    if (el) {
                        el.addEventListener(eventName.split('.')[0], listener);
                    }
                });
            });
            return this;
        }
        remove() {
            this.each((el) => {
                el.parentNode.removeChild(el);
            });
            return this;
        }
        css(css, value) {
            if (value !== undefined) {
                this.each((el) => {
                    Utils.setCss(el, css, value);
                });
                return this;
            }
            if (typeof css === 'object') {
                for (const property in css) {
                    if (Object.prototype.hasOwnProperty.call(css, property)) {
                        this.each((el) => {
                            Utils.setCss(el, property, css[property]);
                        });
                    }
                }
                return this;
            }
            const cssProp = Utils.camelCase(css);
            const property = Utils.styleSupport(cssProp);
            return getComputedStyle(this.element)[property];
        }
        static getSelector(selector, context) {
            if (selector && typeof selector !== 'string') {
                if (selector.length !== undefined) {
                    return selector;
                }
                return [selector];
            }
            context = context || document;
            // For performance reasons, use getElementById
            // eslint-disable-next-line no-control-regex
            const idRegex = /^#(?:[\w-]|\\.|[^\x00-\xa0])*$/;
            if (idRegex.test(selector)) {
                const el = document.getElementById(selector.substring(1));
                return el ? [el] : [];
            }
            return [].slice.call(context.querySelectorAll(selector) || []);
        }
        get(index) {
            if (index !== undefined) {
                return this.elements[index];
            }
            return this.elements;
        }
        each(func) {
            if (!this.elements.length) {
                return this;
            }
            this.elements.forEach((el, index) => {
                func.call(el, el, index);
            });
            return this;
        }
        static setEventName(el, eventName) {
            // Need to verify https://stackoverflow.com/questions/1915341/whats-wrong-with-adding-properties-to-dom-element-objects
            const elementUUId = el.eventEmitterUUID;
            const uuid = elementUUId || Utils.generateUUID();
            // eslint-disable-next-line no-param-reassign
            el.eventEmitterUUID = uuid;
            return Utils.getEventName(eventName, uuid);
        }
        static setCss(el, prop, value) {
            // prettier-ignore
            let cssProperty = Utils.camelCase(prop);
            cssProperty = Utils.styleSupport(cssProperty);
            el.style[cssProperty] = value;
        }
        static camelCase(text) {
            return text.replace(/-([a-z])/gi, (s, group1) => group1.toUpperCase());
        }
        static styleSupport(prop) {
            let vendorProp;
            let supportedProp;
            const capProp = prop.charAt(0).toUpperCase() + prop.slice(1);
            const prefixes = ['Moz', 'Webkit', 'O', 'ms'];
            let div = document.createElement('div');
            if (prop in div.style) {
                supportedProp = prop;
            } else {
                for (let i = 0; i < prefixes.length; i++) {
                    vendorProp = prefixes[i] + capProp;
                    if (vendorProp in div.style) {
                        supportedProp = vendorProp;
                        break;
                    }
                }
            }
            div = null;
            return supportedProp;
        }
        static generateUUID() {
            return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
                // eslint-disable-next-line no-bitwise
                const r = (Math.random() * 16) | 0;
                // eslint-disable-next-line no-bitwise
                const v = c === 'x' ? r : (r & 0x3) | 0x8;
                return v.toString(16);
            });
        }
        static getEventName(eventName, uuid) {
            return `${eventName}__EVENT_EMITTER__${uuid}`;
        }
    }
    Utils.eventListeners = {};
    export default function $utils(selector) {
        return new Utils(selector);
    }
    

    简单看了一下,似乎就是把我们用到的jquery方法替换成了简单的原生方法,并封装在Utils这个类中,那么我们每次调用$("xxx")时,其实就是在调用该类上的方法,那么对这个文件做一些修改

    // 此处删除export
    class Utils {
    	// ...省略一些代码
    }
    Utils.eventListeners = {};
    // 此处删除 export default,并将函数$utils改成$
    function $(selector) {
        return new Utils(selector);
    }
    

    这样就相当于我们在全局模拟jquery定义了一个$方法。此时html文件中的jquery引用就可以删除了,并把我们刚才生成的文件引进来

    再去页面中尝试操作dom,可以看到效果跟之前一样,成功!

    补充

    如果你想用该工具生成jquery所有api的替代文件,即生成一个super-mini-jquery,你可以这么做

    replace-jquery --build-all super-mini-jquery.js

    将代码混淆丑化以后大概只有10kb

    因为这个工具刚发布才2个星期不到,只实现了大部分的jquery代码替换,比如ajax暂时是没办法替换的,你如果尝试去替换,工具也会提醒你

    总的来说,这个工具想法不错,希望后期能支持更多的语法替换!

    以上就是jQuery一键移除使项目脱离对它的依赖的详细内容,更多关于项目脱离jquery依赖的资料请关注其它相关文章!

    在线客服
    服务热线

    服务热线

    4008888355

    微信咨询
    二维码
    返回顶部
    ×二维码

    截屏,微信识别二维码

    打开微信

    微信号已复制,请打开微信添加咨询详情!