toastdotdev / toast

The best place to stack your JAM. Toast is a Jamstack framework
153 stars 13 forks source link

fix: node_modules path as cli arg #33

Open jbolda opened 3 years ago

jbolda commented 3 years ago

Node on windows doesn't setup the bins with symbolic links that we can follow by calling the binary. We don't have very great tools in rust space to derive the location of node_modules and the bin. So instead, we grab them in our light node wrapper and pass them in as args.

jbolda commented 3 years ago

This PR focuses on the new rust CLI flag to pass the toast_module_path. After resolving the binary issues, there were a few downstream path issues that I fixed as well. This was tested on www which, as I understand, doesn't use sourceData so it is possible there are still a couple path bugs there.

Any adjustments to the integration test are purely to fix bugs where it wasn't functioning correctly to use the source code.

jbolda commented 3 years ago

Looks like in switching the tests we did hit issues with source data. Thought you might appreciate some help, but I didn't want to commit anything just in case. It looks like we are hitting path issues with the ESM loader again. I think we can use this function which does something similar to what we had to do in the .mjs with the relative paths.

#[cfg(windows)]
fn windows_path_to_esm(windows_path: &PathBuf) -> String {
    use std::path::Component;
    let mut stringified = windows_path
        .components()
        .filter_map(|comp| match comp {
            Component::Normal(comp) => comp.to_str(),
            _ => None,
        })
        .collect::<Vec<&str>>()
        .join("/");
    stringified.insert_str(0, "/");
    stringified
}

It doesn't seem like we have much help to find relative paths, so running this would give us a path like /Users/Jacob/Documents/dev/christopherbiscardi/toast/toast-node-wrapper/toast-source-data.mjs which is valid for the ESM loader mostly since it doesn't have a colon. That will still resolve to the root of where it is run (so C:).

Unfortunately we then hit an error with the .sock path.

Running toast with overridden binary path: ./toast/target/debug/toast.exe
internal/process/promises.js:213
        triggerUncaughtException(err, true /* fromPromise */);
        ^
RequestError: connect ENOENT /var/tmp/toaster.sock
    at ClientRequest.<anonymous> (C:\Users\Jacob\Documents\dev\christopherbiscardi\node_modules\got\dist
\source\core\index.js:957:25)
    at Object.onceWrapper (events.js:421:26)
    at ClientRequest.emit (events.js:326:22)
    at ClientRequest.origin.emit (C:\Users\Jacob\Documents\dev\christopherbiscardi\node_modules\@szmarcz
ak\http-timer\dist\source\index.js:39:20)
    at Socket.socketErrorListener (_http_client.js:469:9)
    at Socket.emit (events.js:314:20)
    at emitErrorNT (internal/streams/destroy.js:106:8)
    at emitErrorCloseNT (internal/streams/destroy.js:74:3)
    at processTicksAndRejections (internal/process/task_queues.js:80:21)
    at PipeConnectWrap.afterConnect [as oncomplete] (net.js:1145:16) {
  code: 'ENOENT',
  timings: {
    start: 1604158940178,
    socket: 1604158940179,
    lookup: undefined,
    connect: undefined,
    secureConnect: undefined,
    upload: undefined,
    response: undefined,
    end: undefined,
    error: 1604158940181,
    abort: undefined,
    phases: {
      wait: 1,
      dns: undefined,
      tcp: undefined,
      tls: undefined,
      request: undefined,
      firstByte: undefined,
      download: undefined,
      total: 3
    }
  }
}
Error:
   0: command ["cmd", "/c", "node", "--unhandled-rejections", "strict", "--loader", "toast/src/loader.mj
s", "/Users/Jacob/Documents/dev/christopherbiscardi/toast/toast-node-wrapper/toast-source-data.mjs", "/v
ar/tmp/toaster.sock", "/Users/Jacob/Documents/dev/christopherbiscardi/default/toast.js"] exited with cod
e 1

I think we could use %TEMP% which is a built-in env var, but then we need to deal with C: again.

Running toast with overridden binary path: ./toast/target/debug/toast.exe
internal/process/promises.js:213
        triggerUncaughtException(err, true /* fromPromise */);
        ^
TypeError [ERR_INVALID_URL]: Invalid URL: http://unix:C:\Users\Jacob\AppData\Local\Temp/toaster.sock:/
    at onParseError (internal/url.js:257:9)
    at new URL (internal/url.js:333:5)
    at Object.exports.default (C:\Users\Jacob\Documents\dev\christopherbiscardi\node_modules\got\dist\so
urce\core\utils\options-to-url.js:35:17)
    at normalizeArguments (C:\Users\Jacob\Documents\dev\christopherbiscardi\node_modules\got\dist\source
\core\index.js:480:51)
    at got (C:\Users\Jacob\Documents\dev\christopherbiscardi\node_modules\got\dist\source\create.js:112:
39)
    at main (file:///C:/Users/Jacob/Documents/dev/christopherbiscardi/toast/toast-node-wrapper/toast-sou
rce-data.mjs:10:21) {
  input: 'http://unix:C:\\Users\\Jacob\\AppData\\Local\\Temp/toaster.sock:/',
  code: 'ERR_INVALID_URL'
}
Error:
   0: command ["cmd", "/c", "node", "--unhandled-rejections", "strict", "--loader", "toast/src/loader.mj
s", "/Users/Jacob/Documents/dev/christopherbiscardi/toast/toast-node-wrapper/toast-source-data.mjs", "%T
EMP%/toaster.sock", "/Users/Jacob/Documents/dev/christopherbiscardi/default/toast.js"] exited with code
1

That was as far as I got.

EDIT: Looks like std::env::temp_dir() may be a better alternative here.