diff --git a/.changeset/allow-debug-url-customize.md b/.changeset/allow-debug-url-customize.md
new file mode 100644
index 0000000000..51ef3836fe
--- /dev/null
+++ b/.changeset/allow-debug-url-customize.md
@@ -0,0 +1,5 @@
+---
+"@lynx-js/template-webpack-plugin": patch
+---
+
+feat: allow `templateDebugUrl` to be customized via `output.publicPath` or the `beforeEncode` hook.
diff --git a/packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts b/packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts
index 574cd61ad4..38c8287030 100644
--- a/packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts
+++ b/packages/webpack/template-webpack-plugin/src/LynxTemplatePlugin.ts
@@ -757,13 +757,31 @@ class LynxTemplatePluginImpl {
cssPlugins,
enableCSSSelector,
);
+
+ let templateDebugUrl = '';
+ const debugInfoPath = path.posix.format({
+ dir: intermediate,
+ base: 'debug-info.json',
+ });
+ // TODO: Support publicPath function
+ if (
+ typeof compiler.options.output.publicPath === 'string'
+ && compiler.options.output.publicPath !== 'auto'
+ && compiler.options.output.publicPath !== '/'
+ ) {
+ templateDebugUrl = new URL(
+ debugInfoPath,
+ compiler.options.output.publicPath,
+ ).toString();
+ }
+
const encodeRawData: EncodeRawData = {
compilerOptions: {
enableFiberArch: true,
useLepusNG: true,
enableReuseContext: true,
bundleModuleMode: 'ReturnByFunction',
- templateDebugUrl: '',
+ templateDebugUrl,
debugInfoOutside,
defaultDisplayLinear,
@@ -844,23 +862,6 @@ class LynxTemplatePluginImpl {
},
};
- const debugInfoPath = path.posix.format({
- dir: intermediate,
- base: 'debug-info.json',
- });
-
- // TODO: Support publicPath function
- if (
- typeof compiler.options.output.publicPath === 'string'
- && compiler.options.output.publicPath !== 'auto'
- && compiler.options.output.publicPath !== '/'
- ) {
- resolvedEncodeOptions.compilerOptions['templateDebugUrl'] = new URL(
- debugInfoPath,
- compiler.options.output.publicPath,
- ).toString();
- }
-
const { RawSource } = compiler.webpack.sources;
if (isDebug() || isDev) {
diff --git a/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-before-encode/index.js b/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-before-encode/index.js
new file mode 100644
index 0000000000..a7cc460a31
--- /dev/null
+++ b/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-before-encode/index.js
@@ -0,0 +1,26 @@
+///
+
+import fs from 'node:fs/promises';
+import path from 'node:path';
+
+it('should have debug-info.json emitted', async () => {
+ const content = await fs.readFile(
+ path.resolve(__dirname, '.rspeedy/main/debug-info.json'),
+ );
+
+ expect(content.length).not.toBe(0);
+});
+
+it('should have custom templateDebugUrl in tasm.json from hook', async () => {
+ const tasmJSON = await fs.readFile(
+ path.resolve(__dirname, '.rspeedy/main/tasm.json'),
+ 'utf-8',
+ );
+
+ const { compilerOptions } = JSON.parse(tasmJSON);
+
+ expect(compilerOptions).toHaveProperty(
+ 'templateDebugUrl',
+ 'https://custom-hook-url.com/debug-info.json',
+ );
+});
diff --git a/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-before-encode/rspack.config.js b/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-before-encode/rspack.config.js
new file mode 100644
index 0000000000..502af421d0
--- /dev/null
+++ b/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-before-encode/rspack.config.js
@@ -0,0 +1,3 @@
+import config from './webpack.config.js';
+
+export default config;
diff --git a/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-before-encode/webpack.config.js b/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-before-encode/webpack.config.js
new file mode 100644
index 0000000000..3553c3eb93
--- /dev/null
+++ b/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-before-encode/webpack.config.js
@@ -0,0 +1,31 @@
+import { LynxEncodePlugin, LynxTemplatePlugin } from '../../../../src';
+
+/** @type {import('webpack').Configuration} */
+export default {
+ mode: 'development',
+ target: 'node',
+ output: {
+ publicPath: 'https://should-be-overridden.com/',
+ },
+ plugins: [
+ new LynxEncodePlugin(),
+ new LynxTemplatePlugin({
+ intermediate: '.rspeedy/main',
+ }),
+ {
+ apply(compiler) {
+ compiler.hooks.compilation.tap('TestPlugin', (compilation) => {
+ LynxTemplatePlugin.getLynxTemplatePluginHooks(compilation)
+ .beforeEncode.tap(
+ 'TestPlugin',
+ (data) => {
+ data.encodeData.compilerOptions.templateDebugUrl =
+ 'https://custom-hook-url.com/debug-info.json';
+ return data;
+ },
+ );
+ });
+ },
+ },
+ ],
+};
diff --git a/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-public-path-custom/index.js b/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-public-path-custom/index.js
new file mode 100644
index 0000000000..9d336fd437
--- /dev/null
+++ b/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-public-path-custom/index.js
@@ -0,0 +1,26 @@
+///
+
+import fs from 'node:fs/promises';
+import path from 'node:path';
+
+it('should have debug-info.json emitted', async () => {
+ const content = await fs.readFile(
+ path.resolve(__dirname, '.rspeedy/main/debug-info.json'),
+ );
+
+ expect(content.length).not.toBe(0);
+});
+
+it('should have templateDebugUrl in tasm.json', async () => {
+ const tasmJSON = await fs.readFile(
+ path.resolve(__dirname, '.rspeedy/main/tasm.json'),
+ 'utf-8',
+ );
+
+ const { compilerOptions } = JSON.parse(tasmJSON);
+
+ expect(compilerOptions).toHaveProperty(
+ 'templateDebugUrl',
+ 'https://example.com/.rspeedy/main/debug-info.json',
+ );
+});
diff --git a/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-public-path-custom/rspack.config.js b/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-public-path-custom/rspack.config.js
new file mode 100644
index 0000000000..502af421d0
--- /dev/null
+++ b/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-public-path-custom/rspack.config.js
@@ -0,0 +1,3 @@
+import config from './webpack.config.js';
+
+export default config;
diff --git a/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-public-path-custom/webpack.config.js b/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-public-path-custom/webpack.config.js
new file mode 100644
index 0000000000..f8abb29fcd
--- /dev/null
+++ b/packages/webpack/template-webpack-plugin/test/cases/assets/debug-info-public-path-custom/webpack.config.js
@@ -0,0 +1,16 @@
+import { LynxEncodePlugin, LynxTemplatePlugin } from '../../../../src';
+
+/** @type {import('webpack').Configuration} */
+export default {
+ mode: 'development',
+ target: 'node',
+ output: {
+ publicPath: 'https://example.com/',
+ },
+ plugins: [
+ new LynxEncodePlugin(),
+ new LynxTemplatePlugin({
+ intermediate: '.rspeedy/main',
+ }),
+ ],
+};