Skip to content

Linter reports false positives for ES module imports of Three.js via importmap and type="module" #931

@gongfan99

Description

@gongfan99

Describe the bug

The linter in packages/core/src/lint/rules/adapters.ts incorrectly reports false a positive error when Three.js is loaded using modern ES module patterns. Specifically:

missing_three_script rule: Claims Three.js is not loaded when it's properly imported via ES modules

Both the missing_lottie_script and missing_three_script rules only check for Three.js loaded via external <script src> tags, missing valid module-based import patterns.

Sorry, I should have raised this issue in #929

Link to reproduction

see the steps below

Steps to reproduce

  1. Create a minimal hyperframes project with an index.html file containing:
<!doctype html>
<html lang="en">
  <body>
    <div
      id="takeshape-ad"
      data-composition-id="takeshape-ad"
      data-start="0"
      data-duration="58"
      data-width="1920"
      data-height="1080"
    ></div>
    <script type="importmap">
      {
        "imports": {
          "three": "https://cdn.jsdelivr.net/npm/three@0.182.0/build/three.module.js",
          "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.182.0/examples/jsm/"
        }
      }
    </script>
    <script type="module">
      import * as THREE from "three";
      var threeScene = new THREE.Scene();
    </script>
    <script>
      window.__timelines = window.__timelines || {};
    </script>
  </body>
</html>
  1. Run npx hyperframes lint

Expected behavior

The linter should pass without errors. The code is valid:

  • Three.js is properly available through the ES module import chain
  • The type="importmap" and type="module" scripts are standard web platform APIs
  • Three.js will be loaded and available at runtime

Actual behavior

The linter reports the false positive error:

✗ missing_three_script: Composition uses Three.js but no Three.js script is loaded. The 3D scene will not render.

Environment

✓ Version          0.6.20 (latest)
✓ Node.js          v24.15.0 (win32 x64)
✓ CPU              8 cores · 12th Gen Intel(R) Core(TM) i3-1215U @ 2496MHz
✓ Memory           23.7 GB total · 10.3 GB free
✓ Disk             421.0 GB free
✓ Environment      Native terminal
✓ FFmpeg           D:\\ffmpeg-8.1-essentials_build\\bin\\ffmpeg.exe
✓ FFprobe          ffprobe version 8.1-essentials_build
✓ Chrome           cache: C:\\Users\\username\\.cache\\hyperframes\\chrome\\chrome-headless-shell\\win64-131.0.6778.85
✓ Docker           Docker version 28.3.2, build 578ccf6
✗ Docker running   Not running

Additional context

The root causes are in packages/core/src/lint/rules/adapters.ts:

  1. missing_three_script rule in adapters.ts: Only checks for Three.js in script src attributes
    const allScriptSrcs = scripts
      .map((s) => readAttr(`<script ${s.attrs}>`, "src") || "")
      .filter(Boolean);
    const hasThreeScript = allScriptSrcs.some((src) => /three/i.test(src));
    • Fix: Also detect:
      • Valid importmap entries that define "three" or "three/addons/"
      • import statements in type="module" scripts that import from "three"

ES modules and importmaps are standard web platform features supported by all modern browsers. The linter should recognize these valid patterns to prevent false positives for developers using modern JavaScript practices.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions