【问题标题】:How to use ES6 modules while creating jQuery plugin?创建 jQuery 插件时如何使用 ES6 模块?
【发布时间】:2019-02-10 18:46:23
【问题描述】:

我正在创建一个用于构建表单构建器的 jQuery 插件。代码会很长。我不想将所有内容都保存在一个文件中。 为了实现这一点,我试图将所有内容分解为 ES6 模块,但 JS 抛出了语法错误。

Uncaught SyntaxError: Unexpected identifier

未捕获的类型错误:$(...).formBuilder 不是函数

这是我的代码:

index.html

<!DOCTYPE html>
<html>
<head>
  <title>Form Builder</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="style.css">
  
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css">

  <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/3.0.1/mustache.min.js"></script>

  <!-- <script src="functions.js"></script> -->
  <script src="index.js"></script>
</head>
<body>
    <div id="form-builder"></div>
</body>
</html>
<script type="text/javascript">
    $("#form-builder").formBuilder();
</script>

index.js

import formBuilder from './functions.js'

(function($){
    $.fn.formBuilder = function(){
        formBuilder()
    }
}(jQuery))

functions.js

export default function formBuilder(){
    $.get('template.mst', function(template) {
            let rendered = Mustache.render(template, fieldsData);
            $('#form-builder').html(rendered);
    });
}

【问题讨论】:

    标签: javascript jquery ecmascript-6 jquery-plugins


    【解决方案1】:

    我必须进行两项更改才能让您的代码运行(在 Chrome/Firefox 中):

    首先,来自MDN

    import 语句不能用于嵌入式脚本,除非此类脚本具有 type="module"。

    这有点误导:“嵌入式脚本”听起来好像不包含 src= 脚本……但实际上,如果没有它,它似乎无法工作。

    <script type="module" src="index.js"></script>
    

    其次,模块脚本是延迟加载的,这意味着您的最终script 标签将在index.js 实际加载/解析之前执行。您可以使用 jQuery ready 回调来更改此设置。

    <script>
      $(() => {
        $("#form-builder").formBuilder();
      });
    </script>
    

    【讨论】:

    • 我知道你的第一点,我需要使用 type='module' 来工作。但我见过许多使用 ES6 模块的 jquery 插件,但我们只是在没有指定此“类型”属性的情况下导入它们。他们是如何做到的>
    • 它们是否有可能通过 babel/webpack 进行转译?这是一种相当常见的技术:使用 es6 编写模块,然后编译/打包/缩小生产代码。
    • @David784 这样一个 ES6 jQuery 插件的样板会是什么样子?插件是否在其package.json 中将jquery 声明为peer dependency
    • @tonix 对另一个问题的评论有点多,但基本上:如果你问如何编写浏览器script type=module,我会开始here。如果您询问 babel,我建议您使用谷歌搜索“babel es6 模块”并从那里开始。最好的方法就是开始,如果遇到无法解决的特定问题,请通过minimal reproducible example 发布新问题。