From 2a263ff6e5f7cf895fac09d42866f3b6cf912e7f Mon Sep 17 00:00:00 2001
From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com>
Date: Sat, 7 Sep 2024 00:54:18 -0700
Subject: [PATCH] feat: support arraybuffer-loader through `?arrayBuffer`
 resource query

---
 package-lock.json | 40 +++++++++++++++++++++++++++++++++++++++-
 package.json      |  1 +
 src/index.cjs     | 19 +++++++++++++++++--
 3 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 6ddc789..771592e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -25,6 +25,7 @@
       },
       "peerDependencies": {
         "@babel/preset-env": "^7.24.0",
+        "arraybuffer-loader": "^1.0.8",
         "autoprefixer": "^9.0.1",
         "babel-loader": "^9.1.3",
         "css-loader": "5.2.7",
@@ -4635,6 +4636,44 @@
         "node": ">=8"
       }
     },
+    "node_modules/arraybuffer-loader": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/arraybuffer-loader/-/arraybuffer-loader-1.0.8.tgz",
+      "integrity": "sha512-CwUVCcxCgcgZUu2w741OV6Xj1tvRVQebq22RCyGXiLgJOJ4e4M/59EPYdtK2MLfIN28t1TDvuh2ojstNq3Kh5g==",
+      "peer": true,
+      "dependencies": {
+        "loader-utils": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
+    "node_modules/arraybuffer-loader/node_modules/json5": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+      "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+      "peer": true,
+      "dependencies": {
+        "minimist": "^1.2.0"
+      },
+      "bin": {
+        "json5": "lib/cli.js"
+      }
+    },
+    "node_modules/arraybuffer-loader/node_modules/loader-utils": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz",
+      "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==",
+      "peer": true,
+      "dependencies": {
+        "big.js": "^5.2.2",
+        "emojis-list": "^3.0.0",
+        "json5": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
     "node_modules/arrify": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
@@ -10495,7 +10534,6 @@
       "version": "1.2.8",
       "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
       "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
-      "dev": true,
       "license": "MIT",
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
diff --git a/package.json b/package.json
index 7b88617..f795a99 100644
--- a/package.json
+++ b/package.json
@@ -44,6 +44,7 @@
   },
   "peerDependencies": {
     "@babel/preset-env": "^7.24.0",
+    "arraybuffer-loader": "^1.0.8",
     "autoprefixer": "^9.0.1",
     "babel-loader": "^9.1.3",
     "css-loader": "5.2.7",
diff --git a/src/index.cjs b/src/index.cjs
index f8c55c1..ac41ac6 100644
--- a/src/index.cjs
+++ b/src/index.cjs
@@ -5,6 +5,7 @@ const nodeExternals = require('webpack-node-externals');
 const webpack = require('webpack');
 
 const DEFAULT_CHUNK_FILENAME = 'chunks/[name].[chunkhash].js';
+const DEFAULT_ASSET_FILENAME = 'assets/[name].[hash][ext][query]';
 
 /**
  * @typedef {import('webpack').Configuration} Configuration
@@ -70,6 +71,7 @@ class ScratchWebpackConfigBuilder {
             output: {
                 clean: true,
                 filename: '[name].js',
+                assetModuleFilename: DEFAULT_ASSET_FILENAME,
                 chunkFilename: DEFAULT_CHUNK_FILENAME,
                 path: this._distPath,
                 library: {
@@ -116,18 +118,21 @@ class ScratchWebpackConfigBuilder {
                     {
                         // `asset` automatically chooses between exporting a data URI and emitting a separate file.
                         // Previously achievable by using `url-loader` with asset size limit.
-                        resourceQuery: /^\?asset$/,
+                        // If file output is chosen, it is saved with the default asset module filename.
+                        resourceQuery: '?asset',
                         type: 'asset'
                     },
                     {
                         // `asset/resource` emits a separate file and exports the URL.
                         // Previously achievable by using `file-loader`.
+                        // Output is saved with the default asset module filename.
                         resourceQuery: /^\?(resource|file)$/,
                         type: 'asset/resource'
                     },
                     {
                         // `asset/inline` exports a data URI of the asset.
                         // Previously achievable by using `url-loader`.
+                        // Because the file is inlined, there is no filename.
                         resourceQuery: /^\?(inline|url)$/,
                         type: 'asset/inline'
                     },
@@ -135,7 +140,17 @@ class ScratchWebpackConfigBuilder {
                         // `asset/source` exports the source code of the asset.
                         // Previously achievable by using `raw-loader`.
                         resourceQuery: /^\?(source|raw)$/,
-                        type: 'asset/source'
+                        type: 'asset/source',
+                        generator: {
+                            // This filename seems unused, but if it ever gets used,
+                            // its extension should not match the asset's extension.
+                            filename: DEFAULT_ASSET_FILENAME + '.js'
+                        }
+                    },
+                    {
+                        resourceQuery: '?arrayBuffer',
+                        type: 'javascript/auto',
+                        use: 'arraybuffer-loader'
                     },
                     {
                         test: /\.hex$/,