Repository: biomejs/biome (language: rust)

Issue:
💅 useStrictMode mangles leading comments and shebangs in .cjs files
### Environment information

```bash
CLI:
  Version:                      1.9.4
  Color support:                true

Platform:
  CPU Architecture:             aarch64
  OS:                           macos

Environment:
  BIOME_LOG_PATH:               unset
  BIOME_LOG_PREFIX_NAME:        unset
  BIOME_CONFIG_PATH:            unset
  NO_COLOR:                     unset
  TERM:                         "xterm-256color"
  JS_RUNTIME_VERSION:           "v22.12.0"
  JS_RUNTIME_NAME:              "node"
  NODE_PACKAGE_MANAGER:         "yarn/1.22.22"

Biome Configuration:
  Status:                       Loaded successfully
  Formatter disabled:           false
  Linter disabled:              false
  Organize imports disabled:    true
  VCS disabled:                 false

Linter:
  JavaScript enabled:           true
  JSON enabled:                 true
  CSS enabled:                  true
  GraphQL enabled:              false
  Recommended:                  true
  All:                          false
  Enabled rules:
  suspicious/noCatchAssign
  suspicious/noUnsafeNegation
  suspicious/useNamespaceKeyword
  a11y/useValidLang
  complexity/noUselessEmptyExport
  complexity/noMultipleSpacesInRegularExpressionLiterals
  suspicious/useValidTypeof
  a11y/useValidAriaRole
  correctness/noConstantCondition
  a11y/useAriaActivedescendantWithTabindex
  suspicious/noDuplicateParameters
  suspicious/noDuplicateSelectorsKeyframeBlock
  complexity/noEmptyTypeParameters
  correctness/noConstructorReturn
  style/useSelfClosingElements
  correctness/noUnknownProperty
  style/useTemplate
  correctness/noUnusedLabels
  complexity/noUselessTernary
  correctness/noUnreachableSuper
  suspicious/noCompareNegZero
  correctness/noSwitchDeclarations
  correctness/noUnsafeOptionalChaining
  correctness/noConstAssign
  suspicious/noControlCharactersInRegex
  complexity/noUselessTypeConstraint
  style/noVar
  suspicious/noDoubleEquals
  suspicious/noRedundantUseStrict
  style/useLiteralEnumMembers
  suspicious/noGlobalIsNan
  suspicious/noEmptyInterface
  suspicious/noMisleadingCharacterClass
  correctness/noPrecisionLoss
  suspicious/noRedeclare
  correctness/noStringCaseMismatch
  correctness/noSetterReturn
  correctness/noInvalidConstructorSuper
  suspicious/noDuplicateObjectKeys
  suspicious/noUnsafeDeclarationMerging
  correctness/noUnreachable
  complexity/noUselessThisAlias
  complexity/noThisInStatic
  correctness/noInnerDeclarations
  suspicious/noDuplicateCase
  style/noParameterAssign
  a11y/useValidAnchor
  correctness/noSelfAssign
  correctness/noInvalidBuiltinInstantiation
  style/useShorthandFunctionType
  suspicious/noShadowRestrictedNames
  correctness/noInvalidDirectionInLinearGradient
  suspicious/noImportantInKeyframe
  complexity/noUselessLabel
  complexity/noUselessCatch
  correctness/noUnsafeFinally
  a11y/useAriaPropsForRole
  correctness/noNonoctalDecimalEscape
  style/useEnumInitializers
  a11y/useHtmlLang
  complexity/noStaticOnlyClass
  style/useWhile
  style/noInferrableTypes
  style/useNumericLiterals
  complexity/useSimpleNumberKeys
  suspicious/noImportAssign
  a11y/noInteractiveElementToNoninteractiveRole
  suspicious/noLabelVar
  correctness/noUnnecessaryContinue
  suspicious/noApproximativeNumericConstant
  correctness/noGlobalObjectCalls
  a11y/useAltText
  correctness/noEmptyCharacterClassInRegex
  correctness/noUnknownUnit
  suspicious/noSparseArray
  a11y/useIframeTitle
  suspicious/noPrototypeBuiltins
  correctness/noVoidElementsWithChildren
  suspicious/noSuspiciousSemicolonInJsx
  style/useAsConstAssertion
  suspicious/noDebugger
  style/useExportType
  complexity/noUselessLoneBlockStatements
  style/noArguments
  a11y/useValidAriaValues
  suspicious/noGlobalAssign
  suspicious/noCommentText
  correctness/noUnmatchableAnbSelector
  suspicious/noMisleadingInstantiator
  suspicious/noThenProperty
  suspicious/noDuplicateJsxProps
  suspicious/useGetterReturn
  a11y/noPositiveTabindex
  correctness/noEmptyPattern
  security/noDangerouslySetInnerHtmlWithChildren
  suspicious/noExtraNonNullAssertion
  suspicious/noShorthandPropertyOverrides
  correctness/noRenderReturnValue
  security/noGlobalEval
  style/useConst
  a11y/noRedundantRoles
  complexity/useFlatMap
  correctness/useIsNan
  suspicious/noGlobalIsFinite
  suspicious/noSelfCompare
  suspicious/noAsyncPromiseExecutor
  suspicious/noDuplicateFontNames
  style/useNodejsImportProtocol
  a11y/noDistractingElements
  complexity/noWith
  nursery/useStrictMode
  complexity/noExtraBooleanCast
  suspicious/noDuplicateClassMembers
  a11y/useValidAriaProps
  a11y/noRedundantAlt
  correctness/noChildrenProp
  correctness/noUnknownFunction
  correctness/noInvalidPositionAtImportRule
  suspicious/noConfusingLabels
  suspicious/noConfusingVoidType
  suspicious/noFocusedTests
  a11y/noAriaUnsupportedElements
  correctness/noInvalidGridAreas
  correctness/noFlatMapIdentity
  a11y/noBlankTarget
  a11y/useHeadingContent
  correctness/useValidForDirection
  correctness/noVoidTypeReturn
  correctness/noInvalidUseBeforeDeclaration
  a11y/noAriaHiddenOnFocusable
  a11y/useGenericFontNames
  a11y/useAnchorContent
  complexity/noUselessRename
  complexity/noUselessConstructor
  a11y/noAccessKey
  style/useExponentiationOperator
  nursery/useAriaPropsSupportedByRole
  suspicious/noExportsInTest
  a11y/noNoninteractiveElementToInteractiveRole
  style/noCommaOperator
  suspicious/noDuplicateAtImportRules
  suspicious/useIsArray
  a11y/noHeaderScope
  complexity/noUselessFragments
  suspicious/noMisrefactoredShorthandAssign
  suspicious/noEmptyBlock
  suspicious/noClassAssign
  suspicious/noFunctionAssign

Workspace:
  Open Documents:               0
```


