node-sass cli not compiling on initial run when using --watch - node.js

So when running the following command I'm expecting node-sass to compile and start watching. If I have to run a separate node-sass -w command wouldn't I have to include all the same parameters I included on the first? Seems like an odd way of doing things.
node-sass app/styles -o app/styles --source-map true --include-path app/bower_components --quiet --watch

Actually watch triggers compilation each and every time the file changes, as the (sass) documentation states:
You can also tell Sass to watch the file and update the CSS every time the Sass file changes: [...]
However, the documentation says nothing about what happens when the watch process starts, which is what led you to expect it to compile right after being invoked.
It's, for sure, an odd way of doing things.

Related

ESLint output to file and console at the same time

By default ESLint will print it's results to standard output. If you add the output option, it will redirect the output to a file. So far so good, but is there a way for it to do both?
We need the file output for GitLab to parse the results and display them in the UI, but some of our developers can't be bothered to change the way they do things and want to look at the output instead.
Is there an out-of-the-box way to get both or is my only chance to write my own script for running ESLint using the CLIEngine Node stuff mentioned in their documentation?
Thanks in advance.
So, after some research I think I found the answer myself.
There's basically 2 ways to have output on both console and file at the same time:
The easy way is by using this JavaScript package called ESLint Output.
The more complicated way is basically building said package yourself. You have to create a JavaScript file which you will run instead of ESLint and import/require ESLint in that file. By importing ESLint as a package instead of running it directly you can then run ESLint using Node's CLIEngine on your files to be linted and store the output in a variable. That output can then be saved to a file and printed again.
Hopefully, to no one's surprise, the methodology described in Option 2 is exactly what the package in Option 1 does: wrapping option 2 in an easy to understand config file and gathering all the configuration from the default eslintrc file for you.
Just write ESLint result into file and then read it by using one of ESLint-formatters:
npx eslint ./cartridges/ --format json --output-file result.json
node -p "require('./node_modules/eslint/lib/cli-engine/formatters/unix.js')(require('./result.json'))"
You can achieve it with eslint-html-reporter. When you'd like to have results from Terminal and export this into an .html file then the output from Terminal becomes a bit less pretty (which is not the case if it's done only in one of those), but it's doable by running:
./node_modules/.bin/eslint --ext .jsx . & ./node_modules/.bin/eslint --ext .jsx . -f node_modules/eslint-html-reporter/reporter.js -o report.html (in this example it looks recursively for .jsx file in your project's folder).
I had the same issue, and worked around by running eslint twice.
Created a shell script with
#!/usr/bin/env bash
node_modules/.bin/eslint --quiet \
--max-warnings 100 \
-o eslint-output.$1 \
-f $1 '*/**/*.{js,ts,tsx}'
Then call the script twice thru Jenkins:
steps {
echo 'Rodando ESLint...'
sh("""
yarn install
./eslint.sh junit || true
./eslint.sh codeframe || true
""")
junit(
allowEmptyResults: true,
healthScaleFactor: 0.0,
testResults: 'eslint-output.junit'
)
}
To generate the file for report:
eslint src/ --format json --output-file eslintreport.json

How to use Internjs in watch mode

I'm setting up my test environment and I want to use Internjs to peform my unit tests. I'm using typescript and when I type npx intern my tests are executed correctly.
But I can't configure Internjs in watch mode and the doc's didn't gave any help.
Someone can help me to configure Intern to run the unit tests when any change in my files are made?
There isn't currently a built-in watch mode in Intern.
You can implement a custom watcher using chokidar (install chokidar-cli for the command line tool). Run tsc --watch to rebuild your code as necessary, and use chokidar to watch for changes and re-run intern:
$ chokidar '**/*.js' -c 'npx intern' -d 1000

Waiting for webpack bundling before launching nodemon

I have a nodejs project written in Typescript. Therefore, i have webpack using a typescript loader that transpiles my code in Javascript and bundles it in a server.js file (in a dist folder)
When in developement conditions, my webpack runs with its watcher ON and so does nodemon.
Problem is, when i launch my script for the first time combining webpack and nodemon, since webpack is in watch mode it doesn't have an exit code saying that everything is ok, nodemon script can be started. If i run them simultaneously, nodemon will launch faster than webpack and since server.js file doesn't yet exist, it will crash at the start.
I want to launch thanks to one single command both scripts but make nodemon command wait for the bundling to be done.
First of all, when please provide some code when submitting questions.
and since server.js file doesn't yet exist
I think you should work around your setup a little bit s.t. webpack doesn't create your server.js file if you want to do this.
Basically you can chain multiple commands in a script like so webpack -d && nodemon index.js. This will launch node after webpack completes. However if you setup webpack in watch mode -w it never exists, so you can't chain another command to it. So webpack -d -w && nodemon index.js never gets to the nodemon part.
A solution to the above is to chain them using only &, which I guess you are doing, but in this way they both start at the same time. Hence, if you make your setup independent (webpack doesn't interfere with nodemon starting script) you can list them like so.
If for whatever reasons you can't do this or don't want to, your only option is with 2 separate scripts that you launch manually one after the other.
If I were you, I would just use nodemon-webpack-plugin:
Uses Nodemon to watch and restart your module's output file, but only
when webpack is in watch mode (ie, --watch).
Saves the need for installing, configuring and running Nodemon as a
seperate process.

ubuntu 14.04 LTS webpack --watch not recompiling after a few times

I'm using Webpack along with Babel to compile my jsx into js. --watch will work a few times but then stop afterwards. I've had to resort to manually typing in webpack every time in order to make sure my scripts get compiled.
I had a similar problem to this where it turned out that webpack was silently failing to report that I had exceeded the max number of inotify watchers in Linux. Webpack watch uses inotify to observe file changes.
You can immediately try a fix to see if it works with:
sudo -i
echo 1048576 > /proc/sys/fs/inotify/max_user_watches
exit
The long term fix would be to increase your allowed watchers by editing your /etc/sysctl.conf to include this line: fs.inotify.max_user_watches=1048576.
The issue was reported here: https://github.com/webpack/webpack/issues/1281

How to run TypeScript files from command line?

I'm having a surprisingly hard time finding an answer to this. With plain Node.JS, you can run any js file with node path/to/file.js, with CoffeeScript it's coffee hello.coffee and ES6 has babel-node hello.js. How do I do the same with Typescript?
My project has a tsconfig.json which is used by Webpack/ts-loader to build a nice little bundle for the browser. I have a need for a build step run from the console before that, though, that would use some of the .ts files used in the project to generate a schema, but I can't seem to be able to run a single Typescript file without compiling the whole project.
How do I do the same with Typescript
You can leave tsc running in watch mode using tsc -w -p . and it will generate .js files for you in a live fashion, so you can run node foo.js like normal
TS Node
There is ts-node : https://github.com/TypeStrong/ts-node that will compile the code on the fly and run it through node 🌹
npx ts-node src/foo.ts
Run the below commands and install the required packages globally:
npm install -g ts-node typescript '#types/node'
Now run the following command to execute a typescript file:
ts-node typescript-file.ts
We have following steps:
First you need to install typescript
npm install -g typescript
Create one file helloworld.ts
function hello(person){
return "Hello, " + person;
}
let user = "Aamod Tiwari";
const result = hello(user);
console.log("Result", result)
Open command prompt and type the following command
tsc helloworld.ts
Again run the command
node helloworld.js
Result will display on console
To add to #Aamod answer above, If you want to use one command line to compile and run your code, you can use the following:
Windows:
tsc main.ts | node main.js
Linux / macOS:
tsc main.ts && node main.js
Edit: May 2022
ts-node now has an --esm flag use it.
Old Answer:
None of the other answers discuss how to run a TypeScript script that uses modules, and especially modern ES Modules.
First off, ts-node doesn't work in that scenario, as of March 2020. So we'll settle for tsc followed by node.
Second, TypeScript still can't output .mjs files. So we'll settle for .js files and "type": "module" in package.json.
Third, you want clean import lines, without specifying the .js extension (which would be confusing in .ts files):
import { Lib } from './Lib';
Well, that's non-trivial. Node requires specifying extensions on imports, unless you use the experimental-specifier-resolution=node flag. In this case, it would enable Node to look for Lib.js or Lib/index.js when you only specify ./Lib on the import line.
Fourth, there's still a snag: if you have a different main filename than index.js in your package, Node won't find it.
Transpiling makes things a lot messier than running vanilla Node.
Here's a sample repo with a modern TypeScript project structure, generating ES Module code.
I created #digitak/esrun, a thin wrapper around esbuild and that executes a TypeScript file almost instantly. esrun was made because I was disappointed with ts-node: too slow, and just didn't work most of the time.
Advantages of esrun over ts-node include:
very fast (uses esbuild),
can import ESM as well as CJS (just use the libraries of your choice and esrun will work out of the box),
there is an included watch mode, run your script with the --watch option and any change to your entry file or any of its dependencies will re-trigger the result
you can use esrun in inspect mode to use the DevTools console instead of your terminal console.
After installing, just run:
npx #digitak/esrun file.ts
Just helpful information - here is newest TypeScript / JavaScript runtime Deno.
It was created by the creator of node Ryan Dahl, based on what he would do differently if he could start fresh.
You can also try tsx.
tsx is a CLI command (alternative to node) for seamlessly running TypeScript, its build upon esbuild so its very fast.
https://github.com/esbuild-kit/tsx
Example:
npx tsx ./script.ts
As of May 2022 ts-node does support es modules
npx ts-node --esm file.ts
you will likely need to add "type": "module", to your package.json. And some of the imports might be wonky unless you turn on experimental-specifier-resolution=node
npmjs.com/package/ts-node#commonjs-vs-native-ecmascript-modules
For linux / mac you can add the ts-node-script shebang.
Install typescript / ts-node globally (see 1 below for non global install):
npm install ts-node typescript --save-dev --global
Add this as the first line in your .ts file:
#!/usr/bin/env ts-node-script
Then make the file executable:
$ chmod +x ./your-file.ts
You can then run the file directly from the command line:
$ ./your-file.ts
Notes:
1 For non global install you can install local to your project
npm install ts-node typescript --save-dev
and add the relative path to the shebang script eg:
#!/usr/bin/env ./node_modules/.bin/ts-node-script
2 Support for shebangs was officially added in ts-node v8.9.0.
Like Zeeshan Ahmad's answer, I also think ts-node is the way to go. I would also add a shebang and make it executable, so you can just run it directly.
Install typescript and ts-node globally:
npm install -g ts-node typescript
or
yarn global add ts-node typescript
Create a file hello with this content:
#!/usr/bin/env ts-node-script
import * as os from 'os'
function hello(name: string) {
return 'Hello, ' + name
}
const user = os.userInfo().username
console.log(`Result: ${hello(user)}`)
As you can see, line one has the shebang for ts-node
Run directly by just executing the file
$ ./hello
Result: Hello, root
Some notes:
This does not seem to work with ES modules, as Dan Dascalescu has pointed out.
See this issue discussing the best way to make a command line script with package linking, provided by Kaspar Etter. I have improved the shebang accordingly
Update 2020-04-06: Some changes after great input in the comments: Update shebang to use ts-node-script instead of ts-node, link to issues in ts-node.
Write yourself a simple bash wrapper may helps.
#!/bin/bash
npx tsc $1 && node ${1%%.ts}
For environments such as Webstorm where the node command cannot be changed to ts-node or npx:
npm install ts-node typescript (Install dependencies)
node --require ts-node/register src/foo.ts (Add --require ts-node/register to "Node parameters")
This answer may be premature, but deno supports running both TS and JS out of the box.
Based on your development environment, moving to Deno (and learning about it) might be too much, but hopefully this answer helps someone in the future.
Just in case anyone is insane like me and wants to just run typescript script as though it was a .js script, you can try this. I've written a hacky script that appears to execute the .ts script using node.
#!/usr/bin/env bash
NODEPATH="$HOME/.nvm/versions/node/v8.11.3/bin" # set path to your node/tsc
export TSC="$NODEPATH/tsc"
export NODE="$NODEPATH/node"
TSCFILE=$1 # only parameter is the name of the ts file you created.
function show_usage() {
echo "ts2node [ts file]"
exit 0
}
if [ "$TSCFILE" == "" ]
then
show_usage;
fi
JSFILE="$(echo $TSCFILE|cut -d"." -f 1).js"
$TSC $TSCFILE && $NODE $JSFILE
You can do this or write your own but essentially, it creates the .js file and then uses node to run it like so:
# tsrun myscript.ts
Simple. Just make sure your script only has one "." else you'll need to change your JSFILE in a different way than what I've shown.
Install ts-node node module globally.
Create node runtime configuration (for IDE) or use node in command line to run below file js file (The path is for windows, but you can do it for linux as well)
~\AppData\Roaming\npm\node_modules\ts-node\dist\bin.js
Give your ts file path as a command line argument.
Run Or Debug as you like.
Create your TypeScript file (ex. app.ts)
npm i -D typescript ts-node -> to install the dev dependencies local
npx nodemon app.ts
Using nodemon, automatically recompile app.ts every time you change the file
Here is the command
tsc index.ts --outDir .temp && node .temp/index.js && rm -rf .temp
<<<<<<<<< Compile >>>>>>>>> <<<<<<< Run >>>>>>> << Clean >>
There is also an option to run code directly from the CLI, not the *.ts file itself.
It's perfectly described in the ts-node manual.
As a first step, install ts-node globally via npm, yarn, or whatever you like.
...and now just use ts-node -e 'console.log("Hello, world!")' (you may also add the -p flag for printing code)
This little command is perfect for checking, does everything installed fine. And for finding some other error, relevant with tsconfig.json options.
We can run it using nodemon as well
nodemon ./filepath/filename.ts
This question was posted in 2015. In 2018, node recognizes both .js and .ts. So, running node file.ts will also run.

Resources