This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 9d1d396a9b fix: fix extension e2e flow (#35589)
9d1d396a9b is described below

commit 9d1d396a9bbc2b0d2f5da6e2d9ebd4a00a6a62fb
Author: Ville Brofeldt <[email protected]>
AuthorDate: Sat Oct 11 11:31:44 2025 -0700

    fix: fix extension e2e flow (#35589)
    
    Co-authored-by: Ville Brofeldt <[email protected]>
---
 .../src/superset_extensions_cli/cli.py             | 26 +++++++--
 .../templates/backend/src/package/__init__.py.j2   |  0
 .../templates/backend/src/package/entrypoint.py.j2 |  1 +
 .../templates/frontend/package.json.j2             |  2 +-
 .../templates/frontend/src/index.tsx.j2            | 13 +++++
 .../templates/frontend/tsconfig.json.j2            | 13 +++++
 .../templates/frontend/webpack.config.js.j2        | 67 ++++++++++++++++++++++
 7 files changed, 117 insertions(+), 5 deletions(-)

diff --git a/superset-extensions-cli/src/superset_extensions_cli/cli.py 
b/superset-extensions-cli/src/superset_extensions_cli/cli.py
index 06ca4508f1..294fff1f54 100644
--- a/superset-extensions-cli/src/superset_extensions_cli/cli.py
+++ b/superset-extensions-cli/src/superset_extensions_cli/cli.py
@@ -441,24 +441,42 @@ def init() -> None:
     (target_dir / "extension.json").write_text(extension_json)
     click.secho("✅ Created extension.json", fg="green")
 
-    # Copy frontend template
+    # Initialize frontend files
     if include_frontend:
         frontend_dir = target_dir / "frontend"
         frontend_dir.mkdir()
+        frontend_src_dir = frontend_dir / "src"
+        frontend_src_dir.mkdir()
 
-        # package.json
+        # frontend files
         package_json = env.get_template("frontend/package.json.j2").render(ctx)
         (frontend_dir / "package.json").write_text(package_json)
+        webpack_config = 
env.get_template("frontend/webpack.config.js.j2").render(ctx)
+        (frontend_dir / "webpack.config.js").write_text(webpack_config)
+        tsconfig_json = 
env.get_template("frontend/tsconfig.json.j2").render(ctx)
+        (frontend_dir / "tsconfig.json").write_text(tsconfig_json)
+        index_tsx = env.get_template("frontend/src/index.tsx.j2").render(ctx)
+        (frontend_src_dir / "index.tsx").write_text(index_tsx)
         click.secho("✅ Created frontend folder structure", fg="green")
 
-    # Copy backend template
+    # Initialize backend files
     if include_backend:
         backend_dir = target_dir / "backend"
         backend_dir.mkdir()
+        backend_src_dir = backend_dir / "src"
+        backend_src_dir.mkdir()
+        backend_src_package_dir = backend_src_dir / id_
+        backend_src_package_dir.mkdir()
 
-        # pyproject.toml
+        # backend files
         pyproject_toml = 
env.get_template("backend/pyproject.toml.j2").render(ctx)
         (backend_dir / "pyproject.toml").write_text(pyproject_toml)
+        init_py = 
env.get_template("backend/src/package/__init__.py.j2").render(ctx)
+        (backend_src_package_dir / "__init__.py").write_text(init_py)
+        entrypoint_py = 
env.get_template("backend/src/package/entrypoint.py.j2").render(
+            ctx
+        )
+        (backend_src_package_dir / "entrypoint.py").write_text(entrypoint_py)
 
         click.secho("✅ Created backend folder structure", fg="green")
 
diff --git 
a/superset-extensions-cli/src/superset_extensions_cli/templates/backend/src/package/__init__.py.j2
 
b/superset-extensions-cli/src/superset_extensions_cli/templates/backend/src/package/__init__.py.j2
new file mode 100644
index 0000000000..e69de29bb2
diff --git 
a/superset-extensions-cli/src/superset_extensions_cli/templates/backend/src/package/entrypoint.py.j2
 
b/superset-extensions-cli/src/superset_extensions_cli/templates/backend/src/package/entrypoint.py.j2
new file mode 100644
index 0000000000..2ff158bf99
--- /dev/null
+++ 
b/superset-extensions-cli/src/superset_extensions_cli/templates/backend/src/package/entrypoint.py.j2
@@ -0,0 +1 @@
+print("{{ name }} extension registered")
diff --git 
a/superset-extensions-cli/src/superset_extensions_cli/templates/frontend/package.json.j2
 
b/superset-extensions-cli/src/superset_extensions_cli/templates/frontend/package.json.j2
index 6ad06143be..971902917f 100644
--- 
a/superset-extensions-cli/src/superset_extensions_cli/templates/frontend/package.json.j2
+++ 
b/superset-extensions-cli/src/superset_extensions_cli/templates/frontend/package.json.j2
@@ -14,7 +14,7 @@
   "license": "{{ license }}",
   "description": "",
   "peerDependencies": {
-    "@apache-superset/core": 
"file:../../../superset-frontend/packages/superset-core",
+    "@apache-superset/core": "*",
     "react": "^17.0.2",
     "react-dom": "^17.0.2"
   },
diff --git 
a/superset-extensions-cli/src/superset_extensions_cli/templates/frontend/src/index.tsx.j2
 
b/superset-extensions-cli/src/superset_extensions_cli/templates/frontend/src/index.tsx.j2
new file mode 100644
index 0000000000..b9a6266216
--- /dev/null
+++ 
b/superset-extensions-cli/src/superset_extensions_cli/templates/frontend/src/index.tsx.j2
@@ -0,0 +1,13 @@
+import React from "react";
+import { core } from "@apache-superset/core";
+
+export const activate = (context: core.ExtensionContext) => {
+  context.disposables.push(
+    core.registerViewProvider("{{ id }}.example", () => <p>{{ name }}</p>)
+  );
+  console.log("{{ name }} extension activated");
+};
+
+export const deactivate = () => {
+  console.log("{{ name }} extension deactivated");
+};
diff --git 
a/superset-extensions-cli/src/superset_extensions_cli/templates/frontend/tsconfig.json.j2
 
b/superset-extensions-cli/src/superset_extensions_cli/templates/frontend/tsconfig.json.j2
new file mode 100644
index 0000000000..ed813aa944
--- /dev/null
+++ 
b/superset-extensions-cli/src/superset_extensions_cli/templates/frontend/tsconfig.json.j2
@@ -0,0 +1,13 @@
+{
+  "compilerOptions": {
+    "target": "es5",
+    "module": "esnext",
+    "moduleResolution": "node10",
+    "jsx": "react",
+    "strict": true,
+    "esModuleInterop": true,
+    "skipLibCheck": true,
+    "forceConsistentCasingInFileNames": true
+  },
+  "include": ["src"]
+}
diff --git 
a/superset-extensions-cli/src/superset_extensions_cli/templates/frontend/webpack.config.js.j2
 
b/superset-extensions-cli/src/superset_extensions_cli/templates/frontend/webpack.config.js.j2
new file mode 100644
index 0000000000..25f1b5c0be
--- /dev/null
+++ 
b/superset-extensions-cli/src/superset_extensions_cli/templates/frontend/webpack.config.js.j2
@@ -0,0 +1,67 @@
+const path = require("path");
+const { ModuleFederationPlugin } = require("webpack").container;
+const packageConfig = require("./package");
+
+module.exports = (env, argv) => {
+  const isProd = argv.mode === "production";
+
+  return {
+    entry: isProd ? {} : "./src/index.tsx",
+    mode: isProd ? "production" : "development",
+    devServer: {
+      port: 3000,
+      headers: {
+        "Access-Control-Allow-Origin": "*",
+      },
+    },
+    output: {
+      clean: true,
+      filename: isProd ? undefined : "[name].[contenthash].js",
+      chunkFilename: "[name].[contenthash].js",
+      path: path.resolve(__dirname, "dist"),
+      publicPath: `/api/v1/extensions/${packageConfig.name}/`,
+    },
+    resolve: {
+      extensions: [".ts", ".tsx", ".js", ".jsx"],
+    },
+    externalsType: "window",
+    externals: {
+      "@apache-superset/core": "superset",
+    },
+    module: {
+      rules: [
+        {
+          test: /\.tsx?$/,
+          use: "ts-loader",
+          exclude: /node_modules/,
+        },
+      ],
+    },
+    plugins: [
+      new ModuleFederationPlugin({
+        name: "{{ id }}",
+        filename: "remoteEntry.[contenthash].js",
+        exposes: {
+          "./index": "./src/index.tsx",
+        },
+        shared: {
+          react: {
+            singleton: true,
+            requiredVersion: packageConfig.peerDependencies.react,
+            import: false,
+          },
+          "react-dom": {
+            singleton: true,
+            requiredVersion: packageConfig.peerDependencies["react-dom"],
+            import: false,
+          },
+          antd: {
+            singleton: true,
+            requiredVersion: packageConfig.peerDependencies["antd"],
+            import: false,
+          },
+        },
+      }),
+    ],
+  };
+};

Reply via email to