Getting SublimeText2 to compile Typescript - node.js

Really excited about using Typescript on the Mac however, even after a full day of troubleshooting, unable to get it to compile in SublimeText. Followed these directions (the first at the top) to install nodes and npm>
https://gist.github.com/isaacs/579814
Installed Typescript
sudo npm install -g typescript
Installed the syntax highlighting package for sublime
http://msopentech.com/blog/2012/10/01/sublime-text-vi-emacs-typescript-enabled/
Created a build file 'typescript.sublime-build as follows
{
"selector": "source.ts",
"cmd": ["tsc", "$file"],
"path": "/usr/local/bin",
"file_regex": "^(.+?) \\((\\d+),(\\d+)\\): (.+)$"
}
When I type $which node I get
/usr/local/bin/node
When I type $which tsc I get
/Users/<username>/local/bin/tsc
BUT, whenever I try to compile even the simplest .ts file in SublimeText the first effort message I get is
[Errno 2] No such file or directory
Can anyone suggest further troubleshooting steps?

I struggled with a little too. It seems the PATH is quite different when trying to run commands directly from the build system than the terminal, and this is a cause of problems.
What I did as a simple workaround was just set my command to run a Bash script, i.e. in the sublime.project file have the command as..
"cmd": ["./build.sh"]
.. and then in the build.sh script in my project folder simply run the compiler, i.e..
#! /bin/bash
tsc --target ES5 foo.ts
Obviously this assumes foo.ts pulls in all the other project files so they get compiled (or you could glob for the files on the command-line seeing as you're running a Bash command).
This might be a quick and simple solution for you.

You could do what my team mates do. Use Sublime Text for text editing with a grunt watch in the background compiling any files that change : https://github.com/basarat/grunt-ts

Related

Using NPX command for shell script shebang / interpreter

I'd like to run a command line script using the coffee executable, but I'd like to call that executable through npx.
Something like #!/usr/bin/env npx coffee does not work, because only one argument is supported via env.
So, is there a way to run an npx executable via env?
Here is a solution using ts-node.
Any single OS, ts-node installed globally
#!/usr/bin/env ts-node
// TypeScript code
You probably also need to install #swc/core and #swc/cli globally unless you do further configuration or tweaking (see the notes at the end). If you have any issues with those, be sure to install the latest versions.
macOS, ts-node not installed globally
#!/usr/bin/env npx ts-node
// TypeScript code
Whether this always works in macOS is unknown. There could be some magic with node installing a shell command shim (thanks to #DaMaxContext for commenting about this).
This doesn't work in Linux because Linux distros treat all the characters after env as the command, instead of considering spaces as delimiting separate arguments. Or it doesn't work in Linux if the node command shim isn't present (not confirmed that's how it works, but in any case, in my testing, it doesn't work in Linux Docker containers).
This means that npx ts-node will be treated as a single executable name that has a space in it, which obviously won't work, as that's not an executable.
See the notes at the bottom about npx slowness.
Cross-platform with ts-node not installed globally in macOS, and some setup in linux
Creating a shebang that will work in both macOS and Linux (or macOS using Docker running a Linux image), without having to globally install ts-node and other dependencies in macOS, can be accomplished if one is willing to do a little bit of setup on the Linux/Docker side. Obviously, Linux must have node installed.
Use the #!/usr/bin/env npx ts-node shebang. We just have to fool Linux into thinking that npx ts-node with the space is actually a valid executable name.
Build a named Docker image that has the required dependencies globally installed and a symbolic link making npx ts-node resolve to just ts-node.
Here is an example all-in-one command line on macOS that will both build this image and run it:
docker buildx build -t node-ts - << EOF
FROM node:16-alpine
RUN \
npm install -g #swc/cli #swc/core ts-node \
&& ln -s /usr/local/bin/ts-node '/usr/local/bin/npx ts-node'
ENV SWC_BINARY_PATH=/usr/local/lib/node_modules/#swc/core/binding
WORKDIR /app
EOF
docker run -it --rm \
-v "$(pwd):/app" \
node-ts \
sh
Note that for this example script to work, the above line containing EOF must not have any other characters on the line, before or after it, including spaces.
Inside of the running container, all .ts scripts that have been made executable chmod +x script.ts will be executable simply by running them from the command line, e.g., ./test-script.ts. You can replace the above sh with the name of the script, as well (but be sure to precede it with ./ so Docker knows to run it as an executable instead of pass it as an argument to node).
Additional Thoughts & Considerations
There are other ways to achieve the desired functionality.
The docker run command can mount files into the image, including mounting executables in various directories. Some creative use of this could avoid needing to install anything or build a docker image first.
The install commands could be part of the docker run instead of pre-building an image, but then would be performed on each execution, taking much longer.
The PATH could be modified in macOS, linux, and in the docker build to add the folder containing ts-node's bin.js from any ts-node dist directory, then a shebang of #!/usr/bin/env bin.js should theoretically work (and can try bin-esm.js to avoid needing SWC, though this enters experimental node territory and may not be suitable for production scripts). This works in macOS, and in Docker outside of an npm project, and in Docker inside of an npm project configured to use TS & swc by passing the --skipProject flag to ts-node or setting environment variable TS_NODE_SKIP_PROJECT=true. A working test command line example: docker run -it --rm -v "$(pwd):/app" -e TS_NODE_SKIP_PROJECT=true -w /app --entrypoint sh node:16-alpine -c 'PATH="$PATH:/app/node_modules/ts-node/dist" ./test.ts'.
Any named executable that can be found in the PATH and run via direct command can be a shebang (using #!/usr/bin/env executable). It can be a shell script, a binary file, anything. A shell script can easily be put at a known location, added to the PATH, and then call whatever you like. It could be multi-statement, compiling the file to .js, then running that. Whatever your needs are.
In some special cases you might want to simply use node as your shebang executable, setting node options through environment variables to force ts-node as your loader. See ts-node Recipes:Other for more info on this.
Notes:
The SWC_BINARY_PATH environment variable ensures that ts-node can find the architecture-specific swc compiler (to avoid error "Bindings not found"). If you're running on only one architecture, you won't need it. Or, if you are mounting node_modules that have these #swc packages already installed for the correct architecture, you won't need it.
It is possible to install node_modules binaries for multiple architectures. The way to do this varies between the different package managers. For example, yarn 3 lets you define which binaries to install all at once in .yarnrc.yml. There are other options for npm and possible yarn 1 (and 2?) using environment variables.
ts-node does offer options for running without swc (though this is slower). You could try shebangs with ts-node-esm instead of ts-node. Look at all the symlinks in the /usr/local/bin folder or consult ts-node documentation for more information. If ts-node
It is possible to run .ts files directly using node and setting node options in environment variables. node --loader=ts-node does work, in recent versions (16+?). The experimental mode warnings can be suppressed.
There are some crazy ways to trick the shell to run JavaScript instead of a unix shell. Check out this answer that uses a normal sh shebang, but a clever shell statement to transfer execution over to node, that is basically ignored by JavaScript. This isn't great as it requires extra lines of trickery, but could help some people. Other answers on the page are also instructive and it's worth reviewing to get the full picture.
Some of the complexity here might go away if running .ts files outside of an npm project. In my own testing in Docker, the context was always in a project having its own tsconfig.json and swc installed, so with a different setup you might have different results. It proved to be difficult to get ts-node to ignore npm project context found with the executed .ts file.
The difference between ESM and CommonJS module handling has not been explained here. This is a complicated topic and beyond the scope of this answer.
Suffice it to say that if you can figure out how to run your scripts from the command line in the form executable [options] [file], then you should be able to figure out how to run ./[file] with an appropriate shebang, by mixing and matching all the ideas presented here. You don't have to use ts-node. You can directly use node, swc, tsc itself (by first compiling and then running any .js file or set of .js files in the found context), or any utility or tool that is able to compile or run TypeScript.
Note that using npx is significantly slower than running ts-node directly, because it may need to download the ts-node package, and dependencies, every time it runs.
Some various random tips on possible strategies for SWC architecture support:
https://socket.dev/npm/package/#rnw-community/nestjs-webpack-swc
https://github.com/yarnpkg/yarn/issues/2221

Warning: Task "python_packages" not found. Use --force to continue

I am trying to manually setup this project.
When I run grunt command, I am getting below error.
C:\myworkspace\NASA\worldview>grunt
Warning: Task "python_packages" not found. Use --force to continue.
Aborted due to warnings.
Tried with grunt --force. But not worked.
How could I solve this?
Use --force to continue.
Try to run grunt --force.
If it's only a warning, it should pass.
Try making these changes in Gruntfile.js
Change line #321 to
command: 'virtualenv python && "python/Scripts/pip" install xmltodict isodate'
Change line #717 to
grunt.registerTask("default", ["exec:python_packages", "update", "build", "config", "site"]);
Delete python_packages from line no. 717 of the Gruntfile.js and replace it with exec:python_packages. So it reads:
grunt.registerTask("default", ["exec:python_packages", "update", "build", "config", "site"]);
Then run $ grunt via the CLI again.
When the tasks have completed you'll find the .tar files in the dist folder.
EDIT:
As per #Ryuu Agamaki answer you need to also:
Change line #321 to
command: 'virtualenv python && "python/Scripts/pip" install xmltodict isodate'
python/bin/ doesn't exist on Windows.
Extracting the tar.bz2 files
This done 99% without errors. But stuck at last minute. Here is the log file
The issue is now related to extracting the tar.bz2 files. So the commands on line no.s 330, 335, 340, 345, 350 of the Gruntfile.js will all fail on your system. Your log on line #103 reports:
tar: invalid option -- j
What are those commands doing?
As documented here, the cjCf arguments in the command(s) are:
-c : Create a new archive (or truncate an old one) and write the named files to it.
-j : filter the archive through bzip2
-C : change to directory DIR
-f : use archive file or device ARCHIVE
As per your error log it indicates that your system cannot handle the arguments, particularly the j argument (bzip2).
What next?
I would consider replacing those commands in the Gruntfile.js with an equivalent tar command that you know works on your system (Windows).
Some tools for handling tar.bz2 are listed here - assuming you don't already have the necessary tool. Whether these offer equivalent commands to handle the cjCf arguments I'm not sure. There's also node-uncompress which has command-line commands - which may be worth trying, however, I'm unsure whether it supports cross platform..
The worst case scenario is you may find you have to and omit the calls to the commands, (i.e. those calls to the lines of code previously mentioned, "exec:python_packages" etc, etc), from the Gruntfile.js completely. Then manually extract the tar.bz2 files yourself (using something like 7-zip or WinRAR), and move the resultant files into the appropriate folder.
Clearly non Nix systems weren't considered/tested when developing the tooling for this project.

Problems with Coda 2/CoffeeScript plugin

Regarding plugin for Coda 2. I am having some problems making it work. I have written a small test program in CoffeeScript, but when i try to run and/or compile I get the following error message:
All settings/env. variables should be set correctly:
Do you have any idea as to what that may cause this issue? I have installed node using homebrew, and then coffee script via npm. All the shell variables have been verified, and I am able to run node from the command line and write scripts there. Also, when i go to settings and click on "About", I get the following:
Hope you can help.
Thank you and best regards,
Thomas
In Terminal, run the command:
which coffee
For me, this gave:
/usr/local/bin/coffee
So in the CoffeeScript Plug-In Settings, I set PATH to:
/usr/local/bin
Then when I went to the About box, it showed the version of CoffeeScript that I have installed and the Run & Compile options then worked fine.

Node.js Cygwin not supported

I am trying to install node.js. I followed this tutorial and i am stuck in the middle.
When I write ./configure in my cygwin terminal it says "cygwin not supported". Please help me out
Thanks in advance.
Node in my experience runs fine in cygwin, what Node usually has EINVAL errors in seems to be MINTTY which is a terminal emulation 'skin' that is default to cygwin. I still am not sure why these EINVAL errors happen 100% but the following are the steps and tricks I use to get node working.
In my /cygwin/home/{username}/.bashrc I add node to path so cygwin can find it
export PATH=$PATH:"/cygdrive/c/Program Files/nodejs/"
If you run a 32 bit version of node:
export PATH=$PATH:"/cygdrive/c/Program Files (x86)/nodejs/"
Then to make npm run without windows to linux issues I launch cygwin in admin mode then run:
dos2unix '/cygdrive/c/Program Files/nodejs/npm'
At this point running files and most npm packages will run in MINTTY just fine, although every once and awhile you will run into EINVAL issues with certain npm packages as karma. Also you will not be able to run the interpreter directly in MINTTY, anytime I want to do these things I run:
cygstart /bin/bash
This will open a native cygwin bash.exe window, from here you run the interpreter or an any troubling package command that results in a EINVAL. It slightly sucks you have to do this but I rarely use this day to day, and I love MINTTY too much to not use it.
Also note that you can run any one line node code in MINTTY by just running something like:
node -e "console.log('hello node')"
As a simpler derivative of troy's answer for those just looking to install NPM packages:
Install Node.js with the Windows installer package.
Add it to the PATH with export PATH=$PATH:"/cygdrive/c/Program Files/nodejs/" (obviously replacing the path to Node.js's installation directory with where you installed it).
There's a current bug in the Windows version that can be fixed by running mkdir -p ~/AppData/Roaming/npm. This is a bug for all of Windows and not just Cygwin. At some point of the future, you won't have to do this anymore, but the command shouldn't have any negative side effects.
Test it. Eg, npm install pretty-diff -g.
In order to be able to run the newly installed software, you'll need to add the install locations to your PATH. You can find these with npm bin -g and npm bin (the -g flag is the "global" installation location).
Not really anything special that you have to do to get it to run in Cygwin (although I can't say if everything works).
Use Console2, it allows you to run create tabs of CLI shells. It seems running cygwin inside console2 allows me to use node REPL just fine. I have no idea why :P
Follow this guide to add cygwin to console2:
http://blog.msbbc.co.uk/2009/11/configuring-console-2-and-bash-with.html
With Bjørn's suggestion (using Console2) and Soyuka's alias (steps here), my node.js v0.10.13 and npm v1.3.2 are now working under Babun v1.02, a Cygwin distribution.
For windows, Just run bash.exe in cmd, so that you could have a bash work around with cmd console directly, which could support ALL NODE WORKING PERFECTLY.
C:\Users\郷>bash
郷#CHIGIX ~
$ node
>
I'm using this wrapper in /usr/local/bin/node (note no extension!)
#!/bin/sh
_cmd="$(cygpath -lw -- "$1" )"
shift
"/proc/cygdrive/C/Program Files/nodejs/node.exe" "$_cmd" "$#"
This is far from perfect, as Node do not understand Cygwin directory tree, but works relatively well with relative names.
From Windows, run Cygwin.bat (instead of Cygwin Terminal) then in that run node: see and reply on this answer on this effectively-same question asked 1.5 years later.
Grab and run the node.js Windows installer.
In the Cygwin prompt type node
See if it works.

Problems with LESS Sublime Text Build System

On OS X 10.7.2, I created a small build system in Sublime Text 2 that will compile my LESS files into CSS for me, but it seems to be having a problem.
{
"cmd": ["/usr/local/lib/node_modules/less/bin/lessc", "-x", "$file", "$file_path/$file_base_name.css"],
"selector": ["source.less"]
}
I've installed Node.js v0.6.6 using the standard OS X installer package, and installed less v1.1.6 using npm into the /usr/local/lib/node_modules folder. Switching to my build system works fine, but when I attempt to run the build I get the following error message:
[Finished]env: node: No such file or directory
Running the command from the terminal works perfectly fine, it's just Sublime that is taking issue.
Another way to solve this is to install LESS globally, as it looks like you've already done:
npm install -g less
Then pass shell=true as a variable in the build script:
{
"shell" : true,
"cmd": ["lessc", "-x", "$file", "$file_path/$file_base_name.css"],
"selector": "source.css.less"
}
That runs the lessc command in the terminal in a way you'd expect.
While I am still unsure as to why there is a difference between Sublime Text 2 and running the build system in the terminal, I fixed the issue I was encountering by explicitly adding the value of $PATH to my build system.
Acting on the documentation provided on the Sublime Text Help page, I set up my build system to be the following:
{
"cmd": ["/usr/local/lib/node_modules/less/bin/lessc", "-x", "$file", "$file_path/$file_base_name.css"],
"selector": "source.css.less",
"path": "/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin: No such file or directory"
}

Resources