Open gridsystem opened 2 weeks ago
Hey @gridsystem!
Thanks for reaching out and making me aware of this. I have never tried those use-cases in particular, was hoping the recent release, including instance mode support, would handle all those cases.
I'll try to look into this more this weekend hopefully and will give an update. Thanks again, happy to improve on the library, so everybody is able to use it within his/her favorite environment.
Hey again @gridsystem, I looked into this now. Unfortunately that's out of reach for me currently.
I've set up a vite
project and successfully ran a p5.js
sketch, but adding p5.asciify
doesn't work and causes issues I don't know how to solve yet.
I was able to generally import p5.asciify
by exporting the p5asciify
variable, which is located at the beginning of this libraries index.js
file.
Within this index.js
file, there are also some p5
hooks defined, which are necessary for the setup of the library. Those hooks do not work in this scenario for some reason, resulting in the add-on library to never set up and run.
Reference: https://github.com/processing/p5.js/blob/main/contributor_docs/creating_libraries.md#step-6
Also, functions that p5.asciify
attaches to the p5
context, like calling sketch.setAsciiOptions()
, do not seem to be present in this scenario, resulting in more errors.
Are there any other p5.js
add-on libraries that work in those kinds of environments? It would be important that those add-on libraries also use p5
hooks or attach functions/methods to the p5
context to use as a reference.
My only idea would be to not rely on those hooks and require the user to do certain calls in preload()
, setup()
and at the end of the draw()
function to make it work. I'd like to keep it simple for the user and rely on those hooks though, so I am hoping to find a solution at some point, if there is any currently.
Hey man. It’s late here so I’ll have a proper dig through this tomorrow. But I wanted to get a quick reply to you while it’s still fresh in your mind!
I imagine the reason P5.asciify isn’t playing nicely with P5 in that setup is that they are each in their own separate module namespace.
Usually when you’re publishing something to NPM, it would be packaged as a nodejs module, so that it can be installed with npm install my-thing
. This isn’t by any means limited to Vite, it’s just the example I had to hand. I can see that you’re using import
with the different files in the P5.asciify repo - it’s exactly the same.
If the module you’re installing has a dependency, so in your case P5, P5 would be marked as a dependency in package.json
, so that when I npm install p5.asciify
, if I haven’t already installed p5
, npm would install that for me too.
This is really different to the <script src=“…”
way of installing things. In that scenario, the scripts that I’m adding to my site would usually add things to the global namespace - var p5 = …
creates a property on the window, window.p5
. So if I then install p5.asciify
, it can see p5
too, because they’re both just properties of window
, in the global namespace.
I’m not teaching you to suck eggs here - just want to make sure we’re on the same page with terminology etc.
So the solution with p5.asciify
might be as simple as having import p5 from ‘p5’
in your code, so that p5.asciify
and p5
are in the same namespace?
What I’m not sure about though, is if you set that up in Rollup, how you would publish a script that can be imported via <script src=“…
as well as import p5.asciify…
. I experimented with making Rollup modules maybe 5 years ago so I’m not an expert but I have seen it done elsewhere, so I could do some research!
Hey @humanbydefinition !
I've had a play with the code today and found some examples from other p5 library authors.
My suggestion from last night was useless because your code then adds the methods to a different instance of p5
, that I'd created inside your module.
I have worked out how to package the module for use in browser via script tags and for use as an import
-able ES module.
I've also included a reference, which has done the same thing, and a few notes about how.
The reason I'm keen to get this working as an ES module is that so many sites and apps are built with Vue, React, or other frameworks that are built around modules, which don't make it easy to just add <script>
tags or access the global namespace.
I'm not going to submit a full pull request, but here is what I've done with some comments:
// rollup.config.js
// Clearly differentiate between the minified file for browser `<script>` tags and an ES module for importing
…
// Rollup wants a name for an ES module
{ file: 'dist/p5.asciify.js', format: 'es', name: 'p5asciify' },
{
file: 'dist/p5.asciify.min.js',
// The module for browser script tage might use IIFE
// https://rollupjs.org/tutorial/#using-output-plugins
format: 'iife',
// Rollup needs a name for an IIFE
name: 'p5asciify',
…
}
// tests/…/index.html
// Always use the minified version in browser `<script>` tags
<script src="../../dist/p5.asciify.min.js></script>
// package.json
// Always use the non-minified version in ES imports
"main": "dist/p5.asciify.js"
// src/index.js
// Export something for ES modules to import
export default p5asciify;
So with this setup, I can
/tests
directory.pnpm link ../p5.asciify
to use the local version of p5.asciify
instead of the published version on npm (https://pnpm.io/cli/link#use-cases)But there would definitely be some changes to make so that it works when import
ing.
As you've said, in an ES module environment, p5.asciify
doesn't have access to p5
, and as I've tested, importing p5
at the top of your index.js
doesn't give it access to the same version of p5
that you'd make your sketches with.
Here is a library, p5.brush, which works as an ES module and as a browser <script>
tag. They're using Rollup to make a UMD which is different to separate ES module and minified versions for ` Githubissues.
After installing
p5.asciify
from npm, it's not possible to import the module into an app, as it doesn't export anything.I think it just loads itself into the global namespace?
Importing into a (very fast to set up) Vite.js app as an example,
Results in