专栏首页前端印象终于有人对 jQuery下手了,一键移除项目对它的依赖

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

大家好,我是零一。虽然现在很多前端项目都在用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暂时是没办法替换的,你如果尝试去替换,工具也会提醒你

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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • GitHub:我们是这样弃用jQuery的

    最近,我们将jQuery 完全从 GitHub.com 的前端代码中移除了,这标志着我们数年来逐步移除 jQuery这个渐进式的过程终于结束了,这对我们来说是一...

    Fundebug
  • 用于H5的移动开发框架

    今天给大家介绍10款有关HTML5移动开发APP开发框架,这几款框架都是比较优秀的移动 Web 开发框架,能够帮助开发者更加高效的开发移动Web应用。.

    javascript艺术
  • 目前比较火的前端框架及UI组件

    看到的一篇总结性的文章,收藏一下,感兴趣的可以自己看看,哪些是已经会的,哪些是没听说过的,哪些是一知半解的,都可以稍微看看。

    何处锦绣不灰堆
  • 在 ASP.NET Core 项目中使用 npm 管理你的前端组件包

      在项目的前端开发中,对于绝大多数的小伙伴来说,当然,也包括我,不可避免的需要在项目中使用到一些第三方的组件包。这时,团队中的小伙伴是选择直接去组件的官网上下...

    程序员宇说
  • 11-移动端开发教程-zepto.js入门教程

    Zepto.js是一个轻量级的针对现代浏览器的JavaScript库, 它与jquery有着类似的api。 如果你会用jquery,那么你也会用zepto。 1...

    老马
  • 06-移动端开发教程-fullpage框架

    CSS3的新特性已经讲完了,接下来我们看一下jQuery的一个全屏jQuery全屏滚动插件fullPage.js。我们经常见到一些全屏的特绚丽页面,手指或者鼠标...

    老马
  • 06-移动端开发教程-fullpage框架

    CSS3的新特性已经讲完了,接下来我们看一下jQuery的一个全屏jQuery全屏滚动插件fullPage.js。我们经常见到一些全屏的特绚丽页面,手指或者鼠标...

    老马
  • ASP.NET Core 介绍和项目解读

    标签: ASP.NETCore 1. 前言 作为一个.NET Web开发者,我最伤心的时候就是项目开发部署时面对Windows Server上贫瘠的解决方案...

    潘成涛
  • 历时大半年,Github团队成功减少30kb依赖体积

    新人这时候犯嘀咕:“这工作量,我估保守点,逐步替换,一周开发,一周测试,2周上线?”

    公众号@魔术师卡颂
  • 【思考】为何弃用jQuery?(下)

    关于“下“的内容却迟迟没有动手,其中也有诸多事情干扰,也可以认为是借口,但我自己其实也是还没有想清楚该如何去说这个事。

    林小帅
  • awesome-javascript-cn

    JS 资源列表,内容包括:包管理器、加载器、测试框架、运行器、QA、MVC框架和库、模板引擎、数据可视化、时间轴、编辑器等等。 包管理器 管理着 JavaScr...

    guanguans
  • JQuery逐渐退出前端历史舞台?

    现在各大技术论坛经常有类似的问题出现,PHP是否过时了,JQuery是否已经被淘汰?前段时间GitHub宣布改版,并且放弃了JQuery依赖,而且发布文章...

    创译科技
  • 10个基于web的JavaScript最优秀的应用程序库和框架

    在所有可用于创建web应用程序的语言中,JavaScript可能是最健壮的库和框架选择。事实上,有太多的东西,很难弄清楚该用哪一个,尤其是当你刚刚开始的时候。

    程序你好
  • 2018年,JavaScript都经历了什么?

    The State of JavaScript调研已经连续做了3年(2016, 2017, 2018),今年一共调研了2万多个JS开发者。有这样一些有意思的发现...

    Fundebug
  • Node.js建站笔记-使用react和react-router取代Backbone

    斟酌之后,决定在《嗨猫》项目中引入react,整体项目偏重spa模式,舍弃部分server端的模板渲染,将一部分渲染工作交给前端react实现。 react拥有...

    寒月十八
  • 介绍几个移动web app开发框架

    jQuery Mobile框架能够帮助你快速开发出支持多种移动设备的Mobile应用用户界面。jQuery Mobile最新版本是1.4.0,默认主题采用扁平化...

    Java架构师历程
  • 都9102年了,还需要用到 jQuery 吗?[每日前端夜话0xB4]

    关于 jQuery 这个流行的 JavaScript 库如何死亡的问题一直在不断的被讨论。

    疯狂的技术宅
  • 基于web技术的操作系统安装器的设计

    ? 什么是基于web技术的安装器(web-based installer)? 传统的Linux操作系统安装需要启动一个LiveOS,然后在LiveOS中运行一...

    用户1214695
  • 移动端手势的七个事件库

    王小婷

扫码关注云+社区

领取腾讯云代金券