DENO_DIR contains the following files and directories:
# DIRECTORIES
gen/: Cache for files compiled to JavaScript
deps/: Cache for remote url imported files
|__ http/: For http imports
|__ https/: For https imports
# FILES
deno_history.txt: History of Deno REPL
By default, DENO_DIR is located in $HOME/.deno. However, the user could also change its location by modifying the $DENO_DIR environment variable. Explicitly setting DENO_DIR is recommended in production.
gen/
$DENO_DIR/gen/ is used to store JavaScript files that are compiled from source TypeScript files. Such compilation is necessary since V8 does not recognize TypeScript syntax beyond the JS subset.
Each JS file inside of the gen/ folder has a filename that is the hash of its TypeScript source. It also comes with a source map ending with .map.
This cache exists to avoid repeated recompilation each run while the source file is not updated by the user. For example, suppose we have a file hello-world.ts which contains nothing but console.log("Hello world"). During the first run, we will see the message about compilation:
$ deno hello-world.ts
Compiling /Users/kevinqian/my-folder/hello-world.ts
Hello world
However, without changing the file, when you rerun the code:
$ deno hello-world.ts
Hello world
The compilation message is gone. This is because for this run, instead of compiling again, Deno is directly using the cached version in gen/.
The cache load and save code could be found in DenoDir::load_cache and DenoDir::code_cache, from src/deno_dir.rs.
To force Deno to recompile your TypeScript code instead of using the cached version, you could use the --recompile flag.
deps/
$DENO_DIR/deps is used to store files fetched through remote url import. It contains subfolders based on url scheme (currently only http and https), and store files to locations based on the URL path. For example, for the following import (notice that Deno requires the user to specify extensions explicitly):
Notice that unless the user run the code using --reload flag, http.ts in our case would NEVER be re-downloaded in future runs.
Currently (WARNING: MIGHT BE CHANGED IN THE FUTURE), Deno would keep an eye on the content MIME type of downloaded remote files. In the cases where a file is missing an extension, or having an extension that does not match the content type, Deno would create an extra file ended with .mime to store the MIME type as provided by HTTP response headers. Therefore, if we download a file named a.ts while having Content-Type: text/javascript in the response header, a file a.ts.mime would be created to its side, containing text/javascript. Due to the presence of this .mime file, a.ts would later be imported as if it is a JavaScript file.
Code Fetch Logic
Let's now look into how Deno resolves the code for an import.
Go to src/deno_dir.rs and find the following function:
src/deno_dir.rs
fnget_source_code( self:&Self, module_name:&str, filename:&str, ) ->DenoResult<CodeFetchOutput> {let is_module_remote =is_remote(module_name);// We try fetch local. Two cases:// 1. This is a remote module, but no reload provided// 2. This is a local moduleif!is_module_remote ||!self.reload {debug!("fetch local or reload {} is_module_remote {}", module_name, is_module_remote );match self.fetch_local_source(&module_name, &filename)? {Some(output) => {debug!("found local source ");returnOk(output); }None=> {debug!("fetch_local_source returned None"); } } }// If not remote file, stop here!if!is_module_remote {debug!("not remote file stop here");returnErr(DenoError::from(std::io::Error::new( std::io::ErrorKind::NotFound,format!("cannot find local file '{}'", filename), ))); }debug!("is remote but didn't find module");// not cached/local, try remotelet maybe_remote_source = self.fetch_remote_source(&module_name, &filename)?;ifletSome(output) = maybe_remote_source {returnOk(output); }returnErr(DenoError::from(std::io::Error::new( std::io::ErrorKind::NotFound,format!("cannot find remote file '{}'", filename), ))); }
module_name is a string representing the module to be loaded, created based on the paths of the path of the file to be imported, and the file that contains the import statement. Therefore, import "./b.ts" inside of the file imported by import "https://example.com/a.ts" would be treated as if it is import "https://example.com/b.ts".
fetch_local_source goes into the filesystem and try resolving the content based on the filename and its type: