Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compile TypeScript functions source in functions emulator #5633

Open
blidd-google opened this issue Mar 28, 2023 · 3 comments
Open

Compile TypeScript functions source in functions emulator #5633

blidd-google opened this issue Mar 28, 2023 · 3 comments

Comments

@blidd-google
Copy link
Contributor

Today, developers must compile TypeScript code manually by running tsc or tsc --watch before starting the functions emulator to avoid running into a functions source-loading error (see #5627). This feature request is to implement the equivalent of pre-deploy hooks for the emulator so that developers can instruct the emulator on how to build their TypeScript functions.

@MidnightLightning
Copy link

MidnightLightning commented Mar 30, 2023

...to implement the equivalent of pre-deploy hooks for the emulator

Currently, the Emulator infrastructure has a "watch" capacity that is monitoring the /functions folder for file changes when the emulator is up. An alternative to creating a separate section that needs configuration for Typescript functions is to update the logic of the "watch" functionality to detect if it's a *.js file (just try updating it) or *.ts file (compile first, then update it).

@ArturAmpilogov
Copy link

...to implement the equivalent of pre-deploy hooks for the emulator

Currently, the Emulator infrastructure has a "watch" capacity that is monitoring the /functions folder for file changes when the emulator is up. An alternative to creating a separate section that needs configuration for Typescript functions is to update the logic of the "watch" functionality to detect if it's a *.js file (just try updating it) or *.ts file (compile first, then update it).

Second that it might better to have a usual setup for TypeScript build and watch processes from tsc, instead of a custom secret tsconfig/bundler usage.

From my experience, a proper functions support for the modern development style requires:

  1. To have an init command of a Firebase project in TypeScript, for example, firebase init --typesrcipt.

  2. During typescript initialization to see tsconfig file, so that it will be easier it to change and modify, plus dependent npm packages: typescript, babel, whatever is needed. No secret bundlers.

  3. Allow to filter files to watch for changes and hot-reload functions emulator: *.js by default.

  4. In addition to tsc -c, tsc --watch, support modern TypeScript solution build with tsc -b and tsc -b --watch, where -b/--build compiles referenced projects (parent projects in a dependency chain).

  5. Affects point 4. In a monorepo locally shared projects are not installed during functions deployment. At the same time all works fine in a local simulator. The whole concept of a solution division on modules (packages) is broken. Modern monorepo tools: Turborepo, Nx. Also can be used without monorepo, for example, by manually dividing a solution on packages and build them with tsc --build.

    Personally found a workaround to bundle such shared libraries with TypeScript and Rollup, but it is very tedious and error prone to set up.

@gustavopch
Copy link

gustavopch commented Jul 5, 2023

I think I figured how to do it by patching firebase-tools and firebase-functions.

  1. Install @esbuild-kit/esm-loader.

  2. Patch this file:
    https://github.com/firebase/firebase-tools/blob/master/src/emulator/functionsEmulator.ts#L1306

-    const args = [path.join(__dirname, "functionsEmulatorRuntime")];
+    const args = ["--loader=@esbuild-kit/esm-loader", path.join(__dirname, "functionsEmulatorRuntime")];
  1. Patch this file:
    https://github.com/firebase/firebase-functions/blob/master/src/bin/firebase-functions.ts#L1
-#!/usr/bin/env node
+#!/usr/bin/env node --loader=@esbuild-kit/esm-loader

Voilà!

Not sure why yet, but it seems the entry file in special must be .js (but then you can import .ts from it). And of course you'll need to transpile when deploying as these patches will only solve it for the emulator.

Edit: I also patched @esbuild-kit/esm-loader to make it resolve .js(x) imports to .ts(x) files, and to remove process.send() calls that were polluting the emulator logs with lots of [object Object].

Edit 2: This would make it even easier: #6112, please leave a 👍 there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants