blockly-samples icon indicating copy to clipboard operation
blockly-samples copied to clipboard

fix: bundle blockly test images in block-test plugin

Open alicialics opened this issue 2 years ago • 0 comments

The basics

This PR will address issues like bundling assets (specifically tested with png files in @blockly/block-test) in webpack UMD bundles, as well as potential future plugin ESM builds.

It makes use of the following:

  • See https://web.dev/articles/bundling-non-js-resources for details on new URL(..., import.meta.url) pattern

  • publicPath configuration in webpack https://webpack.js.org/guides/public-path/#automatic-publicpath

  • [x] I validated my changes

The details

Resolves

Fixes #503 Fixes #1145

This bundles needed static media files from https://github.com/google/blockly/tree/develop/tests/media into @blockly/block-test package

@maribethb and I discussed in detail (see #1969) on what potential approaches that could enable plugins to bundle assets in their builds. The universal way is inline assets using dataUrls, which is not that interesting in itself and may negatively impact performance.

The approach in this PR requires more tooling support depending on how you ingest the package in your app however the upside is that Webpack supports this natively and there is a minimal change to @blockly/dev-scripts.

Here are the details: Webpack will include the png files as <hash>.png in /dist in @blockly/block-test

@alicialics ➜ /workspaces/blockly-samples/plugins/block-test (import-block-test-assets) $ ls dist/
0ed404116fc61b34ab03.png  e646c1dc1540e78440bb.png  index.js.LICENSE.txt
4daf5c075a6ffed5369f.png  index.js                  index.js.map

package.json module field still points to /src with code new URL('../media/30px.png', import.meta.url) bundlers like Webpack will use the module field to build any code that references this plugin via the module field.
So code like @blockly/dev-tools or examples/blockly-react will also include png files as <hash>.png in their dist/

I also briefly tested removing module field from @blockly/block-test's package.json and it seems that @blockly/dev-tools will still build fine and include all the assets.

@alicialics ➜ .../blockly-samples/plugins/dev-tools/dist (import-block-test-assets) $ ls
0ed404116fc61b34ab03.png  e646c1dc1540e78440bb.png  index.js.LICENSE.txt
4daf5c075a6ffed5369f.png  index.js                  index.js.map

npm start in @blockly/block-test will also work now

For plain html files, import.meta will work when you do a script tag with type module, ie: <script type="module" src="./path/to/@blockly/block-test/dist/index.esm.js">

However we are not building esm format at the moment (see #1877 and #1997) so this is not possible today.

Lastly if you just do a plain script tag in a html file <script src="./path/to/@blockly/dev-tools/dist/index.js"> (eg dev-tools imports block-test as mentioned above) we rely on publicPath: "auto" configuration in webpack to use document.currentScript.src to figure out the correct URL path to the asset in question, such as in advanced playground

The relevant change in the UMD output is:

93383,93402c93383
<         (() => {
<           var l;
<           __webpack_require__.g.importScripts &&
<             (l = __webpack_require__.g.location + "");
<           var n = __webpack_require__.g.document;
<           if (!l && n && (n.currentScript && (l = n.currentScript.src), !l)) {
<             var e = n.getElementsByTagName("script");
<             if (e.length)
<               for (var t = e.length - 1; t > -1 && !l; ) l = e[t--].src;
<           }
<           if (!l)
<             throw new Error(
<               "Automatic publicPath is not supported in this browser",
<             );
<           (l = l
<             .replace(/#.*$/, "")
<             .replace(/\?.*$/, "")
<             .replace(/\/[^\/]+$/, "/")),
<             (__webpack_require__.p = l);
<         })(),
---
>         (__webpack_require__.p = "/dist/"),

Proposed Changes

See above for details

Reason for Changes

Fixes #503 Fixes #1145 (this should provide a way to load any audio assets but I have not tested)

Test Coverage

npm run start in @blockly/block-test

Documentation

N/A

Additional Information

Preferably requires more testing from the blockly team to ensure @blockly/dev-tools still works as expected since it imports @blockly/block-test

cc @cpcallen

alicialics avatar Oct 19 '23 19:10 alicialics