Project

General

Profile

Code modularity » History » Version 3

jahoti, 07/19/2021 08:06 AM
Add links to mentioned bundling/modularization tools

1 1 jahoti
# Code modularity
2
3 3 jahoti
Complex functionality has to be split into multiple javascript files. However, managing these by hand can get very cumbersome as project grows. There exist various ways of bundling javascript. Some tools commonly used for this purpose are [Browserify](https://browserify.org/), [jspm](https://jspm.org/), [Webpack](https://webpack.js.org/), [RequireJS](https://requirejs.org/) and [Babel](https://babeljs.io/). Yet another option is to use [javascript modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) - a native feature of the language.
4 1 jahoti
5
{{toc}}
6
7
## Native modules considerations
8
Javascript modules are rather convenient to use. Unfortunately, support varies between browsers and in some cases there is simply no facility to load a module. An example of such case are content scripts. They are loaded as listed from `manifest.json` file and need to be traditional script files. Chromium already offers a way to load a module dynamically from within a traditional script, but all modules loaded this way (including those pulled by the initial one) need to be listed as web-accessible resources in the manifest.
9
10
## Bundler considerations
11
If we decided to use a bundler, it would create an additional dependency for the project. Hachette clearly has no need for many of the features bundlers provide and as long as the functionality needed from them can be provided by a simple script, this is preferred.
12
13
It is also worth mentioning some of the bundlers are part of the Node.js/NPM ecosystem which, although consisting mostly of libre software, is problematic from software freedom point of view due to requiring people to rely on a third-party package manager and a non FSDG-compliant software repository. If any bundler is to be used, it is preferred to choose one that doesn't rely on Node.js or at least is packaged for an FSDG-compliant GNU/Linux distribution.
14
15
## Current approach
16
At some point early on, this extension utilized native javascript modules. Due to problems with these, sources were slightly modified, so that the import/export semantics of modules were mostly retained, but import and export statements were replaced with assignments and accesses to keys of the `window` object. Each script file's contents are wrapped into a function call so as not to clobber the global namespace. Properly ordered lists of scripts to load in each context were compiled by hand and placed in `manifest.json` and relevant HTML files.
17
18 2 jahoti
The `build.sh` script is now used to automatically write out such assignments and accesses to keys of the `window.killtheweb` object, wrap scripts, and compile those lists. Imports are performed using comments of the form
19
20
```
21
/*
22
 * IMPORTS_START
23
 * IMPORT first_import
24
 ...
25
 * IMPORT last_import
26
 * IMPORTS_END
27
 */
28
```
29
30
placed before the beginning of the code, while exports use a similar structure after the code with `EXPORT` replacing `IMPORT` throughout.