Skip to content

Commit 192cb09

Browse files
committed
Fixes asset path. Prepares to bump version.
1 parent 189a96b commit 192cb09

6 files changed

Lines changed: 63 additions & 6 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@code-dot-org/ml-playground",
3-
"version": "0.0.48",
3+
"version": "0.0.49",
44
"private": false,
55
"repository": {
66
"type": "git",

src/assetPath.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,22 @@
1-
(
2-
global as unknown as Record<string, unknown>
3-
).__ml_playground_asset_public_path__ = './assets/';
4-
1+
// Consumer-facing setter for the ml-playground asset base path.
2+
//
3+
// The function writes a single property on the shared page global,
4+
// which the main bundle reads at startup (see `setPublicPath.ts`) to
5+
// assign webpack's `__webpack_public_path__`. That assignment is what
6+
// controls image and chunk URLs at runtime.
7+
//
8+
// Ordering: call this BEFORE the ml-playground main bundle is loaded
9+
// (i.e. before `require('@code-dot-org/ml-playground')` or any import
10+
// that resolves through the main entry). Asset URLs are computed when
11+
// each asset module first evaluates, so a late call can't retroactively
12+
// rewrite them. The natural CommonJS pattern (`setAssetPath(...); const
13+
// ml = require('@code-dot-org/ml-playground'); ...`) is correct;
14+
// pure-ESM consumers should call this then `await import(...)` the
15+
// main entry.
16+
//
17+
// No module-init side effect on purpose — the fallback for "consumer
18+
// never set it" lives in `setPublicPath.ts` as `|| './'`, so there's
19+
// one place to look when chasing publicPath behavior.
520
export const setAssetPath = (path: string): void => {
621
(
722
global as unknown as Record<string, unknown>

src/indexDev.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import './assetPath';
2+
import './setPublicPath';
23
import {initAll, instructionsDismissed} from './index';
34
import queryString from 'query-string';
45
import {ModelDataToSave, SaveResponse} from './types';

src/indexProd.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
import './setPublicPath';
12
export {initAll, instructionsDismissed} from './index';

src/setPublicPath.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Wire the runtime asset-path global into webpack's publicPath.
2+
//
3+
// Image imports (e.g. `import bot from './ai-bot-body.png'`) and any
4+
// other webpack `asset` / `asset/resource` modules resolve their URLs
5+
// against webpack's runtime `publicPath`. The default is `'auto'`,
6+
// which infers the path from where the host page loaded the script —
7+
// not what we want when the package is embedded into a consumer like
8+
// apps's dashboard, which serves these images from a different base
9+
// path (e.g. `/blockly/media/skins/ailab/`).
10+
//
11+
// Webpack exposes `__webpack_public_path__` as a magic variable: any
12+
// assignment to it at runtime updates the publicPath used by
13+
// subsequently-evaluated asset modules. We pull the desired base from
14+
// the same global the dataset/manifest loader already uses
15+
// (`__ml_playground_asset_public_path__`), so the consumer has one
16+
// knob to turn.
17+
//
18+
// This module MUST be imported before any module that pulls in an
19+
// image — i.e. it should be the first import in the entry file.
20+
// ECMAScript guarantees depth-first evaluation order: when an entry
21+
// does `import './setPublicPath'; import './index';`, this module's
22+
// body runs to completion before `./index` starts evaluating, so all
23+
// downstream asset modules see the updated `__webpack_public_path__`.
24+
// `__webpack_public_path__` is a webpack magic variable: at build time
25+
// webpack rewrites assignments to it as updates to its runtime
26+
// `__webpack_require__.p`. ESLint doesn't understand this — it sees a
27+
// `let` with a single assignment and no read, hence the disables.
28+
/* eslint-disable prefer-const, @typescript-eslint/no-unused-vars */
29+
declare let __webpack_public_path__: string;
30+
__webpack_public_path__ =
31+
(global as unknown as Record<string, string>)
32+
.__ml_playground_asset_public_path__ || './';
33+
/* eslint-enable prefer-const, @typescript-eslint/no-unused-vars */

webpack.config.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,14 @@ const commonConfig = {
3838
},
3939
},
4040
generator: {
41-
filename: 'assets/images/[name][ext][query]',
41+
// URLs resolve to `<__webpack_public_path__>images/<name>`
42+
// at runtime. The consumer sets the public path via
43+
// `__ml_playground_asset_public_path__` (see
44+
// `src/setPublicPath.ts`); leaving an `assets/` prefix here
45+
// would double up against consumer paths that already end
46+
// in `assets/` or similar, so the prefix lives entirely on
47+
// the consumer side.
48+
filename: 'images/[name][ext][query]',
4249
},
4350
},
4451
],

0 commit comments

Comments
 (0)