Skip to content

Conversation

GarboMuffin
Copy link
Member

@GarboMuffin GarboMuffin commented Oct 5, 2025

Make a dynamic import() and it'll get replaced with a data: URL during the production build

Also made most of the internals of build() async. Might help speed things up later since I think a lot of this is IO bound (we're still largely doing everything in serial so if anything it's slower right now)

In development mode, SHA256 sums for the dependencies are stored so at build-time it can be proven that no tampering has been had during a later production build. They also get cached locally to speed things up a bit.

@github-actions github-actions bot added the pr: other Pull requests that neither add new extensions or change existing ones label Oct 5, 2025
@GarboMuffin
Copy link
Member Author

Using import() is not sufficient for things like https://raw.githubusercontent.com/PsychoGoldfishNG/NewgroundsIO-JS/refs/heads/main/dist/NewgroundsIO.min.js that aren't ES modules

So, we could have several different ways to import things, and make them available as Scratch.import(), Scratch.import.asPlainScript(), Scratch.import.executeInIIFEAndExport(), etc.

@FurryR
Copy link
Contributor

FurryR commented Oct 5, 2025

Using import() is not sufficient for things like https://raw.githubusercontent.com/PsychoGoldfishNG/NewgroundsIO-JS/refs/heads/main/dist/NewgroundsIO.min.js that aren't ES modules

So, we could have several different ways to import things, and make them available as Scratch.import(), Scratch.import.asPlainScript(), Scratch.import.executeInIIFEAndExport(), etc.

I prefer letting extension developers decide whether to use import(). Bundling is also okay, but the production should not be minified. (Webpack development build may work, but since its obsolete i recommend tsup)

@GarboMuffin GarboMuffin mentioned this pull request Oct 5, 2025
@Brackets-Coder

This comment was marked as resolved.

@GarboMuffin
Copy link
Member Author

no, it uses URLs to websites

see #2264's imports for general kind of syntax that might work, though actually that PR and this one don't integrate quite right yet, and there's still some missing mechanisms that need to be added

there's a lot in the air - might restrict it to certain websites only (trusted, unlikely to vanish, operated by neutral parties that won't do anything weird with traffic logs) or make it skip the CDNs and download from npm instead. lots of things like that still being decided

there's some nice properties of this general approach:

  • avoid bloating the repository with every version of every dependency
  • no opportunity for anyone to tamper a dependency before copying it into the repository - you would have to tamper with upstream or the CDN which is presumably more difficult and you would have much higher priorities to attack
  • you can copy an extension's unprocessed source code out of the repo, paste it into the editor, and it will always work even before merge. if libraries got fetched from e.tw.o, extension would need to be merged first for those to work

@Brackets-Coder

This comment was marked as resolved.

@GarboMuffin
Copy link
Member Author

GarboMuffin commented Oct 6, 2025

If your school blocks major CDNs then you have much larger problems, but also the point of this PR is that all the dependencies will get inlined during a production build which solves that problem

@GarboMuffin
Copy link
Member Author

The URLs in the source code get used in development (easier to debug) while in production they get transparently converted into another format

@GarboMuffin
Copy link
Member Author

GarboMuffin commented Oct 6, 2025

Re: bundlers were mentioned earlier

I don't intend to bring in bundlers right now. The goal is to use the files provided by upstream without modification. That's needed for non-production usage where the URLs are left unchanged, is a lot simpler, and I think most of the dependencies that people want to integrate tend to offer scripts that work without changes. Biggest hurdle is that few dependencies offer ES modules. Hence the idea of allowing an import-as-script-tag or something that fetches the source code and evals it in an IIFE

Letting people configure bundlers inevitably leads to dependencies requiring random versions of rollup or parcel or webpack or whatever with random configuration and plugins. I don't want to be maintaining that if I don't need to.

If upstream doesn't provide workable files then we can figure something out on a case-by-case basis, possibly by forking a version and publishing under @turbowarp/*

@Brackets-Coder
Copy link
Contributor

Brackets-Coder commented Oct 6, 2025

If your school blocks major CDNs then you have much larger problems, but also the point of this PR is that all the dependencies will get inlined during a production build which solves that problem

I'm not worried about me and I'm not on a school network. I'm concerned for our users who might have a whitelisted school network, but I suppose I misunderstood the fact that the inlining happens when the extension is built, not every time it's loaded, which entirely resolves that

Now that I really understand what's happening here I'm realizing how much better it actually is than I thought

Sorry for the confusion

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr: other Pull requests that neither add new extensions or change existing ones
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Proposal: dependency system based on await import
3 participants