Skip to content

Conversation

@jjspace
Copy link
Contributor

@jjspace jjspace commented Nov 7, 2025

Description

  • Alter the path built for the tsc binary to account for "url" vs "file" path discrepancies on Windows
  • Convert all paths to / instead of \ for globby which only accepts /
  • Removed some unused commented code that I noticed was left over from one of my previous PRs

I am unable to easily test these changes myself as they only affected windows but I tried to validate the individual functions with fake paths as much as possible. @javagl you've seen these the most so I'd appreciate if you can validate that things are working for you now.

Issue number and link

Fixes #13019
Fixes #12951

Testing plan

  • run npm run build-sandcastle
  • Ensure the build steps complete with no errors
  • run npm start
  • Ensure that local sandcastle displays the gallery and search works as expected

Author checklist

  • I have submitted a Contributor License Agreement
  • I have added my name to CONTRIBUTORS.md
  • I have updated CHANGES.md with a short summary of my change
  • I have added or updated unit tests to ensure consistent code coverage
  • I have updated the inline documentation, and included code examples where relevant
  • I have performed a self-review of my code

@jjspace jjspace requested a review from javagl November 7, 2025 22:28
@github-actions
Copy link

github-actions bot commented Nov 7, 2025

Thank you for the pull request, @jjspace!

✅ We can confirm we have a CLA on file for you.

@jjspace jjspace mentioned this pull request Nov 7, 2025
Copy link
Contributor

@javagl javagl left a comment

Choose a reason for hiding this comment

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

This caused the same issue as @Beilinson already mentioned in #13019 (comment) : It says

Error: spawn C:/cesium/node_modules/typescript/bin/tsc ENOENT

in the build-sandcastle step.

Near the linked comment, you already said

I wonder if the binary isn't set to be executable on Windows

And ... this is ... "true", in some way. It is not a binary. And the concept of "being executable" does not exist on Windows in the same way as it does on Linux. The file does exist (no comment about ENOENT at this point). But it is a file that only contains

#!/usr/bin/env node
require('../lib/tsc.js')

I'd expect it to be the same on Linux. But on Linux, one can just set the "executable" flag, and then, the first line tells Linux how to execute that thing (roughly like that...)


The linked issue already suggested using
const ls = spawn(process.execPath, [binPath, "-p", configPath]);

And from my understanding, this should make sense: The process.execPath will be
C:\Program Files\nodejs\node.exe
as expected. The binPath is what is shown above. So this is explicitly using node to execute that file, which (I think) is the same what happens under Linux, but there, this is accomplished with that
#!/usr/bin/env node
line.

One important point - referring to your comment at #13019 (comment) - is that this is not using the "globally installed npx (with its arbitrary version)". It is really executing the exact tsc that is found in the node_modules directory.

Given the lack of alternatives (with the "Compiler API" being "version 0.5 beta" for 2 years now...), this sounds like a reasonabe solution, unless I'm overlooking something.

@javagl
Copy link
Contributor

javagl commented Nov 8, 2025

And I didn't mention that: The "globby" fix also seems to work - it does display the gallery.


BTW: npm run build-apps still causes

Error: ENOENT: no such file or directory, scandir 'C:\cesium\Build\Cesium\Assets'

but (as discussed elsewhere), the sequence of
npm run build-release
npm run build-apps
does work.


My "broken record" mantra about documentation and such:

I think that the build infrastructure could and should(!) be simplified significantly. The 1500-line(!)-gulpfile could be shrunk to 1000 lines by removing redundancies. It should then be increased to 2000 lines by adding extensive documentation for each and every function. This 2000-line-file should then be broken down into at least 10 files with generic utility functionalities. One prominent example is the "generate third party" functionality. If this was implemented once, in a proper form, and in a standalone file, then the same file could be used in CesiumJS, in the 3d-tiles-validator, wetzel, the 3d-tiles-tools, in gltf-pipeline, and about a dozen private repos where this functionality was duplicated.

(In fact, the 3d-tiles-tools and 3d-tiles-validator versions of that already are (nearly...) equal, and already contain some documentation (but could contain more). Similarly, there are command documentations and hierarchical commands - I think that all of this could help longer-term maintainability and flexibility (e.g. so that you can execute specific steps, dedicatedly, with npm run <category>-<substep>-<task>-like calls). But ... let's first get that \-vs-/ thing right...)

@wewindy
Copy link
Contributor

wewindy commented Nov 8, 2025

Checkout this branch, I add some logs and run npm run build-sandcastle, got:

PixPin_2025-11-08_22-22-57

@wewindy
Copy link
Contributor

wewindy commented Nov 8, 2025

But when I change to:

 export default async function typescriptCompile(configPath) {
   const tsPath = fileURLToPath(import.meta.resolve("typescript"));
-  const binPath = join(tsPath, "../../.bin/tsc");
+  const binPath = join(tsPath, "../../../.bin/tsc.cmd");
   return new Promise((resolve, reject) => {
-    const ls = spawn(binPath, ["-p", configPath]);
+    const ls = spawn(binPath, ["-p", configPath], { shell: true });

     ls.stdout.on("data", (data) => {
       console.log(`stdout: ${data}`);
     });

     ls.stderr.on("data", (data) => {
       console.error(`stderr: ${data}`);
     });

     ls.on("close", (code) => {
       if (code === 0) {
         resolve(code);
       } else {
         reject(code);
       }
     });
   });
 }

It works.

Okay, I think I know what's going on. Using Notepad, I opened node_modules/typescript/bin/tsc:

#!/usr/bin/env node
require('../lib/tsc.js')

and node_modules/.bin/typescript/tsc:

#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")

case `uname` in
    *CYGWIN*|*MINGW*|*MSYS*)
        if command -v cygpath > /dev/null 2>&1; then
            basedir=`cygpath -w "$basedir"`
        fi
    ;;
esac

if [ -x "$basedir/node" ]; then
  exec "$basedir/node"  "$basedir/../typescript/bin/tsc" "$@"
else 
  exec node  "$basedir/../typescript/bin/tsc" "$@"
fi

They are actually script files with shebang lines.

As we known, Windows does not support Unix shebang, so we can only call the tsc.cmd file with spawn function, and need to use the shell: true parameter.

The bin/tsc provided by the Node.js TypeScript package is not an executable program, but a script. In fact, typescript is a complete JavaScript package that uses JavaScript to translate TypeScript code.

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.

compile error new Cesium Sandcastle

4 participants