Open castarco opened 1 month ago
It should work if you use --no-config
and don't reference the package.json dependencies in the deno script.
The package is private ("private": true in package.json)
Sorry, I don't think it's a good idea to support typescript in any npm package (private or not) until node stabilizes the behaviour they're going to chose.
You can get around this behaviour by using the flag I mentioned in my previous comment.
@dsherret It's not really about "supporting TypeScript", but about letting "self-contained" scripts(1) be executed as they were intended, and only when they are exposed through the bin
entry in package.json
(2), as if they were any other binary (the other proposed constrains were there only to minimise potential problems).
deno
or node
, because they are in charge of specifying the interpreter via their fixed in their shebang.import
/ required
, and also never for "truly external" packages, only verifiably "local" ones.P.S.: Regarding your proposed solution, using --no-config
and no NPM dependencies, it works as you mentioned, but I still think it presents some problems:
deps.ts
file, or something along the lines, but it's still subpar)In case anyone wants to do something similar to what I describe here, there are other possible hacks to bypass Deno restrictions (although it has some caveats that I will enumerate at the end of this post):
In ./src/myscript.ts
:
#!/usr/bin/env -S deno run --node-modules-dir --unstable-byonm --allow-env --allow-read --allow-sys --allow-run
// --node-modules-dir: allows using modules declared in `package.json`'s `dependencies` field.
// --unstable-byonm: uses `node_modules` managed by other tools (npm, pnpm, ...)
import { $ } from 'zx'
// Do stuff
In the wrapper ./src/myscript.sh
file:
#!/bin/sh
# Compatibility notes:
# - This script tries to stick to POSIX shell, not depending on
# non-standard Bash features.
# - `realpath` is commonly available in Unix-like systems... but
# it wasn't always like that. In Macos it's supported since v13.
# POSIX shell boilerplate to fail early
set -eu;
unset CDPATH; # For safety
# Obtain the directory where the script is placed
SCRIPT_DIR="$( cd -- "$( dirname -- "$0" )" &> /dev/null && pwd )";
# Resolve the absolute directory path, removing symlinks.
SCRIPT_DIR="$(realpath "${SCRIPT_DIR}")";
# Now we can call the TypeScript script without problems:
# If the script is inside an NPM package that belongs to the same
# monorepo and has not been installed from a remote registry, then
# the absolute path won't contain the `node_modules` subpath, and
# Deno will allow us to execute TS scripts.
"${SCRIPT_DIR}/myscript.ts" $@;
In package.json
:
{
"name": "@coderspirit/internal-tools",
"private": true,
"type": "module",
"bin": {
"myscript": "./src/myscript.sh"
},
"dependencies": {
"zx": "^8.1.4"
}
}
Related issues
Problem description
package.json
file of said package:.js
file that in turn calls the.ts
file.Proposed solution
I am aware that there are other open issues that got closed because it is a very bad idea to allow people to pack TypeScript in NPM packages instead of distributing JS directly. I want to be clear that this is not what I'm asking for. I'll go into the details right now.
My first point would be to notice the fact that we are talking about a "binary", a script that it is intended to be executed "as is" (it even has its own shebang to tell the OS how to be executed). We are not talking about code distribution.
Now, my proposal is that, when all of the following conditions are met, Deno should allow the execution of TypeScript scripts even when they are exposed through NPM packages:
"private": true
inpackage.json
)package.json
's"bin"
field.We know that, if we decided to pack POSIX shell scripts in NPM packages, they would be executed without hesitation, even though they are not pure JavaScript. The same would happen if we decided to pack Python scripts. For consistency (and a better life for everyone) the same should apply to virtually any scripting language, including TypeScript.
I don't think that being in the same monorepo and being private are important requirements, but I introduced them here to minimise potential concerns, and because in any case... this is the most common use case.
Alternative Solution
I've been checking the source code to see where this error is raised, and although I still didn't invest enought time, I can see how much of the information I mentioned in the previous proposal could not be available at the time of deciding whether to accept or not that script execution.
A simpler alternative could be to pass a specific flag to
deno run
(in the shebang) that disables the check raising the error... but adding an extra check that verifies that there is a shebang in the executed flag, and raise an error if it's not there.This second check once we are at runtime would serve to ensure that people do not abuse the config flag for "normal code", and it is used only in "binaries".