Fails to handle spaces in file paths
alexeigs opened this issue · 6 comments
I'm working with a standard turbo/yarn workspaces setup as can be found in https://github.com/vercel/turbo/tree/main/examples/with-tailwind and want to use isolate-package
to isolate apps/functions
(firebase functions setup as outlined in the docs here).
Even after I gave it several tries and went over my whole setup to make sure I'm in line with both the standard turbo/yarn workspaces as well as isolate-package
setup, I do not manage though to understand what's going wrong when running isolate
, so let me share some code here.
First the actual error which occurs when I run isolate
. The problem occurs with the common
package (the only package that is needed from ./packages/*) and it seems as the path includes some parts twice with a weird cut or missing piece where usually is a whitespace (in Own Projects
):
⋊> ~/L/D/O/l/a/functions on main ⨯ isolate 20:02:31
debug Running isolate-package version 1.3.3
debug Found tsconfig at: ./tsconfig.json
debug Workspace root resolved to /Users/<username>/Own Projects/<project>
debug Isolate target package (root)/apps/functions
debug Isolate output directory (root)/apps/functions/isolate
debug Cleaned the existing isolate output directory
debug Detected package manager yarn 3.6.4
debug Override workspace packages via config: packages/*,apps/*
debug Registering package ./packages/ui-interactive
debug Registering package ./packages/ui
debug Registering package ./packages/tsconfig
debug Registering package ./packages/tailwind-config
debug Registering package ./packages/eslint-config-custom
debug Registering package ./packages/common
debug Registering package ./apps/web
debug Registering package ./apps/functions
error Error: Command failed: npm pack --pack-destination /Users/<username>/Own Projects/<project>/apps/functions/isolate/__tmp
npm WARN Ignoring workspaces for specified package(s)
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /Users/<username>/Own Projects/<project>/packages/common/Projects/<project>/apps/functions/isolate/__tmp/package.json
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/Users/<username>/Own Projects/<project>/packages/common/Projects/<project>/apps/functions/isolate/__tmp/package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/<username>/.npm/_logs/2023-10-21T18_02_37_406Z-debug-0.log
at ChildProcess.exithandler (node:child_process:419:12)
at ChildProcess.emit (node:events:513:28)
at maybeClose (node:internal/child_process:1091:16)
at Socket.<anonymous> (node:internal/child_process:449:11)
at Socket.emit (node:events:513:28)
at Pipe.<anonymous> (node:net:322:12)
... the invalid path is the following: /Users/<username>/Own Projects/<project>/packages/common/Projects/<project>/apps/functions/isolate/__tmp/package.json
which is a weird combination of /Users/<username>/Own Projects/<project>/packages/common/
and Projects/<project>/apps/functions/isolate/__tmp/package.json
where the latter path lacks the beginning and the Own
in Own Projects
Now let me share my setup:
./package.json:
{
"private": true,
"workspaces": [
"apps/*",
"packages/*"
],
"scripts": {
"build": "turbo build",
},
"prettier": "@vercel/style-guide/prettier",
"devDependencies": {
"@types/node": "^20.8.7",
"@types/react": "^18.2.29",
"@types/react-dom": "^18.2.14",
"prettier": "^3.0.3",
"prettier-plugin-tailwindcss": "^0.5.3",
"tsconfig": "*",
"turbo": "latest",
"typescript": "^5.2.2"
},
"packageManager": "yarn@3.6.4"
}
apps/functions/package.json:
{
"name": "functions",
"version": "0.0.0",
"scripts": {
"build": "tsc -b tsconfig.build.json",
},
"engines": {
"node": "18"
},
"main": "lib/index.js",
"dependencies": {
"common": "*",
"firebase-admin": "^11.8.0",
"firebase-functions": "^4.3.1"
},
"devDependencies": {
"firebase-tools": "latest",
"isolate-package": "^1.3.3",
"typescript": "^4.9.0"
},
"private": true
}
apps/functions/isolate.config.json:
{
"workspaceRoot": "../..",
"workspacePackages": ["packages/*", "apps/*"],
"logLevel": "debug"
}
apps/functions/tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"noImplicitReturns": true,
"noUnusedLocals": true,
"outDir": "lib",
"sourceMap": true,
"strict": true,
"target": "es2017"
},
"compileOnSave": true,
"include": [
"src",
"./*.d.ts"
]
}
apps/functions/tsconfig.build.json:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"rootDir": "src"
},
}
packages/common/package.json:
{
"name": "common",
"version": "0.0.0",
"private": true,
"license": "MIT",
"exports": {
".": "./dist"
},
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
"lint": "eslint src/",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"react": "^18.2.0",
"tsconfig": "*",
"tsup": "^6.1.3",
"typescript": "^5.1.6"
}
}
packages/common/tsconfig.json:
{
"extends": "tsconfig/react-library.json",
"include": ["."],
"exclude": ["dist", "build", "node_modules"]
}
packages/common/tsup.config.ts:
import { defineConfig, Options } from 'tsup';
export default defineConfig((options: Options) => ({
treeshake: true,
splitting: true,
entry: ['src/**/*.ts'],
outDir: 'dist',
format: ['esm'],
dts: true,
minify: true,
clean: true,
external: ['react'],
...options,
}));
Well, I actually answered it myself when writing the issue I guess, and could resolve it by getting rid of the white space in my local path in Own Projects
-> own_projects
. As it may still be an issue users could ran into, and you might want to fix it, I leave it open but feel free to just close it otherwise.
Given I already shared all the code above, I will still add the following issue I'm facing in this thread; in case you have a helpful input that would be much appreciated!
The isolate
output is not as expected but for when I deploy the functions
folder, my setup seems to result in the common package to be looked for in node_modules
instead of ./packages/common
:
[2023-10-21T18:51:33.785Z] > [functions] package.json contents: {
"name": "functions",
"version": "0.0.0",
"scripts": {
"build": "tsc -b tsconfig.build.json",
"build:watch": "tsc --watch",
"serve": "npm run build && firebase emulators:start --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "18"
},
"main": "lib/index.js",
"dependencies": {
"common": "file:./packages/common",
"firebase-admin": "^11.8.0",
"firebase-functions": "^4.3.1"
},
"private": true
}
[2023-10-21T18:51:33.785Z] Building nodejs source
i functions: Loading and analyzing source code for codebase default to determine what to deploy
[2023-10-21T18:51:33.786Z] Could not find functions.yaml. Must use http discovery
[2023-10-21T18:51:33.798Z] Found firebase-functions binary at '/Users/<user>/Local/Dev/own_projects/<project>/node_modules/.bin/firebase-functions'
Serving at port 8243
[2023-10-21T18:51:34.086Z] Got response code 400; body Failed to generate manifest from function source: Error: Cannot find module '/Users/<user>/Local/Dev/own_projects/<project>/node_modules/common/dist'
shutdown requested via /__/quitquitquit
Hi Alexei,
Thanks for bringing the spaces in paths issue to my attention. That is an oversight. I think programmers traditionally avoid spaces exactly for this reason but modern software should of course just handle them correctly.
As for your remaining issue. I'm not sure what you mean with
my setup seems to result in the common package to be looked for in node_modules instead of ./packages/common:
The package json you posted is from the isolate output, right? The path there correctly points to "file:./packages/common", so I'm not sure what part of your setup you are referring to.
One thing I can think of is that your build script from package.json interferes with the deploy process.
At first I omitted the scripts, but then got a request to include them, which I did in v1.3.2. But then recently a user told me that the build script is being picked up by the firebase deploy pipeline, which it shouldn't really.
So I think in the next version I am going to at least create a configuration option to include/exclude the package scripts from the isolate output manifest.
Could you try to use v1.3.1, which still omits the scripts property? If that works then we know where the problem is...
Also, I wonder why you have these configurations set:
"workspaceRoot": "../..",
"workspacePackages": ["packages/*", "apps/*"],
If you are using a typical monorepo setup, I think they should not be required.
@alexeigs I've created an example that might find useful https://github.com/0x80/mono-ts