1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

feat(lint): Add lint for usage of node globals (with autofix) (#25048)

From upgrading `deno_lint`.

Previously if you had a node project that used a bunch of node globals
(`process.env`, etc), you would have to fix the errors by hand. This PR
includes a new lint that detects usages of node globals (`process`,
`setImmediate`, `Buffer`, etc.) and provides an autofix to import the
correct value. For instance:

```ts
// main.ts
const _foo = process.env.FOO;
```

`deno lint` gives you

```ts
error[no-node-globals]: NodeJS globals are not available in Deno
 --> /home/foo.ts:1:14
  |
1 | const _foo = process.env.FOO;
  |              ^^^^^^^
  = hint: Add `import process from "node:process";`

  docs: https://lint.deno.land/rules/no-node-globals


Found 1 problem (1 fixable via --fix)
Checked 1 file
```
And `deno lint --fix` adds the import for you:

```ts
// main.ts
import process from "node:process";
const _foo = process.env.FOO;
```
This commit is contained in:
Nathan Whitaker 2024-08-15 13:43:04 -07:00 committed by GitHub
parent e8d57cd3fe
commit 5ec3c5c3a4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 72 additions and 5 deletions

5
Cargo.lock generated
View file

@ -1703,9 +1703,9 @@ dependencies = [
[[package]] [[package]]
name = "deno_lint" name = "deno_lint"
version = "0.62.0" version = "0.63.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69bb0887acec1830cac1a325ebe5cec96fdc41f61ee50e7b25447741007757b6" checksum = "e0e6cc8fcb4819dd5e12d640d6fc455217c66bda00e30fd6d46d2844e3e1bdcf"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"deno_ast", "deno_ast",
@ -1713,6 +1713,7 @@ dependencies = [
"if_chain", "if_chain",
"log", "log",
"once_cell", "once_cell",
"phf 0.11.2",
"regex", "regex",
"serde", "serde",
"serde_json", "serde_json",

View file

@ -70,7 +70,7 @@ deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"]
deno_doc = { version = "0.146.0", features = ["html", "syntect"] } deno_doc = { version = "0.146.0", features = ["html", "syntect"] }
deno_emit = "=0.44.0" deno_emit = "=0.44.0"
deno_graph = { version = "=0.81.2" } deno_graph = { version = "=0.81.2" }
deno_lint = { version = "=0.62.0", features = ["docs"] } deno_lint = { version = "=0.63.1", features = ["docs"] }
deno_lockfile.workspace = true deno_lockfile.workspace = true
deno_npm = "=0.21.4" deno_npm = "=0.21.4"
deno_package_json.workspace = true deno_package_json.workspace = true

View file

@ -1,5 +1,6 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use std::collections::HashSet;
use std::path::Path; use std::path::Path;
use deno_ast::MediaType; use deno_ast::MediaType;
@ -225,14 +226,23 @@ fn apply_lint_fixes(
if quick_fixes.is_empty() { if quick_fixes.is_empty() {
return None; return None;
} }
let mut import_fixes = HashSet::new();
// remove any overlapping text changes, we'll circle // remove any overlapping text changes, we'll circle
// back for another pass to fix the remaining // back for another pass to fix the remaining
quick_fixes.sort_by_key(|change| change.range.start); quick_fixes.sort_by_key(|change| change.range.start);
for i in (1..quick_fixes.len()).rev() { for i in (1..quick_fixes.len()).rev() {
let cur = &quick_fixes[i]; let cur = &quick_fixes[i];
let previous = &quick_fixes[i - 1]; let previous = &quick_fixes[i - 1];
let is_overlapping = cur.range.start < previous.range.end; // hack: deduplicate import fixes to avoid creating errors
if is_overlapping { if previous.new_text.trim_start().starts_with("import ") {
import_fixes.insert(previous.new_text.trim().to_string());
}
let is_overlapping = cur.range.start <= previous.range.end;
if is_overlapping
|| (cur.new_text.trim_start().starts_with("import ")
&& import_fixes.contains(cur.new_text.trim()))
{
quick_fixes.remove(i); quick_fixes.remove(i);
} }
} }

View file

@ -0,0 +1,23 @@
{
"tempDir": true,
"steps": [
{
"args": "run main.ts",
"output": "error.out",
"exitCode": 1
},
{
"args": "lint main.ts",
"output": "lint.out",
"exitCode": 1
},
{
"args": "lint --fix main.ts",
"output": "Checked 1 file\n"
},
{
"args": "run --allow-env main.ts",
"output": ""
}
]
}

View file

@ -0,0 +1,4 @@
error: Uncaught (in promise) ReferenceError: process is not defined
const _foo = process.env.FOO;
^
at [WILDCARD]main.ts:3:14

View file

@ -0,0 +1,22 @@
error[no-node-globals]: NodeJS globals are not available in Deno
--> [WILDCARD]main.ts:3:14
|
3 | const _foo = process.env.FOO;
| ^^^^^^^
= hint: Add `import process from "node:process";`
docs: https://lint.deno.land/rules/no-node-globals
error[no-node-globals]: NodeJS globals are not available in Deno
--> [WILDCARD]main.ts:7:14
|
7 | const _bar = process.env.BAR;
| ^^^^^^^
= hint: Add `import process from "node:process";`
docs: https://lint.deno.land/rules/no-node-globals
Found 2 problems (2 fixable via --fix)
Checked 1 file

View file

@ -0,0 +1,7 @@
import {} from "node:console";
const _foo = process.env.FOO;
import {} from "node:assert";
const _bar = process.env.BAR;