Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minimal Code not working when following "Getting Started" instructions #2584

Open
rzeta0 opened this issue Jan 7, 2024 · 3 comments
Open

Comments

@rzeta0
Copy link

rzeta0 commented Jan 7, 2024

I am new to modern web development so I am carefully following the instructions at the "Getting Started" page.

Context

I am using a python Flask web application server which successfully responds to a web browser with HTML and static content like CSS and javascript. There is no issue with these being correctly sent to the browser, as verified by "Inspect element / view source".

I have tried loading the editorjs using two methods: (1) CDN and (2) static file sent from the web server to the browser. Both of these follow the Getting Started instructions:

<script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest"></script>

or

<script src="editor.js"></script>

Problem 1: Which Library?

Actually, the link on the Getting Started page doesn't point to an official release of editor.js but a page of mostly pre-release versions. This is confusing for newcomers like me. However I scrolled down and found version v2.28.1 which didn't have a pre-release tag against it, and clicked on that. In the zip file there is no editor.js ... is this "release" meant for us to compile ourselves? If I then click on the "tags" tab and scroll down the list I see a v2.28.2 but again the zip doesn't have an editor.js (and why is this not on the main list?). If I go to the main git hub page - not linked from the Getting Started tutorial - I can see on the right that v.2.28.0 is the latest. Yes, I'm confused. This has editor.mjs and editor.umd.js .. as a newbie I don't know what these are and the Getting Started instructions don't mention it. I tried both.

Problem 2: Loading Library Fails

Back to the Getting Started tutorial, at the top of a new javascript file, includes as <script src= ..> just after the library is imported, I immediately import the library, as per the tutorial's example code

import EditorJS from '@editorjs/editor.mjs'; // and also tried editor.umd.js

