Import Export Modules Javascript

exma2's picture
Forums: 

Hi,

im using some content and want to import show. In the message.js, the function show is exporting in the right way.

I always got an Error that "MyContent is not a constructor" if i try to use MyContent in other h5p contents.

I just get this error if im importing some stuff. Can someone explain me why? I know, or i saw in other contents on github, that other developer only using import statements in connection with npm. 

It would be nice if someone can help me here.

import {show} from './message.js';

var H5P = H5P || {};
H5P.MyContent = (function (EventDispatcher)
{

  show("hi");
  /**
   * Constructor
   */
  function MyContent ()
  {...}
  MyContent .prototype = Object.create(EventDispatcher.prototype);
  MyContent .prototype.constructor = MyContent ;

  return MyContent ;

})(H5P.EventDispatcher);

otacke's picture

Hi!

I think it was easier if you provided a little more context or a link to all of the code. The `import` statement alone should cause trouble if you're not in a module (and H5P core doesn't attribute the scripts as such normally) and not bundling the code.

Cheers,
Oliver

exma2's picture

Thx for the answer!

you can see the full code here:

https://github.com/chrismeyer10/H5P.ContentExample

but there is nothing special. Its just like an hello world content.

Im working in other projects where i need to include some objects or classes which uses the export statement. I saw in your and other projects that if you use export and import, you always bundle the code with npm build. I never did that and i dont know how exactly it works (would be nice if you can link me to some introduction). Im still asking myself why isnt that possible, to not bundle and use export and import statements in the framework h5p without some strange constructor error.. by the way, i got the same error if i trying to load modules with require(..).

Im happy about any information you can give me :)

 

otacke's picture

Hello again!

As mentioned, `import` is only allowed in modules (that have been introduced to JavaScript in "ES6" in 2015), and H5P core doesn't load scripts with that `module` attribute. That's why your code fails. It crashes at the `import` statement, hence the Constructor is never defined and cannot be found.

The `require` statement is not part of JavaScript, but of node.js which allows to use JavaScript server-side outside a browser. It was node.js's take on importing modules before JavaScript had that `import` option. `require` was never officially part of JavaScript's specification.

It's not about the bundling of sources per se, but channeling your code through "Babel" which makes other code using the `import` statement work. Babel can transform ("transpile") your core to make it suitable for different target environments, e.g. "web" and "ES5" (ES5 is the JavaScript version before ES6). That's useful in this case to "replace" (I am simplifying here) the `import` statements (that need ES6+) with code that can run in ES5 environments, too. In general, Babel allows you to use all the new fancy stuff that the latest JavaScript version offers but not all browsers may support yet - you can write code using the latest syntax and run it through Babel to turn it into code using an older syntax that more browsers understand.

That "transpiling" is usually only one step of a larger build chain that can do all kinds of things for you automatically, e.g. also "lint" your code (detect style guide or syntax issues), minify the code so it takes less space (for the sake of intelligibility), bundle resources, etc. That build chain can take all your code files and assets as input, run them through Babel to make them work in older environments, compress the code, etc. and turn that into some output. A tool that's often used for that process is `webpack`.

I fear I cannot explain all this to you in detail - there are endless resources out there on the web already. But I can point you to https://github.com/h5p/h5p-boilerplate which has two branches. The main branch holds a very basic "Hello world" that's written in a more modern (and intelligible) way than what you may have seen (and are using) and a branch with a fully fledged template for a "question like" content type with all kinds of shenanigans like xAPI or resume support. Their build chain should be updated and their code might need tweaking, but you can find a full example with configuration for bundling, transpiling, minifying, eslint configuration for the H5P style guide, etc.

Cheers,
Oliver