### Rule name

useStrictMode

### Playground link

https://biomejs.dev/playground/?lintRules=all&files.main.cjs=LwAvACAAYwBvAG0AbQBlAG4AdAA%3D

### Expected result

When the input file has extension .cjs, and does not have a "use strict" directive, and the first line of the file is a comment or a shebang, it will apply an incorrect fix.

With leading comments -

Input file:
```js
// leading comment
```

After applying fix:
```js
// leading comment
"use strict"; // leading comment
```

With shebang -

Input file:
```js
#!/usr/bin/env node
```

After applying fix:
```js
#!/usr/bin/env node"use strict";
```

### Code of Conduct

- [X] I agree to follow Biome's Code of Conduct


Discussion / hints:
@ematipico i’d like to work on this issue, could you please assign it to me? :D

Fix patch:
diff --git a/.changeset/fix_the_use_strict_directive_insertion_logic_for_shebang_and_top_leading_comments.md b/.changeset/fix_the_use_strict_directive_insertion_logic_for_shebang_and_top_leading_comments.md
new file mode 100644
index 000000000000..e1e55c47df8c
--- /dev/null
+++ b/.changeset/fix_the_use_strict_directive_insertion_logic_for_shebang_and_top_leading_comments.md
@@ -0,0 +1,47 @@
+---
+biome_js_analyze: patch
+---
+
+# Fix [#4841](https://github.com/biomejs/biome/issues/4841), shebang and top leading comments in cjs files are now handled correctly
+
+- shebang only (keep it as is)
+
+```
+#!/usr/bin/env node
+```
+
+- comments only (keep it as is)
+
+```
+// comment
+```
+
+- with shebang
+
+```diff
+- #!/usr/bin/env node"use strict";
++ #!/usr/bin/env node
++ "use strict";
+let some_variable = "some value";
+```
+
+- with comment
+
+```diff
+- // comment
+- "use strict"; // comment
++ "use strict";
++ // comment
+let some_variable = "some value";
+```
+
+- with shebang and comment
+
+```diff
+- #!/usr/bin/env node"use strict";
+- // comment
++ #!/usr/bin/env node
++ "use strict";
++ // comment
+let some_variable = "some value";
+```
diff --git a/crates/biome_js_analyze/src/lint/nursery/use_strict_mode.rs b/crates/biome_js_analyze/src/lint/nursery/use_strict_mode.rs
index 9287f31c8e71..01a146e4f127 100644
--- a/crates/biome_js_analyze/src/lint/nursery/use_strict_mode.rs
+++ b/crates/biome_js_analyze/src/lint/nursery/use_strict_mode.rs
@@ -5,9 +5,9 @@ use biome_analyze::{
 };
 use biome_console::markup;
 use biome_diagnostics::Severity;
