Repository: firebase/firebase-tools (ts)

Issue:
Emulator doesn't work with demo projects + web frameworks
<!-- DO NOT DELETE
validate_template=true
template_path=.github/ISSUE_TEMPLATE/bug_report.md
-->

<!--
Thank you for contributing to the Firebase community!

Think you found a bug?
=======================
Yeah, we're definitely not perfect! Please use this template and include a minimal repro when opening the issue. If you know how to solve the issue, please create a Pull Request, and we'd be happy to review it!

Have a feature request?
========================
Great, we love hearing how we can improve our products! However, do not use this template to submit a feature request. Please submit your feature requests to: https://firebase.google.com/support/contact/bugs-features/

Have a usage question?
=======================
We get lots of those and we love helping you, but GitHub is not the best place for them and they will be closed. Please take a look at the guide first: https://firebase.google.com/docs/cli/

If the official documentation doesn't help, try asking through our official support channel: https://firebase.google.com/support/

Additional locations to check for solutions or assistance from the community:
- Stack Overflow: https://stackoverflow.com/
- Firebase Slack Community: https://firebase.community/

*Please avoid duplicate posting across multiple channels!*
-->

### [REQUIRED] Environment info

<!-- What version of the Firebase CLI (`firebase-tools`) are you using? Note that your issue may already be fixed in the latest versions. The latest version can be found at https://github.com/firebase/firebase-tools/releases -->

<!-- Output of `firebase --version` -->

**firebase-tools:**
12.5.4

<!-- e.g. macOS, Windows, Ubuntu -->

**Platform:**
ChromeOS/linux

### [REQUIRED] Test case

<!-- Provide a minimal, complete, and verifiable example (http://stackoverflow.com/help/mcve) -->

1. Setup with  firebase init
- Select firestore, hosting, functions
- defaults for everything except hosting
  - Select use frameworks, vite, javascript

2. Run firebase emulators:start --project demo-x

So far things work OK.

3. Kill the emulator
4. cd hosting
5. npm i --save firebase
6. cd ..
7. run firebase emulators:start --project demo-x

Expected to run fine, but fails with error:

Error: could not find sites for project "demo-x"
 
### [REQUIRED] Steps to reproduce

<!-- Provide the steps needed to reproduce the issue with the above test case. -->

See above

### [REQUIRED] Expected behavior

<!-- What is the expected behavior? -->

Adding firebase as a dependency to the web framework should still work with demo projects.

### [REQUIRED] Actual behavior

fails with error:
Error: could not find sites for project "demo-x"

<!-- Run the command with --debug flag, and include the logs below. -->


Pull request description:
remove public directory from hosting emulator for frameworks
<!--

Thank you for contributing to the Firebase community! Please fill out the form below.

Run the linter and test suite
==============================
Run `npm test` to make sure your changes compile properly and the tests all pass on your local machine. We've hooked up this repo with continuous integration to double check those things for you.

-->

### Description

Should fix #6377

<!-- Are you fixing a bug? Implementing a new feature? Make sure we have the context around your change. Link to other relevant issues or pull requests. -->

### Scenarios Tested

<!-- Write a list of all the user journeys and edge cases you've tested. Instructions for manual testing can be found at https://github.com/firebase/firebase-tools/blob/master/.github/CONTRIBUTING.md#development-setup -->

### Sample Commands

<!-- Proposing a change to commands or flags? Provide examples of how they will be used. -->


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dd5aaaa96..33037f7e2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,3 +3,4 @@
 - Add force flag to delete backend (#6635).
 - Use framework build target in Vite builds (#6643).
 - Use framework build target in NODE_ENV for production Vite builds (#6644)
+- Let framework handle public directory with emulator. (#6674)
diff --git a/src/frameworks/angular/index.ts b/src/frameworks/angular/index.ts
index 691584624..8e0f80a19 100644
--- a/src/frameworks/angular/index.ts
+++ b/src/frameworks/angular/index.ts
@@ -42,7 +42,7 @@ export async function discover(dir: string): Promise<Discovery | undefined> {
   if (!(await pathExists(join(dir, "package.json")))) return;
   if (!(await pathExists(join(dir, "angular.json")))) return;
   const version = getAngularVersion(dir);
-  return { mayWantBackend: true, publicDirectory: join(dir, "src", "assets"), version };
+  return { mayWantBackend: true, version };
 }
 
 export function init(setup: any, config: any) {
diff --git a/src/frameworks/astro/index.ts b/src/frameworks/astro/index.ts
index 3f0bd4923..346913e40 100644
--- a/src/frameworks/astro/index.ts
+++ b/src/frameworks/astro/index.ts
@@ -15,10 +15,9 @@ export async function discover(dir: string): Promise<Discovery | undefined> {
   if (!existsSync(join(dir, "package.json"))) return;
   const version = getAstroVersion(dir);
   if (!version) return;
-  const { output, publicDir: publicDirectory } = await getConfig(dir);
+  const { output } = await getConfig(dir);
   return {
     mayWantBackend: output !== "static",
-    publicDirectory,
     version,
   };
 }
diff --git a/src/frameworks/flutter/index.ts b/src/frameworks/flutter/index.ts
index 2e21849bc..c77afaa97 100644
--- a/src/frameworks/flutter/index.ts
+++ b/src/frameworks/flutter/index.ts
@@ -20,7 +20,7 @@ export async function discover(dir: string): Promise<Discovery | undefined> {
   const pubSpec = loadYaml(pubSpecBuffer.toString());
   const usingFlutter = pubSpec.dependencies?.flutter;
   if (!usingFlutter) return;
-  return { mayWantBackend: false, publicDirectory: join(dir, "web") };
+  return { mayWantBackend: false };
 }
 
 export function init(setup: any, config: any) {
diff --git a/src/frameworks/index.ts b/src/frameworks/index.ts
index f5dc59b59..a49029369 100644
--- a/src/frameworks/index.ts
+++ b/src/frameworks/index.ts
@@ -254,7 +254,7 @@ export async function prepareFrameworks(
         )
       );
     }
-    const { framework, mayWantBackend, publicDirectory } = results;
+    const { framework, mayWantBackend } = results;
     const {
       build,
       ɵcodegenPublicDirectory,
@@ -304,7 +304,6 @@ export async function prepareFrameworks(
       getDevModeHandle &&
       (await getDevModeHandle(getProjectPath(), frameworksBuildTarget, hostingEmulatorInfo));
     if (devModeHandle) {
-      config.public = relative(projectRoot, publicDirectory);
       // Attach the handle to options, it will be used when spinning up superstatic
       options.frameworksDevModeHandle = devModeHandle;
       // null is the dev-mode entry for firebase-framework-tools
@@ -339,10 +338,10 @@ export async function prepareFrameworks(
         site,
       });
 
-      config.public = relative(projectRoot, hostingDist);
       if (wantsBackend && !omitCloudFunction)
         codegenFunctionsDirectory = codegenProdModeFunctionsDirectory;
     }
+    config.public = relative(projectRoot, hostingDist);
     config.webFramework = `${framework}${codegenFunctionsDirectory ? "_ssr" : ""}`;
     if (codegenFunctionsDirectory) {
       if (firebaseDefaults) {
diff --git a/src/frameworks/interfaces.ts b/src/frameworks/interfaces.ts
index 0ea91951b..e40ab5611 100644
--- a/src/frameworks/interfaces.ts
+++ b/src/frameworks/interfaces.ts
@@ -22,7 +22,6 @@ export const enum SupportLevel {
 
 export interface Discovery {
   mayWantBackend: boolean;
-  publicDirectory: string;
   version?: string;
   vite?: boolean;
 }
diff --git a/src/frameworks/nuxt/index.ts b/src/frameworks/nuxt/index.ts
index b86001758..073578cac 100644
--- a/src/frameworks/nuxt/index.ts
+++ b/src/frameworks/nuxt/index.ts
@@ -33,12 +33,9 @@ export async function discover(dir: string) {
   if (!anyConfigFileExists && !version) return;
   if (version && lt(version, "3.0.0-0")) return;
 
-  const {
-    dir: { public: publicDirectory },
-    ssr: mayWantBackend,
-  } = await getConfig(dir);
+  const { ssr: mayWantBackend } = await getConfig(dir);
 
-  return { publicDirectory, mayWantBackend, version };
+  return { mayWantBackend, version };
 }
 
 export async function build(cwd: string) {
diff --git a/src/frameworks/nuxt2/index.ts b/src/frameworks/nuxt2/index.ts
index 381ed59a5..c67178c95 100644
--- a/src/frameworks/nuxt2/index.ts
+++ b/src/frameworks/nuxt2/index.ts
@@ -30,8 +30,7 @@ export async function discover(rootDir: string) {
   if (!(await pathExists(join(rootDir, "package.json")))) return;
   const version = getNuxtVersion(rootDir);
   if (!version || (version && gte(version, "3.0.0-0"))) return;
-  const { app } = await getAndLoadNuxt({ rootDir, for: "build" });
-  return { mayWantBackend: true, publicDirectory: app.options.dir.static, version };
+  return { mayWantBackend: true, version };
 }
 
 /**


Test patch:
diff --git a/src/test/frameworks/angular/index.spec.ts b/src/test/frameworks/angular/index.spec.ts
index 20721ce61..d9b85d1bd 100644
--- a/src/test/frameworks/angular/index.spec.ts
+++ b/src/test/frameworks/angular/index.spec.ts
@@ -3,7 +3,6 @@ import * as sinon from "sinon";
 import * as fsExtra from "fs-extra";
 
 import { discover } from "../../../frameworks/angular";
-import { join } from "path";
 
 describe("Angular", () => {
   describe("discovery", () => {
@@ -22,7 +21,6 @@ describe("Angular", () => {
       sandbox.stub(fsExtra, "pathExists").resolves(true);
       expect(await discover(cwd)).to.deep.equal({
         mayWantBackend: true,
-        publicDirectory: join(cwd, "src", "assets"),
         version: undefined,
       });
     });
diff --git a/src/test/frameworks/astro/index.spec.ts b/src/test/frameworks/astro/index.spec.ts
index 6f1d42a7d..a4494cfb2 100644
--- a/src/test/frameworks/astro/index.spec.ts
+++ b/src/test/frameworks/astro/index.spec.ts
@@ -53,7 +53,6 @@ describe("Astro", () => {
         });
       expect(await discover(cwd)).to.deep.equal({
         mayWantBackend: false,
-        publicDirectory: publicDir,
         version: "2.2.2",
       });
     });
@@ -84,7 +83,6 @@ describe("Astro", () => {
         });
       expect(await discover(cwd)).to.deep.equal({
         mayWantBackend: true,
-        publicDirectory: publicDir,
         version: "2.2.2",
       });
     });
diff --git a/src/test/frameworks/flutter/index.spec.ts b/src/test/frameworks/flutter/index.spec.ts
index 40590fae3..e806aede1 100644
--- a/src/test/frameworks/flutter/index.spec.ts
+++ b/src/test/frameworks/flutter/index.spec.ts
@@ -35,7 +35,6 @@ describe("Flutter", () => {
         );
       expect(await discover(cwd)).to.deep.equal({
         mayWantBackend: false,
-        publicDirectory: "web",
       });
     });
 
diff --git a/src/test/frameworks/nuxt/index.spec.ts b/src/test/frameworks/nuxt/index.spec.ts
index 2ffabcf6a..0f63cf064 100644
--- a/src/test/frameworks/nuxt/index.spec.ts
+++ b/src/test/frameworks/nuxt/index.spec.ts
@@ -44,7 +44,6 @@ describe("Nuxt 2 utils", () => {
 
       expect(await discoverNuxt2(discoverNuxtDir)).to.deep.equal({
         mayWantBackend: true,
-        publicDirectory: "static",
         version: "2.15.8",
       });
     });
@@ -75,7 +74,6 @@ describe("Nuxt 2 utils", () => {
 
       expect(await discoverNuxt3(discoverNuxtDir)).to.deep.equal({
         mayWantBackend: true,
-        publicDirectory: "public",
         version: "3.0.0",
       });
     });