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

feat(cli): allow bare specifier for builtin node module #20728

Merged
merged 25 commits into from
Oct 20, 2023

Conversation

kt3k
Copy link
Member

@kt3k kt3k commented Sep 28, 2023

This PR allows using bare specifiers for importing builtin node modules (ex. "fs" resolves to "node:fs"). When such resolution happens, the warnings like the below are shown.

Warning: Resolving "fs" as "node:fs" at file:///path/to/script.ts:1:16. If you want to use a built-in Node module, add a "node:" prefix.

This feature is implemented behind the unstable flag `--unstable-bare-node-builtins"

closes #20566

@kt3k kt3k requested review from ry and dsherret September 28, 2023 15:43
Copy link
Member

@bartlomieju bartlomieju left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will the warning be printed for every occurence of import "fs" or only the first one?

cli/resolver.rs Outdated
@@ -291,6 +295,12 @@ impl NpmResolver for CliGraphResolver {
}
}

fn on_resolve_bare_builtin_node_module(&self, module_name: &str) {
if !self.quiet {
eprintln!("Warning: Resolving \"{module_name}\" as \"node:{module_name}\". If you want to use a built-in Node module, add a \"node:\" prefix.")
Copy link
Member

@dsherret dsherret Sep 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can get rid of the quiet property and just use the log::warn! macro. The --quiet flag will automatically work with log::warn!

cli/resolver.rs Outdated Show resolved Hide resolved
@kt3k
Copy link
Member Author

kt3k commented Sep 30, 2023

Now I found a bug. When any import map is present, the new resolution doesn't seem working.. fixed in 91aaf73

@@ -1,4 +1,4 @@
error: Uncaught (in promise) TypeError: Relative import path "unmapped" not prefixed with / or ./ or ../ and not in import map from "file://[WILDCARD]/092_import_map_unmapped_bare_specifier.ts"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The last part of this error message was lost because of this commit (We now ignore ImportMapError::UnmappedBareSpecifier because that can't be handled by bare node specifier check implemented in deno_graph.

I drafted a PR to handle ImportMapError::UnmappedBareSpecifier in deno_graph, but I'm not sure it's worth the complexity

Copy link
Member

@ry ry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bartlomieju asked for a feature flag that would allow us to land this disabled in a patch release. I don't see that in this patch?

@dsherret
Copy link
Member

dsherret commented Oct 2, 2023

@ry maybe we can just land it without a feature flag in a patch? denoland/deno_graph#295 (comment)

@kt3k
Copy link
Member Author

kt3k commented Oct 4, 2023

Created an issue for feature flag system #20779

Let me check my understanding. Are we going to handle 3 inputs for checking whether the feature is enabled?

  • CLI flag --unstable-bare-node-specifier
  • Env var DENO_UNSTABLE=bare_node_specifier
  • features field of deno.json(c) "features": ["bare_node_specifier"]

@dsherret
Copy link
Member

dsherret commented Oct 4, 2023

Yup, that sounds good to me.

@bartlomieju
Copy link
Member

Created an issue for feature flag system #20779

Let me check my understanding. Are we going to handle 3 inputs for checking whether the feature is enabled?

  • CLI flag --unstable-bare-node-specifier
  • Env var DENO_UNSTABLE=bare_node_specifier
  • features field of deno.json(c) "features": ["bare_node_specifier"]

Just saw this comment. #20765 should unblock you for checking if the feature is enabled. I would suggest --unstable-bare-node-builtins.

@kt3k
Copy link
Member Author

kt3k commented Oct 4, 2023

--unstable-bare-node-builtins sounds good to me

@kt3k
Copy link
Member Author

kt3k commented Oct 5, 2023

This branch now reads the feature flag from 3 inputs: DENO_UNSTABLE_BARE_NODE_BUILTINS=1 env var, --unstable-bare-node-builtins flag, "unstable": ["bare-node-builtins"] field in deno.json. The LSP behavior can only be configured by unstable field of deno.json

@kt3k
Copy link
Member Author

kt3k commented Oct 6, 2023

I'd like to avoid implementing --no-bare-node-builtins flag in this PR because the feature is only enabled when explicitly enabled by the user. I think we should implement that flag when the feature is automatically enabled by some condition.

@bartlomieju
Copy link
Member

@kt3k you can now get an instance of FeatureChecker from CliFactory. Let me know if you need any help with this update.

@dsherret
Copy link
Member

dsherret commented Oct 12, 2023

I'm curious why this needs to use the feature checker. I feel like what's done here is fine since this is not an unstable runtime feature? What would the code look like?

cli/args/flags.rs Outdated Show resolved Hide resolved
cli/factory.rs Outdated Show resolved Hide resolved
@kt3k
Copy link
Member Author

kt3k commented Oct 13, 2023

I'm curious why this needs to use the feature checker.

Now feature_checker is moved to CliFactory in #20797, and it's ready when we create the resolver. So I think it makes sense to pass flag to feature_checker, and we can follow the same pattern for all unstable flags.

@kt3k
Copy link
Member Author

kt3k commented Oct 13, 2023

Now CliOption#unstable_bare_node_builtins includes all necessary checks for the feature flag. The flag is passed to FeatureChecker at the initialization of it. CliGraphResolver uses FeatureChecker#check_feature for the availability of the feature.

cli/args/mod.rs Outdated
@@ -1216,6 +1216,13 @@ impl CliOptions {
self.flags.unstable
}

pub fn unstable_bare_node_builtlins(&self) -> bool {
self.flags.unstable_bare_node_builtlins
|| self.maybe_config_file().as_ref().map_or(false, |c| {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I find map_or to be confusing to read because it reads backwards instead of left to right or top to bottom. I opened #18212 to remove them in the past.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, we prefer map().unwrap_or(). Ok. I'll update.

cli/factory.rs Outdated
@@ -563,6 +566,9 @@ impl CliFactory {
pub fn feature_checker(&self) -> &Arc<FeatureChecker> {
self.services.feature_checker.get_or_init(|| {
let mut checker = FeatureChecker::default();
if self.options.unstable_bare_node_builtlins() {
checker.enable_feature("bare-node-builtins");
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it makes sense to pass this to the feature checker unless the feature is being used with the runtime code. For example, in this case we could just call self.options.unstable_bare_node_builtins() above on line 380.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this is just an overhead. Updated

@kt3k
Copy link
Member Author

kt3k commented Oct 13, 2023

We currently support the following 3. Do these look fine? (Especially I'm unconfident about the casing of deno.json field syntax)

  • DENO_UNSTABLE_BARE_NODE_BUILTINS=1 (env)
  • --unstable-bare-node-builtins (cli arg)
  • "unstable": ["bare-node-builtins"] (deno.json field)
$ cat b.js
import path from "path"
console.log(path.resolve);
$ ./target/debug/deno run b.js                              
error: Relative import path "path" not prefixed with / or ./ or ../
If you want to use a built-in Node module, add a "node:" prefix (ex. "node:path").
    at file:///Users/kt3k/denoland/deno/b.js:1:18
$ ./target/debug/deno run --unstable-bare-node-builtins b.js
Warning: Resolving "path" as "node:path" at file:///Users/kt3k/denoland/deno/b.js:1:18. If you want to use a built-in Node module, add a "node:" prefix.
[Function: resolve]
$ DENO_UNSTABLE_NODE_BUILTINS=1 ./target/debug/deno run b.js 
Warning: Resolving "path" as "node:path" at file:///Users/kt3k/denoland/deno/b.js:1:18. If you want to use a built-in Node module, add a "node:" prefix.
[Function: resolve]
$ echo '{"unstable":["bare-node-builtins"]}' > deno.json
$ ./target/debug/deno run b.js                              
Warning: Resolving "path" as "node:path" at file:///Users/kt3k/denoland/deno/b.js:1:18. If you want to use a built-in Node module, add a "node:" prefix.
[Function: resolve]

@dsherret
Copy link
Member

@kt3k looks good to me!

@kt3k
Copy link
Member Author

kt3k commented Oct 17, 2023

@bartlomieju PTAL

Copy link
Member

@bartlomieju bartlomieju left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM too!

@kt3k kt3k merged commit fb73eb1 into denoland:main Oct 20, 2023
13 checks passed
@kt3k kt3k deleted the allow-bare-specifier-for-builtin-node-modules branch October 20, 2023 04:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow importing built-in node modules import "fs" with warning
4 participants