1

I am creating a jQuery Plugin for building a form builder. The code is going to be very lengthy. I don't wanna keep everything in just one file. To achieve this I am trying to break everything into ES6 modules but JS is throwing a Syntax error.

Uncaught SyntaxError: Unexpected identifier

Uncaught TypeError: $(...).formBuilder is not a function

Here's my code:

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);
    });
}
0

1 Answer 1

2

I had to make two changes to get your code to run (in Chrome/Firefox):

First, from MDN

The import statement cannot be used in embedded scripts unless such script has a type="module".

This is a little misleading: "embedded script" sounds like it wouldn't include a src= script...but in practice it doesn't seem to work without it.

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

Second, module scripts are lazy-loaded, which means your final script tag will be executed before index.js is actually loaded/parsed. You can change this by using the jQuery ready callback.

<script>
  $(() => {
    $("#form-builder").formBuilder();
  });
</script>
Sign up to request clarification or add additional context in comments.

4 Comments

I knew your first point that I need to use type='module' to get in work. but I have seen many jquery plugins which are using ES6 modules but we just import them without specifying this "type" attribute. How they do this>
Is it possible they are being transpiled via babel/webpack? That's a fairly common technique: write the module using es6, but then transpile/pack/minify the production code.
@David784 How would a boilerplate of such a ES6 jQuery plugin look like? Does the plugin declare jquery as a peer dependency in its package.json?
@tonix Bit much for a comment in another question, but basically: If you're asking how to write a browser script type=module, I'd start here. If you're asking about babel, I'd recommend googling "babel es6 module" and start there. Best way to do it is just to get started and if you run into a specific problem you can't solve, post a new question with minimal reproducible example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.