Difference between revisions of "pas2js modules"

From Lazarus wiki
Jump to navigationJump to search
Line 73: Line 73:
  
 
== Module export ==
 
== Module export ==
Module export will be implemented using the existing pascal library concept, but this is currently a work in progress.
+
Module export is implemented using the existing pascal '''Library''' concept.
 +
 
 +
A pas2js library is transpiled into a Javascript module with its own rtl.js and rtl.run.
 +
For example a library exporting a function:
 +
 
 +
<syntaxhighlight lang=pascal>
 +
library Fish;
 +
procedure Swim(w: word);
 +
begin
 +
end;
 +
exports
 +
  Swim;
 +
  Swim name 'Move';
 +
begin
 +
end.
 +
</syntaxhighlight>
 +
 
 +
Generates the following JavaScript:
 +
 
 +
<syntaxhighlight lang=javascript>
 +
...rtl.js and system unit...
 +
rtl.module("library", [], function () {
 +
  var $mod = this;
 +
  this.Swim = function (w) {
 +
  };
 +
  $mod.$main = function () {
 +
  };
 +
});
 +
rtl.run("library");
 +
export const Swim = pas.library.Swim;
 +
export const Move = pas.library.Swim;
 +
</syntaxhighlight>
 +
 
 +
HTML:
 +
<syntaxhighlight lang=html>
 +
<!DOCTYPE html>
 +
<html lang="en-US">
 +
  <head>
 +
    <meta charset="utf-8">
 +
    <title>Basic Pas2JS library example</title>
 +
    <script type="module" src="fish.js"></script>
 +
  </head>
 +
  <body>
 +
 
 +
  </body>
 +
</html>
 +
</syntaxhighlight>

Revision as of 12:44, 22 February 2022

Module import

pas2js can convert the $linklib directive to a JS import statement:

The following:

{$linklib ./modules/canvas.js canvas}

is converted to

import * as canvas from "./modules/canvas.js";

If the alias is omitted, one is constructed for you:

{$linklib ./modules/some-api.js}

is converted to import * as some_api from "./modules/some-api.js";

The import statements are always inserted in the main program. This is because modules are like windows libraries: self-contained programs, which only import and export well-defined symbols.

For this reason, a new target "operating system" has been invented: the module. This means that you must compile with target module:

pas2js -Tmodule -Jirtl.js main.pp

The nodejs target will also work, but in the future the 2 targets may diverge.

Demos

The pas2js demos/modules directory contains a series of subdirectories. Each subdirectory has 1 demo. Compile with the command-line as above:

pas2js -Tmodule -Jirtl.js main.pp

Basic

This shows a simple program, no units, that uses the linklib directive to import a javascript module. It uses an external class definition to access the exported symbols from the modules.

Basic-Units

This is the same as the Basic example, but the import definitions are split out in units.

Flat

This shows a simple program, no units, that uses the linklib directive to import a javascript module. It uses only external 'name' definitions to access the exported symbols from the modules; no external class is used.

Flat-Units

This is the same as the flat example, but the import definitions are split out in units.

Module export

Module export is implemented using the existing pascal Library concept.

A pas2js library is transpiled into a Javascript module with its own rtl.js and rtl.run. For example a library exporting a function:

library Fish;
procedure Swim(w: word);
begin
end;
exports
  Swim;
  Swim name 'Move';
begin
end.

Generates the following JavaScript:

...rtl.js and system unit...
rtl.module("library", [], function () {
  var $mod = this;
  this.Swim = function (w) {
  };
  $mod.$main = function () {
  };
});
rtl.run("library");
export const Swim = pas.library.Swim;
export const Move = pas.library.Swim;

HTML:

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <title>Basic Pas2JS library example</title>
    <script type="module" src="fish.js"></script>
  </head>
  <body>

  </body>
</html>