Difference between revisions of "pas2js modules"
(6 intermediate revisions by the same user not shown) | |||
Line 83: | Line 83: | ||
procedure Swim(w: word); | procedure Swim(w: word); | ||
begin | begin | ||
+ | writeln('Swimming ',w,' meters'); | ||
end; | end; | ||
exports | exports | ||
Line 91: | Line 92: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | Compiled with ''"pas2js -Tmodule fish.pas"'' generates the following ''fish.js'': | + | Compiled with ''"pas2js -Tmodule -Jirtl.js -Jc fish.pas"'' generates the following ''fish.js'': |
<syntaxhighlight lang=javascript> | <syntaxhighlight lang=javascript> | ||
Line 98: | Line 99: | ||
var $mod = this; | var $mod = this; | ||
this.Swim = function (w) { | this.Swim = function (w) { | ||
+ | pas.System.Writeln("Swimming ",w," meters"); | ||
}; | }; | ||
$mod.$main = function () { | $mod.$main = function () { | ||
Line 109: | Line 111: | ||
=Using a Pascal Library= | =Using a Pascal Library= | ||
− | HTML: | + | Javascript modules can be used using the Javascript [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import import] statement. |
+ | |||
+ | Consider the following HTML: | ||
<syntaxhighlight lang=html> | <syntaxhighlight lang=html> | ||
<!DOCTYPE html> | <!DOCTYPE html> | ||
Line 123: | Line 127: | ||
</html> | </html> | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | Note that the script has type '''module''', and that no script tag with the '''rtl.run();''' statement is present in the HTML body. | ||
+ | It is not possible to use or import a module from a regular script tag. | ||
==Using Pascal Library from JavaScript== | ==Using Pascal Library from JavaScript== | ||
− | + | The imports from a pascal library are no different from a regular Javascript import. | |
+ | |||
+ | Taking the above HTML as the example, if the file '''swim.js''' contains the following javascript: | ||
+ | |||
+ | <syntaxhighlight lang="javascript"> | ||
+ | import Swim from "fish.js"; | ||
+ | |||
+ | Swim(10); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Then the browser console will show the output of the program: | ||
+ | |||
+ | Swimming 10 meters | ||
==Using Pascal Library from Pascal== | ==Using Pascal Library from Pascal== | ||
− | + | As mentioned above, using a Pascal produced library from pascal is done no different from using a Javascript module, | |
+ | and is no different from using a library in a native program. Our 'fish' library can be used using the following program: | ||
+ | |||
+ | <syntaxhighlight lang="pascal"> | ||
+ | // Import the functions in an object called aqua | ||
+ | {$linklib ./fish.js aqua} | ||
+ | |||
+ | // We use the aqua object name in the external: | ||
+ | procedure Swim(aMeters: word); external name 'aqua.Swim'; | ||
+ | procedure SwimHarder(aMeters: word); external name 'aqua.Move'; | ||
+ | |||
+ | begin | ||
+ | Swim(3); | ||
+ | SwimHarder(10); | ||
+ | end. | ||
+ | </syntaxhighlight> | ||
+ | compile using the module target: | ||
+ | |||
+ | <code>pas2js -Tmodule -Jc -Jirtl.js swim.lpr</code> | ||
+ | |||
+ | Again, the output will be shown on the console. | ||
+ | |||
+ | You can find another example in the pas2js [https://gitlab.com/freepascal.org/fpc/pas2js/-/tree/main/demo/library Pas2JS demos] | ||
+ | |||
+ | = Navigation = | ||
+ | * Back to [[pas2js]] | ||
+ | * Back to [[lazarus pas2js integration]] | ||
+ | |||
+ | [[Category:Pas2js]] | ||
+ | |||
+ | Note that we made a pascal program for the swim.js, but we could just as well have made a library. |
Latest revision as of 00:41, 23 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. It can export global functions, static methods, and global variables.
For example a library exporting a function twice, as name Swim and as Move:
library Fish;
procedure Swim(w: word);
begin
writeln('Swimming ',w,' meters');
end;
exports
Swim;
Swim name 'Move';
begin
end.
Compiled with "pas2js -Tmodule -Jirtl.js -Jc fish.pas" generates the following fish.js:
...rtl.js and system unit...
rtl.module("library", [], function () {
var $mod = this;
this.Swim = function (w) {
pas.System.Writeln("Swimming ",w," meters");
};
$mod.$main = function () {
};
});
rtl.run("library");
export const Swim = pas.library.Swim;
export const Move = pas.library.Swim;
Using a Pascal Library
Javascript modules can be used using the Javascript import statement.
Consider the following 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>
Note that the script has type module, and that no script tag with the rtl.run(); statement is present in the HTML body. It is not possible to use or import a module from a regular script tag.
Using Pascal Library from JavaScript
The imports from a pascal library are no different from a regular Javascript import.
Taking the above HTML as the example, if the file swim.js contains the following javascript:
import Swim from "fish.js";
Swim(10);
Then the browser console will show the output of the program:
Swimming 10 meters
Using Pascal Library from Pascal
As mentioned above, using a Pascal produced library from pascal is done no different from using a Javascript module, and is no different from using a library in a native program. Our 'fish' library can be used using the following program:
// Import the functions in an object called aqua
{$linklib ./fish.js aqua}
// We use the aqua object name in the external:
procedure Swim(aMeters: word); external name 'aqua.Swim';
procedure SwimHarder(aMeters: word); external name 'aqua.Move';
begin
Swim(3);
SwimHarder(10);
end.
compile using the module target:
pas2js -Tmodule -Jc -Jirtl.js swim.lpr
Again, the output will be shown on the console.
You can find another example in the pas2js Pas2JS demos
- Back to pas2js
- Back to lazarus pas2js integration
Note that we made a pascal program for the swim.js, but we could just as well have made a library.