Skip to content

Commit e7d9f5a

Browse files
committed
feat(bundlers): warn if plugins are not used
1 parent 3fc7786 commit e7d9f5a

File tree

10 files changed

+87
-10
lines changed

10 files changed

+87
-10
lines changed

packages/alphatab/src/Environment.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,15 @@ export class Environment {
697697
try {
698698
// @ts-expect-error
699699
if (typeof __webpack_require__ === 'function') {
700+
// check if webpack plugin was used
701+
// @ts-expect-error
702+
if (typeof __ALPHATAB_WEBPACK__ !== 'boolean') {
703+
Logger.warning(
704+
'WebPack',
705+
`Detected bundling with WebPack but @coderline/alphatab-webpcak was not used! To ensure alphaTab works as expected use our bundler plugins. Learn more at https://www.alphatab.net/docs/getting-started/installation-webpack`
706+
);
707+
}
708+
700709
return true;
701710
}
702711
} catch {
@@ -712,6 +721,15 @@ export class Environment {
712721
try {
713722
// @ts-expect-error
714723
if (typeof __BASE__ === 'string') {
724+
// check if vite plugin was used
725+
// @ts-expect-error
726+
if (typeof __ALPHATAB_VITE__ !== 'boolean') {
727+
Logger.warning(
728+
'Vite',
729+
`Detected bundling with Vite but @coderline/alphatab-vite was not used! To ensure alphaTab works as expected use our bundler plugins. Learn more at https://www.alphatab.net/docs/getting-started/installation-vite`
730+
);
731+
}
732+
715733
return true;
716734
}
717735
} catch {

packages/vite/src/alphaTabVitePlugin.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { detectionGlobalPlugin } from '@coderline/alphatab-vite/detectionGlobalPlugin';
12
import type { AlphaTabVitePluginOptions } from './AlphaTabVitePluginOptions';
23
import type { Plugin } from './bridge';
34
import { copyAssetsPlugin } from './copyAssetsPlugin';
@@ -12,6 +13,7 @@ export function alphaTab(options?: AlphaTabVitePluginOptions) {
1213

1314
options ??= {};
1415

16+
plugins.push(detectionGlobalPlugin());
1517
plugins.push(importMetaUrlPlugin(options));
1618
plugins.push(workerPlugin(options));
1719
plugins.push(copyAssetsPlugin(options));
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import MagicString from 'magic-string';
2+
import type { Plugin, ResolvedConfig } from './bridge';
3+
4+
const marker = '__ALPHATAB_VITE__';
5+
6+
/**
7+
* @public
8+
*/
9+
export function detectionGlobalPlugin(): Plugin {
10+
let resolvedConfig: ResolvedConfig;
11+
return {
12+
name: 'vite-plugin-alphatab-global',
13+
14+
configResolved(config) {
15+
resolvedConfig = config as ResolvedConfig;
16+
},
17+
18+
shouldTransformCachedModule({ code }) {
19+
return code.includes(marker);
20+
},
21+
22+
async transform(code, id) {
23+
if (!code.includes(marker)) {
24+
return;
25+
}
26+
27+
const s = new MagicString(code);
28+
s.replaceAll(marker, JSON.stringify(true));
29+
return {
30+
code: s.toString(),
31+
map:
32+
resolvedConfig.command === 'build' && resolvedConfig.build.sourcemap
33+
? s.generateMap({ hires: 'boundary', source: id })
34+
: null
35+
};
36+
}
37+
};
38+
}

packages/vite/test/Vite.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ describe('Vite', () => {
6262
expect(text).to.include('assets/alphaTab.worklet-');
6363
// without custom chunking the app will bundle alphatab directly
6464
expect(text).to.include(".at-surface");
65+
// ensure __ALPHATAB_VITE__ got replaced
66+
expect(text).to.not.include("__ALPHATAB_VITE__");
6567
appValidated = true;
6668
} else if (file.name.startsWith('alphaTab.worker-')) {
6769
expect(text).to.include('initializeWorker()');

packages/webpack/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"test": "mocha"
4343
},
4444
"dependencies": {
45-
"webpack": "^5.101.3"
45+
"webpack": "^5.103.0"
4646
},
4747
"engines": {
4848
"node": ">=20.19.0"

packages/webpack/src/AlphaTabWebPackPlugin.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type { webPackWithAlphaTab, webpackTypes } from './Utils';
1414
import { injectWebWorkerDependency } from './AlphaTabWebWorkerDependency';
1515
import { injectWorkletRuntimeModule } from './AlphaTabWorkletStartRuntimeModule';
1616
import { injectWorkletDependency } from './AlphaTabWorkletDependency';
17+
import { configureDetectionGlobal } from '@coderline/alphatab-webpack/DetectionGlobal';
1718

1819
const WINDOWS_ABS_PATH_REGEXP = /^[a-zA-Z]:[\\/]/;
1920
const WINDOWS_PATH_SEPARATOR_REGEXP = /\\/g;
@@ -219,6 +220,7 @@ export class AlphaTabWebPackPlugin {
219220
cachedContextify
220221
);
221222
this._configureAssetCopy(this._webPackWithAlphaTab, pluginName, compiler, compilation);
223+
configureDetectionGlobal(pluginName, normalModuleFactory);
222224
});
223225
}
224226

packages/webpack/src/AlphaTabWebWorkerDependency.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ export function injectWebWorkerDependency(webPackWithAlphaTab: webPackWithAlphaT
8181
runtimeRequirements.add(webPackWithAlphaTab.webpack.RuntimeGlobals.getChunkScriptFilename);
8282

8383
source.replace(
84-
dep.range[0],
85-
dep.range[1] - 1,
84+
dep.range![0],
85+
dep.range![1] - 1,
8686
`/* worker import */ ${workerImportBaseUrl} + ${
8787
webPackWithAlphaTab.webpack.RuntimeGlobals.getChunkScriptFilename
8888
}(${JSON.stringify(chunk.id)}), ${webPackWithAlphaTab.webpack.RuntimeGlobals.baseURI}`

packages/webpack/src/AlphaTabWorkletDependency.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ export function injectWorkletDependency(webPackWithAlphaTab: webPackWithAlphaTab
9999
runtimeRequirements.add(webPackWithAlphaTab.alphaTab.RuntimeGlobalWorkletGetStartupChunks);
100100

101101
source.replace(
102-
dep.range[0],
103-
dep.range[1] - 1,
102+
dep.range![0],
103+
dep.range![1] - 1,
104104
webPackWithAlphaTab.webpack.Template.asString([
105105
'(/* worklet bootstrap */ async function(__webpack_worklet__) {',
106106
webPackWithAlphaTab.webpack.Template.indent([
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type { Expression } from 'estree';
2+
import { tapJavaScript } from './Utils';
3+
4+
/**
5+
* @internal
6+
*/
7+
export function configureDetectionGlobal(pluginName: string, normalModuleFactory: any) {
8+
const parserPlugin = (parser: any) => {
9+
parser.hooks.evaluateIdentifier.for('__ALPHATAB_WEBPACK__').tap(pluginName, (expr: Expression) => {
10+
const res = parser.evaluate('true');
11+
res.setRange(expr.range);
12+
return res;
13+
});
14+
};
15+
16+
tapJavaScript(normalModuleFactory, pluginName, parserPlugin);
17+
}

packages/webpack/test/WebPack.test.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,7 @@ describe('WebPack', () => {
3030
filename: '[name]-[contenthash:8].js',
3131
path: path.resolve('./out')
3232
},
33-
plugins: [
34-
new AlphaTabWebPackPlugin(),
35-
new HtmlWebpackPlugin()
36-
],
33+
plugins: [new AlphaTabWebPackPlugin(), new HtmlWebpackPlugin()],
3734
optimization: {
3835
minimize: false,
3936
splitChunks: {
@@ -105,7 +102,8 @@ describe('WebPack', () => {
105102
expect(text).to.include('class AlphaTabApiBase');
106103
// ensure the library mode is active as needed
107104
expect(text).to.include('alphaTabApp = __webpack_exports__');
108-
105+
// ensure __ALPHATAB_WEBPACK__ got replaced
106+
expect(text).to.not.include('__ALPHATAB_WEBPACK__');
109107
appValidated = true;
110108
} else if (file.name.endsWith('.js')) {
111109
if (text.includes('class AlphaTabApiBase')) {

0 commit comments

Comments
 (0)