This leads to an error in Firefox latest (

Uncaught SyntaxError: import declarations may only appear at top level of a module

In Safari latest, the error is different

SyntaxError: Unexpected identifier 'EditorJS'. import call expects one or two arguments.

I also tried the other options in the tutorial eg:

import EditorJS from '@editorjs/editorjs';

const editor = new EditorJS({
  /**
   * Id of Element that should contain Editor instance
   */
  holder: 'editorjs'
});

My Attempts to Solve This

I have been coding since the 1980s (!) but not modern web stuff, so I understand fundamentals but not the specifics. I asked around and people who are expert front end developers tell me I need "node/npm". This, if I understand, is a server-side javascript runtime framework. I'm not trying to do that - I',m just trying to load the library into the web browser and use it client side - as the Getting Started page suggests I can and should.

Also, is the use of "@" in the import statement something I need to replace when loading from a CDN or from a web server? Is it an alias that is resolved by node compiling it?

Summary

There are two key problems, irrespective of my own inexperience:

  1. Following the tutorial at the Getting Started pages doesn't work for newcomers as clearly some guidance / information is missing.

  2. There's a mismatch between the linked editor.js and actually finding the lates/official release. I still can't find a file named exactly "editor.js" on the GitHub pages.

@rzeta0 rzeta0 added the bug label Jan 7, 2024
@ConnectGrid
Copy link

ConnectGrid commented Jan 14, 2024

EditorJS has amazing potential, but seems to suffer from piecemeal design. There are several design decisions that makes one shake their head. For someone new to modern web app development, definitely don't use EditorJS as any sort of "perfect" example of how such a library should be designed. I've had to do some very fancy footwork to work around its bizarre approach to configuration, for example.

  • The naming convention of Tools and Tunes is very inconsistent.
  • Constructors for plugins is inconsistent (see Undo vs. DragDrop).

I'm currently using the hosted file in my projects, and it's working fine.
https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest

But I'm experiencing problems loading a Tune (Text Alignment), and that may be due to an incompatibility with the latest version of EditorJS. Their docs no longer match the tune's internal design.

Kudos to the contributors of this project, but we (the larger community) would love to see some cleaner guidelines and versioning of the library and add-ons.

@rzeta0
Copy link
Author

rzeta0 commented Jan 14, 2024

I finally managed to get a minimal code example working by:

  1. loading the libraries in the html <head>
  2. establishing the html elements
  3. only only then after but before loading my javascript which uses the editor.js object

I'm no expert but this seems to force sequential execution - forcing the use of the editor.js object only after the html (dom?) has completely loaded.

But this isn't what the Getting Started guide suggests.... so what is the standard pattern to use editor.js?

<!DOCTYPE html>
<html lang="en">

<head>
    <title>Quintus</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
    <script src="https://cdn.jsdelivr.net/npm/@editorjs/[email protected]/dist/editorjs.umd.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@editorjs/header@latest"></script>
    <script src="https://cdn.jsdelivr.net/npm/@editorjs/list@latest"></script>
</head>

<body>
    <h1>test header</h1
    <div>Test 1</div>
    <hr>
    <div id="editorjs"></div>
    <hr>
    <div>Test 2</div>
</body>

<script src="{{url_for('static', filename='quintus_editor.js')}}"></script>

</html>

@fyrye
Copy link

fyrye commented Jan 31, 2024

Would suggest for consistency, enforcing the version on all of the plugins and EditorJS core.
That way when one or the others are updated, they won't be out of sync with the core when using @latest and encounter BC breaks.
Allowing for you to functionally test any updates to the packages and see if they made changes that would impact your usage.

It seems the devs changed from using editor.js after v2.26.4 to UMD and MJS formats in v2.27+.
Meaning the documentation was appropriate for v2.26.4 and v2.26.5.

With that said, one of the newer approaches for using <script> tags as of 2018 is adding the type="module".

Unfortunately, using import outside of a package manager that compiles everything for you, also requires using specific version syntax of the packages, typically MJS or ESM.
Normally the desired ESM version can be retrieved automatically from the CDN by adding /+esm to the URL but a change in the EditorJS package has broken it.
Meaning using https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest/+esm no longer works like it used to but https://cdn.jsdelivr.net/npm/@editorjs/[email protected]/+esm will.

Looking at the /dist code library available at https://cdn.jsdelivr.net/npm/@editorjs/[email protected]/, you'll see there are two variants of the package, where one is .mjs (Module JavaScript) and another that is UMD (Universal Module Definition) as .umd.js.

Using the .mjs version will fix an issue with import EditorJS throwing an error for no export default.

So for an example of how to wire everything together with import:

<head>
<script type="module">
    /* alternative URLs for the version you want - either will work */
    // import EditorJS from "https://cdn.jsdelivr.net/npm/@editorjs/[email protected]/dist/editorjs.mjs";
    // import EditorJS from "https://cdn.jsdelivr.net/npm/@editorjs/[email protected]/dist/header.mjs";
    // import List from "https://cdn.jsdelivr.net/npm/@editorjs/[email protected]/dist/list.mjs";

    /* these are minified and tersed */
    import EditorJS from "https://cdn.jsdelivr.net/npm/@editorjs/[email protected]/+esm"
    import Header from "https://cdn.jsdelivr.net/npm/@editorjs/[email protected]/+esm";
    import List from "https://cdn.jsdelivr.net/npm/@editorjs/[email protected]/+esm";

    /* ES6 arrow function syntax for (function(){ })(); */
    (() => {
        'use strict';
        const container = document.getElementById('editorjs');
        const editor = new EditorJS({
            "holder": container,
            "tools": {
                "list": {
                    "class": List,
                    "inlineToolbar": true,
                    "config": {
                        "defaultStyle": "unordered"
                    }
                },
                "header": {
                    "class": Header,
                    "shortcut": "CMD+SHIFT+H",
                    "config": {
                        "placeholder": "Enter a header",
                        "levels": [2, 3, 4],
                        "defaultLevel": 3
                    }
                }
            }
        });
    })();
</script>
</head>

When using the script as a static file.

/* /my_editor.js */
import EditorJS from "https://cdn.jsdelivr.net/npm/@editorjs/[email protected]/+esm"
import Header from "https://cdn.jsdelivr.net/npm/@editorjs/[email protected]/+esm";
import List from "https://cdn.jsdelivr.net/npm/@editorjs/[email protected]/+esm";

export default (el) => new EditorJS({
    "holder": el,
    "tools": {
        "list": {
            "class": List,
            "inlineToolbar": true,
            "config": {
                "defaultStyle": "unordered"
            }
        },
        "header": {
            "class": Header,
            "shortcut": "CMD+SHIFT+H",
            "config": {
                "placeholder": "Enter a header",
                "levels": [2, 3, 4],
                "defaultLevel": 3
            }
        }
    }
});
<head>
<script type="module">
    import my_editor from '/my_editor.js';

    my_editor(document.getElementById('editorjs'));
</script>
</head>

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants