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

Can't load reveal backend in ReactJS app #205

Closed
patoch opened this issue Sep 29, 2018 · 10 comments
Closed

Can't load reveal backend in ReactJS app #205

patoch opened this issue Sep 29, 2018 · 10 comments

Comments

@patoch
Copy link

patoch commented Sep 29, 2018

Hi here,

I am trying to embed the reveal converter in a react web app and have the following :

message: asciidoctor: FAILED: missing converter for backend 'revealjs'. Processing aborted.

   import Asciidoctor from "asciidoctor.js"; 
   require("asciidoctor-reveal.js");

    var content= ...
    var asciidoctor = Asciidoctor();
    const attributes = { revealjsdir: "node_modules/reveal.js@" };
    const options = {
      safe: "safe",
      backend: "revealjs",
      attributes: attributes,
      header_footer: true
    };

  html = asciidoctor.convert(content, options)

Fails with :

opal.js:4993 Uncaught $NameError {name: "Converter", message: "uninitialized constant Asciidoctor::Converter", stack: "Converter: uninitialized constant Asciidoctor::Converter"}
...
./node_modules/opal-runtime/src/nodejs.js
14:48-55 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

Any clue how to get this run in the browser ?

Thank you

Patrick

@patoch patoch changed the title asciidoctor: FAILED: missing converter for backend 'revealjs'. Processing aborted. Can't load reveal backend in browser Oct 1, 2018
@obilodeau
Copy link
Member

After spending 15 minutes researching this, I think I understand what's going on but I don't know how to fix it.

I think our node package isn't webpack ready so you can't really import it using Reactjs. Can you try removing the import bit and avoid using react constructs? I'm not familiar with React so I don't know if this is feasible. You shouldn't experience namespace clashes doing so, I think it's a good first test. Eventually, we might want to make our node module webpack ready. I'm not sure how to do that.

Providing a gist of an example app that reproduce your problem and that we could try would be great because then I could try some things on my own to fix it. Right now, I know so little of Reactjs, webpack and Javascript that I'm completely lost on where to start.

Tagging @Mogztter to chime in as he is the most knowledgeable person I know on the Asciidoctor.js ecosystem.

@obilodeau obilodeau changed the title Can't load reveal backend in browser Can't load reveal backend in ReactJS app Oct 11, 2018
@ggrossetie
Copy link
Member

ggrossetie commented Oct 11, 2018

We encountered the same issue in the HTML5 semantic converter: jirutka/asciidoctor-html5s#2

In short, the Reveal.js converter should be lazily initialized otherwise the Asciidoctor context won't be available. You can take a look at what Jakub did: jirutka/asciidoctor-html5s@4702cb2

The warning about require has been resolved in Asciidoctor.js (and will be available in the next release): asciidoctor/asciidoctor.js#508

Please note that the warning message is not critical and Asciidoctor.js + Reveal.js converter should work fine.

@obilodeau
Copy link
Member

Thanks for the great pointers @Mogztter!

@patoch, if you can provide a minimal broken example with as little code as possible, I will try to fix the problem with @Mogztter's guidance borrowing from the html5s back-end. Until I have something [broken] to work with, it is too time-consuming for me to go learn react and try to reproduce your problem.

@ggrossetie
Copy link
Member

I can provide a minimal example using Babel: https://babeljs.io

@ggrossetie
Copy link
Member

@obilodeau https://github.com/Mogztter/asciidoctor-reveal.js-integration-babel

For reference the source code and the generated code:

source.js

import Asciidoctor from 'asciidoctor.js'
const asciidoctor = Asciidoctor()

import 'asciidoctor-reveal.js'
//require('asciidoctor-reveal.js')

const attributes = { revealjsdir: 'node_modules/reveal.js@' }
const options = {
  safe: 'safe',
  backend: 'revealjs',
  attributes: attributes,
  header_footer: true
}

console.log(asciidoctor.convert('Hello *Babel*', options))

generated.js

'use strict';

var _asciidoctor = require('asciidoctor.js');

var _asciidoctor2 = _interopRequireDefault(_asciidoctor);

require('asciidoctor-reveal.js');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var asciidoctor = (0, _asciidoctor2.default)();

// Babel will move the import statement at the top of the file.
// As a consequence, the reveal.js converter will be loaded before the initialization of Asciidoctor.js.

// If we replace the import statement by a require statement then it's working.
// Another way to fix this issue is to lazily load the reveal.js converter.
//require('asciidoctor-reveal.js')

var attributes = { revealjsdir: 'node_modules/reveal.js@' };
var options = {
  safe: 'safe',
  backend: 'revealjs',
  attributes: attributes,
  header_footer: true
};

console.log(asciidoctor.convert('Hello *Babel*', options));

@patoch Since you are already using require, you could reorder your code to fix this issue:

import Asciidoctor from 'asciidoctor.js'
var asciidoctor = Asciidoctor()
require('asciidoctor-reveal.js')

var content = 'hello';

const attributes = { revealjsdir: 'node_modules/reveal.js@' }
const options = {
  safe: 'safe',
  backend: 'revealjs',
  attributes: attributes,
  header_footer: true
};

html = asciidoctor.convert(content, options)

@patoch
Copy link
Author

patoch commented Oct 16, 2018

@obilodeau
Thank you for you response. I just tested and this works fine for me.
I would add this to the documentation, surely other people will be interested to get this in the browser!
Thanks again !

@patoch patoch closed this as completed Oct 16, 2018
@obilodeau
Copy link
Member

obilodeau commented Oct 16, 2018 via email

@ggrossetie
Copy link
Member

@obilodeau I believe it's a good practice to load a module "on demand". The require method is just a workaround. A user should be able to use import for both Asciidoctor.js and the reveal.js converter:

import Asciidoctor from 'asciidoctor.js'
import AsciidoctorRevealjsConverter from 'asciidoctor-reveal.js'

const asciidoctor = Asciidoctor()
AsciidoctorRevealjsConverter.registrer()

@obilodeau
Copy link
Member

@patoch a heads up: please be aware that the changes we are about to merge in #219 which will be released in 1.2.0 relatively soon will break the workaround that @Mogztter proposed you.

@obilodeau
Copy link
Member

#219 is merged. Watch out when you will upgrade to our next release.

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

3 participants