Sign in Join
Wiki copytemporary

pas2js modules: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: pas2js modules

OldNewLine
1+# Module import
2+
3+pas2js can convert the **\$linklib** directive to a JS import statement:
4+
5+The following:
6+
7+`{$linklib ./modules/canvas.js canvas}`
8+
9+is converted to
10+
11+`import * as canvas from "./modules/canvas.js";`
12+
13+If the alias is omitted, one is constructed for you:
14+
15+`{$linklib ./modules/some-api.js}`
16+
17+is converted to `import * as some_api from "./modules/some-api.js";`
18+
19+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.
20+
21+For this reason, a new target "operating system" has been invented: the module. This means that you must compile with target module:
22+
23+`pas2js -Tmodule -Jirtl.js main.pp`
24+
25+The nodejs target will also work, but in the future the 2 targets may diverge.
26+
27+# Demos
28+
29+The pas2js demos/modules directory contains a series of subdirectories. Each subdirectory has 1 demo. Compile with the command-line as above:
30+
31+`pas2js -Tmodule -Jirtl.js main.pp`
32+
33+## Basic
34+
35+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.
36+
37+## Basic-Units
38+
39+This is the same as the Basic example, but the import definitions are split out in units.
40+
41+## Flat
42+
43+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.
44+
45+## Flat-Units
46+
47+This is the same as the flat example, but the import definitions are split out in units.
48+
49+# Module export
50+
51+Module export is implemented using the existing pascal **Library** concept.
52+
53+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.
54+
55+For example a library exporting a function twice, as name *Swim* and as *Move*:
56+
57+``` pascal
58+library Fish;
59+procedure Swim(w: word);
60+begin
61+ writeln('Swimming ',w,' meters');
62+end;
63+exports
64+ Swim;
65+ Swim name 'Move';
66+begin
67+end.
68+```
69+
70+Compiled with *"pas2js -Tmodule -Jirtl.js -Jc fish.pas"* generates the following *fish.js*:
71+
72+``` javascript
73+...rtl.js and system unit...
74+rtl.module("library", [], function () {
75+ var $mod = this;
76+ this.Swim = function (w) {
77+ pas.System.Writeln("Swimming ",w," meters");
78+ };
79+ $mod.$main = function () {
80+ };
81+});
82+rtl.run("library");
83+export const Swim = pas.library.Swim;
84+export const Move = pas.library.Swim;
85+```
86+
87+# Using a Pascal Library
88+
89+Javascript modules can be used using the Javascript [import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) statement.
90+
91+Consider the following HTML:
92+
93+``` html
94+<!DOCTYPE html>
95+<html lang="en-US">
96+ <head>
97+ <meta charset="utf-8">
98+ <title>Basic Pas2JS library example</title>
99+ <script type="module" src="fish.js"></script>
100+ </head>
101+ <body>
102+
103+ </body>
104+</html>
105+```
106+
107+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.
108+
109+## Using Pascal Library from JavaScript
110+
111+The imports from a pascal library are no different from a regular Javascript import.
112+
113+Taking the above HTML as the example, if the file **swim.js** contains the following javascript:
114+
115+``` javascript
116+import Swim from "fish.js";
117+
118+Swim(10);
119+```
120+
121+Then the browser console will show the output of the program:
122+
123+`   Swimming 10 meters`
124+
125+## Using Pascal Library from Pascal
126+
127+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:
128+
129+``` pascal
130+// Import the functions in an object called aqua
131+{$linklib ./fish.js aqua}
132+
133+// We use the aqua object name in the external:
134+procedure Swim(aMeters: word); external name 'aqua.Swim';
135+procedure SwimHarder(aMeters: word); external name 'aqua.Move';
136+
137+begin
138+ Swim(3);
139+ SwimHarder(10);
140+end.
141+```
142+
143+compile using the module target:
144+
145+`   ``pas2js -Tmodule -Jc -Jirtl.js swim.lpr`
146+
147+Again, the output will be shown on the console.
148+
149+You can find another example in the pas2js [Pas2JS demos](https://gitlab.com/freepascal.org/fpc/pas2js/-/tree/main/demo/library)
150+
151+# Navigation
152+
153+- Back to [[pas2js]]
154+- Back to [[lazarus pas2js integration]]
155+
156+Note that we made a pascal program for the swim.js, but we could just as well have made a library.
157+
158+---
159+*From the Free Pascal wiki, page "pas2js modules", as it stood on 2022-02-22 after a change by Michael, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
160+Category: Pas2js

Back to history