Description
Increasing access
p5.js as a library is mostly about the easy to use syntax to enable drawing onto a virtual canvas that it provides its users, the underlying implementation can and should change depending on what the specific needs of the environment are. With a functional core that additional modules can be attached onto, p5.js can be made maximally flexible across environment and diverse user needs.
Which types of changes would be made?
- Breaking change (Add-on libraries or sketches will work differently even if their code stays the same.)
- Systemic change (Many features or contributor workflows will be affected.)
- Overdue change (Modifications will be made that have been desirable for a long time.)
- Unsure (The community can help to determine the type of change.)
Most appropriate sub-area of p5.js?
- Accessibility
- Color
- Core/Environment/Rendering
- Data
- DOM
- Events
- Image
- IO
- Math
- Typography
- Utilities
- WebGL
- Build process
- Unit testing
- Internationalization
- Friendly errors
- Other (specify if possible)
What's the problem?
The way p5.js is currently split into modules utilizes ES6 modules side-effect imports which on the one hand is not very semantic, and on the other hand more significantly, different modules depends on each other to a large extent, making it hard to exclude certain module where it should not have been needed.
The current build of p5.js library files are also very big. Being able to modularize the build to not include features the user may not need can reduce file size significantly.
What's the solution?
p5.js will have a core that contains only the absolute essential functionalities, while all other code will be separately import-able. Take as example the core only build of p5.js and the math module as a separate module not included in core, two versions of each will be built from the source code: IIFE and ESM. Rollup is setup to create build for both with IIFE being the preferred format for most users using <script>
tags and ESM the preferred format for users using their own bundlers. (CommonJS or AMD format will not be supported)
IIFE
Immediately Invoked Function Expression (IIFE) is a common format libraries meant to be included with regular <script>
tag will come in. It prevents excessive global namespace pollution and is also used by p5.js 1.0. Rollup have several output formats and libraries meant to be included with regular <script>
tag will either be using iife
or umd
, the later of which combines IIFE, CommonJS, and RequireJS/AMD module syntax in one. p5.js 2.0 will mainly use Rollup's iife
format as IIFE allows for initialization through just side effects while for UMD, an export name must be set which is not compatible with the IIFE usage we want.
<script src="./lib/p5.js"></script>
<script src="./lib/p5.math.js"></script>
<script>
function setup(){
createCanvas(400, 400);
console.log(ceil(2.1));
}
function draw(){
background(200);
circle(200, 200, 100);
}
</script>
In the above example, both p5.js
and p5.math.js
are built with the iife
format. This usage is similar if not identical to the usage of addon libraries currently (deliberately so). The math
module here is a bundled module taken from all the source located in src/math
folder. Each file in that folder can be independenly built into the iife
format with Rollup if desired and the whole module can be included in the final p5.js
bundle if desired as well.
// src/math/index.js
import calculation from './calculation.js';
import noise from './noise.js';
import random from './random.js';
import trigonometry from './trigonometry.js';
import math from './math.js';
import vector from './p5.Vector.js';
export default function(p5, fn){
p5.registerAddon(calculation);
p5.registerAddon(noise);
p5.registerAddon(random);
p5.registerAddon(trigonometry);
p5.registerAddon(math);
p5.registerAddon(vector);
}
// src/math/calculation.js (redacted)
function calculation(p5, fn){
fn.abs = Math.abs;
}
export default calculation;
if(typeof p5 !== 'undefined'){
calculation(p5, p5.prototype);
}
// src/app.js (redacted)
// math (include if to be bundled as part of p5.js)
import './math/calculation';
import './math/math';
import './math/noise';
import './math/p5.Vector';
import './math/random';
import './math/trigonometry';
Please see relevant examples in the exploration fork for implementation.
ESM
ESM or ES Module is the current standard in JavaScript for working with modular JavaScript code. ESM are now very widely supported with all major browsers natively supporting it, all modern build tools supports or are even built around it, and Node.js have native support for it as well. p5.js 1.0's code is already written with ESM and transpiled into a UMD module. As part of the refactor mentioned in a previos section, the syntax of the internal use of ESM will be updated to match semantic usage. The main goal will be to limit cross dependencies between modules and minimize the use of side effects imports.
import p5 from 'p5';
import math from 'p5/math';
p5.registerAddon(math);
// The same instance mode syntax
const sketch = (p => {
p.setup = () => {
p.createCanvas(400, 400);
console.log(p.ceil(2.1));
};
p.draw = () => {
p.background(200);
p.circle(200, 200, 100);
};
});
new p5(sketch);
The above example assumes the user is using Node.js module resolution and have installed p5
through NPM. However, distributable ESM modules are built and will be published via CDN as well. To use this, the first two lines will instead be:
import p5 from './js/p5.esm.js';
import math from './js/p5.math.esm.js';
The registerAddon
static method is further described in the library proposal and represent a unified way that internal module and third party library extends the functionalities of the p5.js core.
Pros (updated based on community comments)
- Potential for modular build with smaller foot print
- Unified interface for authoring libraries and working on internal modules, if you are a library author, you will also know how to work on p5.js internals
Cons (updated based on community comments)
- Require significant refactoring of code base
- May require some internal functionalities to be redesigned/rethought, although these should not require user facing breaking changes
Proposal status
Under review
Metadata
Metadata
Assignees
Type
Projects
Status