摆脱jQuery到Svelte的烦恼

大家好。

我是一名后端开发人员,我会尽力解决前端任务,也就是说,在jQuery上,它在2015年可用,现在可以使用。但是有了Vue和React,这不再是一个麻烦了。出于对一种特殊方式的热爱,我决定精通Angular / React / Vue(尚未经过数百万开发人员的测试),因此决定尝试Svelte

在完成了教科书中的一些练习后,我决定继续练习。为此,我参加了一项成功完成的测试任务。

在分配任务时,有必要检查任务列表和该列表中的一项任务,不需要CRUD。

客户端部分被实现为SPA,并且所有与DOM的工作都是通过jQuery完成的,它是用Svelte替换jQuery的绝佳选择。

在下文中,我将讨论此过程中的第一个障碍,当然还有如何克服这些障碍。
Svelte教程非常易于访问和直观,但是如何将Svelte嵌入到任意项目中尚不清楚,因为Svelte不是像jQuery这样的库,而是一个编译器,也就是说,使用Svelte指令编写的代码必须以某种方式编译为本机JS。

另一个绊脚石是使用

$

在Svelte中,这是一个保留字符,因此在将由Svelte编译的代码中使用它会导致错误:


[!] (plugin svelte) ValidationError: $ is an illegal variable name

