Sign in Join
Wiki copytemporary

Pas2js Package: what changed

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

Title: Pas2js Package

OldNewLine
1+# Overview
2+
3+This is a proposal for pas2js packages, working similar to FPC/Delphi packages.
4+
5+Advantages of packages:
6+
7+- load code dynamically, e.g. the website starts with a small program and then loads the other code when needed. Or as addon in an IDE.
8+- big applications that uses most of its packages, might compile faster as less js needs to be generated.
9+- eventually unloading a package, e.g. to load a new version
10+
11+Disadvantages of packages:
12+
13+- the package js contains all elements, even those never used by the program.
14+- duplicate specializations
15+- version hell. A package must be shipped with compatible packages. If you change something in the RTL, all packages must be recompiled. This is mitigated when you use Lazarus lpk, so that Lazarus will automatically recompile packages if something has changed.
16+
17+## Source
18+
19+A pas2js package has a pascal source starting with keyword **package** instead of *program*, and it has an optional **requires** and **contains** clause.
20+
21+## Compiling a package
22+
23+When pas2js compiles a package, it generates a pkgname.ppmd, a pkgname.js and optionally a pkgname.js.map file. A **ppmd** stands for "pas2js package meta data".
24+
25+- Options *-FU*, *-FE* and *-o* apply canonically.
26+- Option *-Jc* has no effect.
27+- New option *-FP\<dir;dir;...\>* to specify the package search path (additional to *-Fu*)
28+
29+## PPMD
30+
31+The ppmd is a json file and contains the package units including their sources, plus data about specializations (specialized generics) and whatever else is needed.
32+
33+## Specializations
34+
35+Each pas2js package can have its own specializations - same as in Delphi:
36+
37+- Two dependent packages use the same TList\<TExample\>.
38+- Two independent packages B and C might have two different TList\<TExample\>. For example package A defines a TExample, and there is no TList\<TExample\> in A, and packages B and C both use A and define TList\<TExample\>, then there are two different TList\<TExample\>, although they have the same name.
39+
40+## Contains
41+
42+All units of a package must be listed in the **contains** clause Contrary to Delphi if a package uses a unit outside a package pas2js creates an error. This means a package can only use packaged units.
43+
44+## Requires
45+
46+Lists all packages needed by the package.
47+
48+## Using a package
49+
50+Compiling a program/library with packages:
51+
52+pas2js gets a new command line option *-Fp\<pkgname;pkgnam;...\>* to specify the packages of a program/library and *-FP\<dir;dir;...\>* to add directories to the package search path. pas2js searches the ppmd files first in the -FP search paths and then in the unit search paths given by -Fu. It loads all the ppmd recursively. Then it starts the normal compilation, reading all units, searching units first in the packages, then in the unit path.
53+
54+Then it generates js only for the program sources.
55+
56+The html needs to load all js files of the packages and the program.
57+
58+## The -Jc option
59+
60+If -Jc is given when compiling a program with packages pas2js concatenates all the package js and the program into one js (generating a big js.map).
61+
62+Without -Jc pas2js concatenates all program js, leaving out the packages.
63+
64+## Optimizations
65+
66+With precompiled package js files pas2js cannot remove unneeded code from the packages, as it does not yet have any post-js optimization. Theoretically since the packages contain all the sources, it could generate a program the current way (not using the package js files).
67+
68+## Dynamic loading
69+
70+Packages can be loaded after the program was loaded.
71+
72+Unloading is not supported (yet) as this requires more bookkeeping what was loaded.
73+
74+# Implementation
75+
76+## ToDos
77+
78+- Scanner: list of used files
79+- Parser: **package**, **requires**, **contains**
80+- Compiler: Read *-Fp* and *-FP* options
81+- Compiler: Read recursively **ppmd** files and check checksums
82+- Compiler: when searching an unit consider **contains**
83+- Compiler: when loading a unit load from **ppmd**
84+- Resolver: mark specializations in packages, generate lists for each package,
85+- Pas2js Resolver: compute the place where the specialization is created (near first occurrence)
86+- Analyzer: when compiling a package mark all public/protected declarations of package units
87+- Converter:
88+ - create package js
89+ - create package specializations (the generic is in another package)
90+ - many changes to access of local variables, e.g. the declarations of the generic unit
91+- Compiler: write **ppmd**
92+ - checksum of all sources
93+ - **requires** list with checksums
94+ - **contains** with sources with linebreaks set to \#10
95+- With -Jc: generate all js into one file - similar to static linking. Omitting not needed elements (if enabled). Dynamic loading of packages is not supported.
96+- Without -Jc: generate all program/library modules into one js.
97+ - source map
98+- Options -FU, -FE and -o apply canonically
99+- libpas2js hooks:
100+ - after loading an unit source from ppmd, for decryption
101+ - before saving an unit source to ppmd, for encryption
102+ - after loading ppmd, for reading custom data
103+ - before saving ppmd, for writing custom data
104+- Create a release with packages, adding another lpk for each package. The rtl.js will be in the RTL package.
105+
106+---
107+*From the Free Pascal wiki, page "Pas2js Package", as it stood on 2023-01-16 after a change by Mattias2, 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).*

Back to history