-use biome_js_factory::make;
+use biome_js_factory::make::{js_directive, js_directive_list, token};
 use biome_js_syntax::{JsScript, JsSyntaxKind, JsSyntaxToken, T};
-use biome_rowan::{AstNode, AstNodeList, BatchMutationExt};
+use biome_rowan::{AstNode, AstNodeList, BatchMutationExt, TriviaPieceKind};
 
 declare_lint_rule! {
     /// Enforce the use of the directive `"use strict"` in script files.
@@ -53,16 +53,20 @@ impl Rule for UseStrictMode {
 
     fn run(ctx: &RuleContext<Self>) -> Self::Signals {
         let node = ctx.query();
-        if node
-            .directives()
-            .iter()
-            .filter_map(|directive| directive.inner_string_text().ok())
-            .all(|directive| directive.text() != "use strict")
-        {
-            Some(())
-        } else {
-            None
+
+        if node.directives().is_empty() && node.statements().is_empty() {
+            return None;
+        }
+
+        if node.directives().iter().any(|directive| {
+            directive
+                .inner_string_text()
+                .map_or(false, |text| text.text() == "use strict")
+        }) {
+            return None;
         }
+
+        Some(())
     }
 
     fn diagnostic(ctx: &RuleContext<Self>, _state: &Self::State) -> Option<RuleDiagnostic> {
@@ -79,7 +83,7 @@ impl Rule for UseStrictMode {
                 "Strict mode allows to opt-in some optimisations of the runtime engines, and it eliminates some JavaScript silent errors by changing them to throw errors."
             })
             .note(markup!{
-                "Check the "<Hyperlink href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode">"for more information regarding strict mode."</Hyperlink>
+                "Check the "<Hyperlink href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode">"MDN web docs"</Hyperlink>" for more information regarding strict mode."
             }),
         )
     }
@@ -91,22 +95,62 @@ impl Rule for UseStrictMode {
             PreferredQuote::Double => "\"use strict\"",
             PreferredQuote::Single => "'use strict'",
         };
-        let value = JsSyntaxToken::new_detached(JsSyntaxKind::JSX_STRING_LITERAL, value, [], []);
-        let use_strict_diretcive = make::js_directive(value)
-            .with_semicolon_token(make::token(T![;]))
-            .build();
-        let directives = make::js_directive_list(
+
+        // check if the first statement has a newline as the first trivia.
+        let is_statement_first_trivia_newline = node
+            .statements()
+            .syntax()
+            .first_leading_trivia()
+            .is_some_and(|f| {
+                f.pieces()
+                    .next()
+                    .is_some_and(|piece| piece.kind() == TriviaPieceKind::Newline)
+            });
+
+        let mut leading_trivia = Vec::new();
+        let mut trailing_trivia = Vec::new();
+
+        // if the script has directives or an interpreter directive, add a newline before the "use strict" directive.
+        if !node.directives().is_empty() || node.interpreter_token().is_some() {
+            leading_trivia.push((TriviaPieceKind::Newline, "\n"));
+        }
+
+        // if the script has statements and the first statement does not have a newline before it, add a newline behind the "use strict" directive.
+        if !node.statements().is_empty() && !is_statement_first_trivia_newline {
+            trailing_trivia.push((TriviaPieceKind::Newline, "\n"));
+        }
+
+        let mut strict_directive_token =
+            JsSyntaxToken::new_detached(JsSyntaxKind::JSX_STRING_LITERAL, value, [], []);
+
+        if !leading_trivia.is_empty() {
+            strict_directive_token = strict_directive_token.with_leading_trivia(leading_trivia);
+        }
+
+        let mut strict_directive = js_directive(strict_directive_token);
+
+        if !trailing_trivia.is_empty() {
+            strict_directive = strict_directive
+                .with_semicolon_token(token(T![;]).with_trailing_trivia(trailing_trivia))
+        } else {
+            strict_directive = strict_directive.with_semicolon_token(token(T![;]));
+        };
+
+        let directives = js_directive_list(
             node.directives()
                 .into_iter()
-                .chain([use_strict_diretcive])
+                .chain([strict_directive.build()])
                 .collect::<Vec<_>>(),
         );
+
         let new_node = node.clone().with_directives(directives);
-        mutation.replace_node(node, new_node);
+
+        // use replace_element_discard_trivia to prevent duplication of the leading comment when it is the first element in the node's leading trivia.
+        mutation.replace_element_discard_trivia(node.into(), new_node.into());
         Some(JsRuleAction::new(
             ctx.metadata().action_category(ctx.category(), ctx.group()),
             ctx.metadata().applicability(),
-            markup!("Insert a top level"<Emphasis>"\"use strict\" "</Emphasis>".").to_owned(),
+            markup!("Insert a top level "<Emphasis>"\"use strict\""</Emphasis>".").to_owned(),
             mutation,
         ))
     }


Test patch:
diff --git a/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-comments.cjs b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-comments.cjs
new file mode 100644
index 000000000000..a664f0ba7515
--- /dev/null
+++ b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-comments.cjs
@@ -0,0 +1,2 @@
+// comment
+let some_variable = "some value";
diff --git a/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-comments.cjs.snap b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-comments.cjs.snap
new file mode 100644
index 000000000000..76dc7be1035d
--- /dev/null
+++ b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-comments.cjs.snap
@@ -0,0 +1,34 @@
+---
+source: crates/biome_js_analyze/tests/spec_tests.rs
+expression: invalid-with-comments.cjs
+---
+# Input
+```cjs
+// comment
+let some_variable = "some value";
+
+```
+
+# Diagnostics
+```
+invalid-with-comments.cjs:2:1 lint/nursery/useStrictMode  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+  ! Unexpected absence of the directive "use strict".
+  
+    1 │ // comment
+  > 2 │ let some_variable = "some value";
+      │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+    3 │ 
+  
+  i Strict mode allows to opt-in some optimisations of the runtime engines, and it eliminates some JavaScript silent errors by changing them to throw errors.
+  
+  i Check the MDN web docs for more information regarding strict mode.
+  
+  i Safe fix: Insert a top level "use strict".
+  
+      1 │ + "use·strict";
+    1 2 │   // comment
+    2 3 │   let some_variable = "some value";
+  
+
+```
diff --git a/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-directive.cjs.snap b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-directive.cjs.snap
index 53e53cf703db..a41a6bfbd942 100644
--- a/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-directive.cjs.snap
+++ b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-directive.cjs.snap
@@ -20,11 +20,13 @@ invalid-with-directive.cjs:1:1 lint/nursery/useStrictMode  FIXABLE  ━━━━
   
   i Strict mode allows to opt-in some optimisations of the runtime engines, and it eliminates some JavaScript silent errors by changing them to throw errors.
   
-  i Check the for more information regarding strict mode.
+  i Check the MDN web docs for more information regarding strict mode.
   
-  i Safe fix: Insert a top level"use strict" .
+  i Safe fix: Insert a top level "use strict".
+  
+    1 1 │   "use server";
+      2 │ + "use·strict";
+    2 3 │   
   
-    1 │ "use·server";"use·strict";
-      │              +++++++++++++
 
 ```
diff --git a/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-shebang-comments.cjs b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-shebang-comments.cjs
new file mode 100644
index 000000000000..b0ca3f989253
--- /dev/null
+++ b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-shebang-comments.cjs
@@ -0,0 +1,3 @@
+#!/usr/bin/env node
+// comment
+let some_variable = "some value";
diff --git a/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-shebang-comments.cjs.snap b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-shebang-comments.cjs.snap
new file mode 100644
index 000000000000..f81166fa89b5
--- /dev/null
+++ b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-shebang-comments.cjs.snap
@@ -0,0 +1,38 @@
+---
+source: crates/biome_js_analyze/tests/spec_tests.rs
+expression: invalid-with-shebang-comments.cjs
+---
+# Input
+```cjs
+#!/usr/bin/env node
+// comment
+let some_variable = "some value";
+
+```
+
+# Diagnostics
+```
+invalid-with-shebang-comments.cjs:1:1 lint/nursery/useStrictMode  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━
+
+  ! Unexpected absence of the directive "use strict".
+  
+  > 1 │ #!/usr/bin/env node
+      │ ^^^^^^^^^^^^^^^^^^^
+  > 2 │ // comment
+  > 3 │ let some_variable = "some value";
+      │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+    4 │ 
+  
+  i Strict mode allows to opt-in some optimisations of the runtime engines, and it eliminates some JavaScript silent errors by changing them to throw errors.
+  
+  i Check the MDN web docs for more information regarding strict mode.
+  
+  i Safe fix: Insert a top level "use strict".
+  
+    1 1 │   #!/usr/bin/env node
+      2 │ + "use·strict";
+    2 3 │   // comment
+    3 4 │   let some_variable = "some value";
+  
+
+```
diff --git a/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-shebang.cjs b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-shebang.cjs
new file mode 100644
index 000000000000..9b28167729c0
--- /dev/null
+++ b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-shebang.cjs
@@ -0,0 +1,2 @@
+#!/usr/bin/env node
+let some_variable = "some value";
diff --git a/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-shebang.cjs.snap b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-shebang.cjs.snap
new file mode 100644
index 000000000000..ad38cb947297
--- /dev/null
+++ b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid-with-shebang.cjs.snap
@@ -0,0 +1,36 @@
+---
+source: crates/biome_js_analyze/tests/spec_tests.rs
+expression: invalid-with-shebang.cjs
+---
+# Input
+```cjs
+#!/usr/bin/env node
+let some_variable = "some value";
+
+```
+
+# Diagnostics
+```
+invalid-with-shebang.cjs:1:1 lint/nursery/useStrictMode  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+  ! Unexpected absence of the directive "use strict".
+  
+  > 1 │ #!/usr/bin/env node
+      │ ^^^^^^^^^^^^^^^^^^^
+  > 2 │ let some_variable = "some value";
+      │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+    3 │ 
+  
+  i Strict mode allows to opt-in some optimisations of the runtime engines, and it eliminates some JavaScript silent errors by changing them to throw errors.
+  
+  i Check the MDN web docs for more information regarding strict mode.
+  
+  i Safe fix: Insert a top level "use strict".
+  
+    1 1 │   #!/usr/bin/env node
+      2 │ + "use·strict";
+    2 3 │   let some_variable = "some value";
+    3 4 │   
+  
+
+```
diff --git a/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid.js.snap b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid.js.snap
index f33c7b2ecbc0..cde0e09d92d3 100644
--- a/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid.js.snap
+++ b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/invalid.js.snap
@@ -1,7 +1,6 @@
 ---
 source: crates/biome_js_analyze/tests/spec_tests.rs
 expression: invalid.js
-snapshot_kind: text
 ---
 # Input
 ```cjs
@@ -28,16 +27,11 @@ invalid.js:3:1 lint/nursery/useStrictMode  FIXABLE  ━━━━━━━━━
   
   i Strict mode allows to opt-in some optimisations of the runtime engines, and it eliminates some JavaScript silent errors by changing them to throw errors.
   
-  i Check the for more information regarding strict mode.
+  i Check the MDN web docs for more information regarding strict mode.
   
-  i Safe fix: Insert a top level"use strict" .
-  
-    1 1 │   
-    2 2 │   
-      3 │ + "use·strict";
-      4 │ + 
-    3 5 │   function f() {
-    4 6 │   	return "lorem ipsum"
+  i Safe fix: Insert a top level "use strict".
   
+    1 │ "use·strict";
+      │ +++++++++++++
 
 ```
diff --git a/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-comments.cjs b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-comments.cjs
new file mode 100644
index 000000000000..3be40bde38ba
--- /dev/null
+++ b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-comments.cjs
@@ -0,0 +1,3 @@
+
+
+// comment
diff --git a/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-comments.cjs.snap b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-comments.cjs.snap
new file mode 100644
index 000000000000..d41b7821db11
--- /dev/null
+++ b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-comments.cjs.snap
@@ -0,0 +1,11 @@
+---
+source: crates/biome_js_analyze/tests/spec_tests.rs
+expression: valid-with-comments.cjs
+---
+# Input
+```cjs
+
+
+// comment
+
+```
diff --git a/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-shebang-comments.cjs b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-shebang-comments.cjs
new file mode 100644
index 000000000000..2d3a21af2a32
--- /dev/null
+++ b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-shebang-comments.cjs
@@ -0,0 +1,3 @@
+#!/usr/bin/env node
+
+// comment
diff --git a/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-shebang-comments.cjs.snap b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-shebang-comments.cjs.snap
new file mode 100644
index 000000000000..a4e53ef1adcb
--- /dev/null
+++ b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-shebang-comments.cjs.snap
@@ -0,0 +1,11 @@
+---
+source: crates/biome_js_analyze/tests/spec_tests.rs
+expression: valid-with-shebang-comments.cjs
+---
+# Input
+```cjs
+#!/usr/bin/env node
+
+// comment
+
+```
diff --git a/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-shebang.cjs b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-shebang.cjs
new file mode 100644
index 000000000000..908ba8417a00
--- /dev/null
+++ b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-shebang.cjs
@@ -0,0 +1,1 @@
+#!/usr/bin/env node
diff --git a/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-shebang.cjs.snap b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-shebang.cjs.snap
new file mode 100644
index 000000000000..cae82ef2131b
--- /dev/null
+++ b/crates/biome_js_analyze/tests/specs/nursery/useStrictMode/valid-with-shebang.cjs.snap
@@ -0,0 +1,9 @@
+---
+source: crates/biome_js_analyze/tests/spec_tests.rs
+expression: valid-with-shebang.cjs
+---
+# Input
+```cjs
+#!/usr/bin/env node
+
+```