When the entry script is under the subdirectory, reading the relative file under the subdirectory is unsuccessful.
In Node.js, you can get the directory where the script is located by __dirname.
And __file__ can also be used in Python
Hi, I am not sure if this is what you need.
import { cwd } from 'deno'
console.log(cwd())
Actually no, cwd is just the working directory...
Could be injected by TypeScript compiler
Hi, I am not sure if this is what you need.
import { cwd } from 'deno' console.log(cwd())
Unfortunately, cwd() does not achieve the same effect.
Assume you have the following files and directories:
~/demo/test/test.ts
~/demo/test/test.txt
When I execute deno test/test.ts under ~/demo,
cwd() in ~/demo/test/test.ts will output ~/demo, not ~/demo/test.
This is a common use, for example, when I use Deno to write some tool scripts
Sounds like injecting through TS compiler should work. There is also a pitfall that the actual running files are loaded from cache under DENO_PATH and thus different from the expected TS file path. Need to differentiate the two.
@kitsonk Does this look like a good place for injection? (on my phone so cannot really verify if it would work)
Sounds like injecting through TS compiler should work.
No, in my opinion. We are working on #975. When that lands, coupled with #1190 then in a lot of cases the TypeScript compiler won't get involved.
Rust "knows" where the original file is located, even if it is loading from the cache, but even then it is tricky when dealing with remote modules.
Basing code dealing with the relative location of the module that the code is running in is rather dangerous. It can also be super fragile, what if the module get moved around. Why would you want to "hard code" that into the logic of the module?
While it would be Ryan's call, I would personally want to try to avoid this at all costs unless there are problems that just can't be solved. Don't want to handle people a 👣 🔫 to author fragile code if we can avoid it.
All file creation/read/access APIs that are exposed would be relative to the cwd() anyways.
I think it would be nice if we could do
import { uint8Array } from "./style.css";
that is, statically resolving and including non-javascript files. Maybe that negates the need to have __dirname.
I'm not necessarily against __dirname (it's certainly useful) but I think it would be nice if we could avoid it. Let's add the above feature before doing __dirname. If we can avoid __dirname that means code is that much more context-independent - which is good for maintenance and reuse-ability .
I'm definitely not doing the two underscore thing again tho. We will use DIRNAME (or something)
@ry we would/could handle any media type in the compiler.
We already support .json and associated media types in the compiler. If we assume anything else is "text" ish... we would potentially just "compile" down to something like this:
export function toUint8Array(): Uint8Array {
return deno.getUint8Array("./style.css");
}
export function toString(): string {
return (new TextDecoder()).decode(deno.getUint8Array("./style.css"));
}
I think we would have to generate that "shell" module which would be loaded in the runtime which will op back out to Rust to get the resource. Rust would use the module resolution logic, which would negate the need for the module to know where it sits. Doing some sort of "getter" as an export of a module is awkward since export = is not an ESM construct. So it does mean that you would have to do something like this:
import * as styleCss from "./style.css";
const value = styleCss.toUint8Array();
Isn't this what import.meta.url was intended for?
@janpot thanks - I didn’t know about that
@Janpot I think we might need to tweak the tsconfig options for this to work as intended:
1:13 - error TS1343: The 'import.
meta' meta-property is only allowed using 'ESNext' for the 'target' and
'module' compiler options.
1 console.log(import.meta);
@Smith this would be resolved when we move to native ESM which is soon. #975
__dirname doesn't work in node.js either when you are using ES Modules. Here's how you get around it in node.js :
import path from 'path';
const __dirname = path.dirname(new URL(import.meta.url).pathname);
After this, I could use __dirname in the node script, but eslint couldn't parse any use of the import.meta object, because eslint doesn't support stage 3 proposals:
https://stackoverflow.com/questions/54337576/eslint-import-meta-causes-fatal-parsing-error
You can now retrieve URL of script with import.meta.url
Hesitated to write here this but all my searches led me to this thread.
What about finding the _directory_ of the current script then? That is what I want most of the time.
The import.meta.url gives a file:///... to the file itself (of course), and I haven't found very ergonomic ways to use it to then carry out what path.join(___dirname, "static-files") used to do.
@npup import.meta doesn't work well on win10, maybe this is a bug.
ref: https://github.com/denoland/deno/issues/4647
@npup There's the path module which you could use.
@SyrupThinker path.join(import.meta.url, "path") cannot be used directly on Win10
@npup new URL("static-files", import.meta.url).pathname.
That one looks cool, thanks!
/p
On 20 April 2020 17:06:45 Nayeem Rahman notifications@github.com wrote:
>
@npup new URL("static-files", import.meta.url).pathname.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
@nayeemrmn that gives a path that looks like "/C:/Users/seishun/project/static-files", which Deno.readFileSync doesn't accept.
Here's a hacky but cross-platform way:
import { createRequire } from "https://deno.land/std/node/module.ts";
const require = createRequire(import.meta.url);
console.log(require.resolve("./static-file"));
@seishun new URL("static-files", import.meta.url).pathname.slice(Deno.build.os == "win") 🤷♂️
@nayeemrmn ...slice(Deno.build.os == "win") isn't typed correctly. I suppose the false case should evaluate numerically to 0. Is the true case 1?
related to my above comment: https://github.com/denoland/deno/issues/4915
@zhmushan @seishun Update! As of Deno 1.1.0, thanks to @actual-size's work in #5990, FS functions support file URLs so you can do the following:
console.log(Deno.statSync(import.meta.url)); // FileInfo { ... }
console.log([...Deno.readDirSync(new URL("static-files", import.meta.url))]); // [ ... ]
Thanks for your mention, this is very useful for me!
From my testing, it seems like import.meta.url does not work as expected when bundling. It will instead reference the original file that was bundled. I could create a bug if this is not intended. If intended, then I'd be looking for another option to make my script portable so that it can use a directory relative to the location of it.
@han-tyumi there is already an issue for that: #6344
Most helpful comment
I think it would be nice if we could do
that is, statically resolving and including non-javascript files. Maybe that negates the need to have
__dirname.I'm not necessarily against
__dirname(it's certainly useful) but I think it would be nice if we could avoid it. Let's add the above feature before doing__dirname. If we can avoid__dirnamethat means code is that much more context-independent - which is good for maintenance and reuse-ability .I'm definitely not doing the two underscore thing again tho. We will use
DIRNAME(or something)