使用`$


当然,可能会出现问题:如果将jQuery完全更改为Svelte,`$`是什么样的?
是的,这个问题是合理的,但是如果您考虑一下,问题就会变得很清楚-您不需要全部吃掉大象,有经验的人也可以部分吃掉大象。从使用jQuery到使用Svelte的过渡,这将是一系列原子重构,进度将始终可见,并且整个“系统”将始终处于工作状态。

计划是这样的:我们重写一块,测试,修复,重写下一块,依此类推,直到我们吃掉了整个大象。

$的问题仅出现在Svelte编译的代码中,我已将所有SPA逻辑移至“ business-process.js”文件,无需解决此问题,但“ business-process.js”中的所有代码都应转到App.svelte和其他相关应用程序组件。

第一次重构后,App.svelte出现以下代码:


<script>
    jQuery(function ($) {

        function loadStartScreen() {
        loadPaging(0, settings.capacity);
        loadPage(0, settings.capacity);
        }

        loadStartScreen();

        async function search(sample) {
            $('#paging').empty();
            $.ajax({
                type: "GET",
                url: `/api/v1/task/search/${sample}/`,
                dataType: "json",
                success: renderTasks,
                error: function (jqXHR, textStatus, errorThrown) {
                },
                timeout: 500,
            });
        }

        $("#search").submit(async function (event) {
            event.preventDefault();
            const sample = $("#sample").val();

            if (sample) {
                search(sample);
            }
            if (!sample) {
                loadStartScreen();
            }
        });
    });
</script>

<div class="container">
    <h1>  </h1>

    <form class="form-horizontal" id="search">
        <div class="form-group">
            <label class="control-label col-sm-2" for="sample">
            
            </label>
            <div class="col-sm-10">
                <input id="sample" class="form-control " type="search"
                 placeholder="  " 
                 autofocus autocomplete="on" />
            </div>
        </div>
    </form>
    <div id="taskList">
    </div>
    <div id="paging">
    </div>

该代码正在运行,实际上实际上尚未使用Svelte,在此阶段,Svelte仅生成插入到其中的HTML代码。

<body>

变量$在调用中被隔离

jQuery(function ($) {});

没有命名冲突。

我们将样本变量与id =“ sample”的输入元素的值绑定:


                <input id="sample" class="form-control " type="search"
                 placeholder="  "
                 autofocus autocomplete="on"
                 bind:value={sample}
                 />

在id =“ search”的form元素的Submit事件上,执行代码:


        $("#search").submit(async function (event) {
            event.preventDefault();

            if (sample) {
                search(sample);
            }
            if (!sample) {
                loadStartScreen();
            }
        });

此代码必须根据Svelte指令执行,我们将其重写:


<script>
    async function svelteSearch(event) {
        event.preventDefault();
        if (sample) {
            search(sample);
        }
        if (!sample) {
            loadStartScreen();
        }
    }
</script>
<form class="form-horizontal" id="search"
on:submit="{svelteSearch}">
</form>

代码可以编译,但是不起作用,因为search()函数是在jQuery范围内定义的(function($){}); 并且在全局范围内,此功能不可见。使用svelteSearch(event)将search()拉入一个范围:


<script>
    function loadStartScreen() {
        loadPaging(0, settings.capacity);
        loadPage(0, settings.capacity);
    }

    let sample = '';

    jQuery(function ($) {
        loadStartScreen();
    });
    async function search(sample) {
        $('#paging').empty();
        $.ajax({
            type: "GET",
            url: `/api/v1/task/search/${sample}/`,
            dataType: "json",
            success: renderTasks,
            error: function (jqXHR, textStatus, errorThrown) {
            },
            timeout: 500,
        });
    }
    async function svelteSearch(event) {
        event.preventDefault();
        if (sample) {
            search(sample);
        }
        if (!sample) {
            loadStartScreen();
        }
    }
</script>

此类代码无法编译:


[!] (plugin svelte) ValidationError: $ is an illegal variable name

该怎么办?去谷歌上查询!“ Svelte如何导入jquery”:如何在Svelte中使用jQuery
我不喜欢标记为“正确”的答案来导入第三方库(任意* .js),仅编写import *是不够的,您必须在rollup.config.js中注册它外部:


export default { external []};

带有window的第二个选项$需要更少的身体移动,并且由于我们计划完全放弃jQuery的使用,因此此导入指令是临时的,对导入的熟悉可以推迟到以后。

对堆栈溢出使用复制粘贴:


<script>
    function loadStartScreen() {
        loadPaging(0, settings.capacity);
        loadPage(0, settings.capacity);
    }
    jQuery(function ($) {
        loadStartScreen();
    });

    let sample = '';

    async function search(sample) {
        window.$('#paging').empty();
        window.$.ajax({
            type: "GET",
            url: `/api/v1/task/search/${sample}/`,
            dataType: "json",
            success: renderTasks,
            error: function (jqXHR, textStatus, errorThrown) {
            },
            timeout: 500,
        });
    }
    async function svelteSearch(event) {
        event.preventDefault();
        if (sample) {
            search(sample);
        }
        if (!sample) {
            loadStartScreen();
        }
    }
</script>

<div class="container">
    <h1>  </h1>
    <form class="form-horizontal" id="search"
    on:submit="{svelteSearch}">
        <div class="form-group">
            <label class="control-label col-sm-2" for="sample">
            
            </label>
            <div class="col-sm-10">
                <input id="sample" class="form-control " type="search"
                 placeholder="  "
                 autofocus autocomplete="on"
                 bind:value={sample}
                 />
            </div>
        </div>
    </form>
// ..skip..
</div>

它仍然有待摆脱:


    jQuery(function ($) {
        loadStartScreen();
    });

我们删除以下代码并将其添加到标记中:


<svelte:window on:load = {loadStartScreen} />

做完了

Svelte文档中,您可以找到:
<svelte:document>
<svelte:document>标记,与<svelte:window>一样,为您提供了一种方便的方法,以声明方式将事件侦听器添加到文档对象。这对于侦听不会在窗口上触发的事件(例如mouseenter和mouseleave)很有用。

实际上,我们有:


[!] (plugin svelte) ParseError: Valid <svelte:...> tag names are svelte:head, svelte:options, svelte:window, svelte:body, svelte:self or svelte:component

也就是说,该标签是从代码中删除的,但是他们忘记了从文档中删除它,令我惊讶的是,Svelte不是由众神开发的,而是由那些也倾向于将其留待以后忘记的人们开发的。

我告诉我如何在Svelte代码中集成jQuery。

如何在JS代码中编译Svelte指令


我们将一个空项目泵入一个单独的文件夹,如Svelte博客所述(一路安装Node.js)。现在,我们将下载的文件传输到我们项目的目录中。

我们将文件从“ public”传输到客户端(用户浏览器)要下载的文件,我将其“ public / assets / Site”下载,不需要“ global.css”样式,也没有传输此文件。

我将文件“ public / index.html”转移到服务器将要用于查看的模板所在的位置:“ view / Site / index.html”。

来自“ src”的文件将添加到前端的源-“ src / frontend”。

描述前端来源的文件:

  • rollup.config.js
  • package-lock.json
  • package.json

我移到了根目录,IDE在这里找到了它们并处理了所有事情(已安装的依赖项)。
现在,您需要在JS中更改Svelte指令的编译配置。

打开rollup.config.js并更改文件路径:


export default {
	input: 'src/frontend/main.js',
	output: {
		sourcemap: true,
		format: 'iife',
		name: 'app',
		file: 'public/assets/Site/bundle.js'
	},
	plugins: [
		svelte({
			dev: !production,
			css: css => {
				css.write('public/assets/Site/bundle.css');
			}
		}),

这就是将Svelte初始集成到现有项目中的困难。

我们安装依赖项,并开始跟踪前端源代码中的更改以进行即时编译:

npm install
npm run dev

不要忘记


编辑演示文稿模板(在我的情况下,它是“ view / Site / index.html”):

  • 身体标签内的所有内容均可移植到App.svelte
  • 将链接添加到必要的资源文件

    
    <head>
      <link rel='stylesheet' href='/assets/Site/bundle.css'>
    </head>
    
  • 在body标签之后,向生成的程序集文件添加“链接”:

    
    <body>
    </body>
    <script src='/assets/Site/bundle.js'></script>
    


整个代码可以在存储库中查看

jQuery在该项目中的最终放弃仍然遥遥无期,但本文并非以此为目的,而是关于在您的代码中实现Svelte的第一步,以及最简单的事情。

谢谢您的关注。

威胁
转换的结果如何,您可以在下一篇文章“ 怎么样 ”中阅读

Source: https://habr.com/ru/post/undefined/


All Articles