终于有人对 jQuery下手了,一键移除项目对它的依赖

简介: 大家好,我是零一。虽然现在很多前端项目都在用Vue、React,但依赖jquery的项目也不少,尤其是年代比较久远的项目,那些还正在维护jquery项目的你,是否想将jquery从你的项目中移除?毕竟这个库那么大,你能用到的代码也就只有15%~30%,而且jquery对各个浏览器的兼容性也做了很大的处理(代码量up up),但其实很多老项目也不会去考虑兼容很边缘的浏览器了,所以其实jquery中兼容处理的代码也没太大必要最近新发现了一个有意思的工具,仅上线2周,就有600+的Star,它说能帮助你的项目脱离对jquery的依赖,感觉是个不错的想法,一起来看看吧~

使用方式


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


先来搞一个极简的jquery项目


index.html


4ebd632be6b63659b17f7864f05b9bea.png


main.js


df081c87fa68a4c3931c2b658facfdad.png


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


503a17caf2176f8e5d9455c5248018cd.jpg


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


先全局下载一下


npm install -g replace-jquery


然后在项目目录使用,语法为replace-jquery 目标js文件 生成的js文件


replace-jquery main.js newMain.js


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


deee96670c2f2af48a1cc4498ded47da.png


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


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引用就可以删除了,并把我们刚才生成的文件引进来


831ac74aa378e556080a271b5bf24f9b.png


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


补充


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


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


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


51a862acce55e92041eeaa3d708183de.png


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


90ee782b7327c372531e04443abb69b4.png


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


对于这个工具,你们有什么看法,欢迎在评论区留言讨论~


我是零一,分享技术,不止前端。关注我,了解更多前端新姿势~

相关文章
|
5月前
|
JavaScript 前端开发 Java
bootsrap+jquery+组件项目引入文件的常见报错
bootsrap+jquery+组件项目引入文件的常见报错
47 0
|
11月前
|
JavaScript 前端开发 开发者
解决Vue项目中使用原生/jquery插件无法获取DOM的问题
解决Vue项目中使用原生/jquery插件无法获取DOM的问题记录。
228 1
|
移动开发 JavaScript 前端开发
前后端的展示页面.本项目采用了以下知识点.JSP Servlect HTML5 JQUERY JavaScript Css3 MYSQL Sping架包 和几个框架。(二)
前后端的展示页面.本项目采用了以下知识点.JSP Servlect HTML5 JQUERY JavaScript Css3 MYSQL Sping架包 和几个框架。
55 0
前后端的展示页面.本项目采用了以下知识点.JSP Servlect HTML5 JQUERY JavaScript Css3 MYSQL Sping架包 和几个框架。(二)
|
移动开发 JavaScript 前端开发
前后端的展示页面.本项目采用了以下知识点.JSP Servlect HTML5 JQUERY JavaScript Css3 MYSQL Sping架包 和几个框架。(一)
前后端的展示页面.本项目采用了以下知识点.JSP Servlect HTML5 JQUERY JavaScript Css3 MYSQL Sping架包 和几个框架。
65 0
前后端的展示页面.本项目采用了以下知识点.JSP Servlect HTML5 JQUERY JavaScript Css3 MYSQL Sping架包 和几个框架。(一)
|
JavaScript 前端开发 Java
jquery实现动态表格项目(表格增加删除/全选/表格变色特效等功能)(附源码+javaWEB开发如果需要可以直接使用)
jquery实现动态表格项目(表格增加删除/全选/表格变色特效) 🍅 Java学习路线:搬砖工的Java学习路线 🍅 作者:程序员小王 🍅 程序员小王的博客:https://www.wolai.com/wnaghengjie/ahNwvAUPG2Hb1Sy7Z8waaF 🍅 扫描主页左侧二维码,加我微信 一起学习、一起进步 🍅 欢迎点赞 👍 收藏 ⭐留言 📝
266 0
jquery实现动态表格项目(表格增加删除/全选/表格变色特效等功能)(附源码+javaWEB开发如果需要可以直接使用)
|
JavaScript
vue项目中如何使用jquery?
vue项目中如何使用jquery?
vue项目中如何使用jquery?
|
JavaScript
Vue.js - Vue 项目引入 JQuery 框架(上)
Vue.js - Vue 项目引入 JQuery 框架(上)
157 0
Vue.js - Vue 项目引入 JQuery 框架(上)
|
开发框架 JavaScript 前端开发
jQuery 已“死”?为清除技术债,我们删掉了前端所有 jQuery 依赖
近期,英国公共部门信息网站 GOV.UK 前端开发主管 Matt Hobbs 宣布该公司删除了 jQuery 作为所有前端应用程序的依赖项,这意味着“在所有 13 个 FE 应用程序中,JS 大小减少了 32 KB(31% ~49% 之间)”。
121 0
jQuery 已“死”?为清除技术债,我们删掉了前端所有 jQuery 依赖
|
JavaScript
在Vue项目中引入 ECharts 3D 路径图 Flights GL(需安装echarts、echarts-gl、jQuery依赖,已踩坑)
在Vue项目中引入 ECharts 3D 路径图 Flights GL(需安装echarts、echarts-gl、jQuery依赖,已踩坑)
1299 0
在Vue项目中引入 ECharts 3D 路径图 Flights GL(需安装echarts、echarts-gl、jQuery依赖,已踩坑)