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,
+ },
+ },
+ }),
+ ],
+ };
+};