1

I have bunch of JavaScript functions, all loaded in memory and I need to validate their syntax before I write them down in .js files.

The code that I have is in python and need to check the validity of js functions on the fly. So, looking for a python package that could perform this task for me.

JSHint works OK if I write each function in a file and then call something like os.system("jshint --verbose sample.js"), but writing the js functions in file is expensive and takes a lot of time.

I was wondering if there is any way that I could call JSHint directly in python.

In addition, I can get what I need if it was possible to call JSHint in command line directly with the code, not its address. In other words, if I could pass the actual script jshint "var source = ['function goo() {}', 'foo = 3;' ];", instead of its address like jshint sample.js, I could get what I need.

Afshin Oroojlooy
  • 1,326
  • 3
  • 21
  • 43
  • 1
    "I was wondering if there is any way that I could call JSHint directly in python." You already have the best way - `os.system()`. There aren't commonly tools to manipulate JS ASTs in Python, these tools are normally written in JS (because the programmer is familiar with JS) or Rust (because Rust is fast). BTW for linting JS, JShint isn't so popular now - most people would use a tool like `prettier` now. It's the equivalent of Python's `black`. – mikemaccana Jun 16 '23 at 13:43
  • Couldn't you use a node.js script to validate the script? – Mr. Polywhirl Jun 16 '23 at 13:45
  • @mikemaccana ESlint is actually a linter that everyone in the JS community is familiar with. Prettier is typically used as formatter and works on top of ESlint. – Mr. Polywhirl Jun 16 '23 at 13:47
  • @Mr.Polywhirl, I have bunch of those JS file which are loaded as text, the python code does bunch of preprocessing and post-processing on them. I am not sure if it is possible to move all those steps to node.js. – Afshin Oroojlooy Jun 16 '23 at 13:57
  • @mikemaccana Do you if `prettier` is callable from command line? – Afshin Oroojlooy Jun 16 '23 at 14:00
  • 1
    If you have Node installed, you can globally install `prettier` via: `npm install -g prettier`. Now you can run `prettier` at any time in your terminal. Global node package installations are added to your executable path. – Mr. Polywhirl Jun 16 '23 at 14:23
  • @Mr.Polywhirl Yes, I've used eslint since it existed, and I've written ESlint plugins you might use. The reason I mention prettier is that is what people call from the command line. – mikemaccana Jun 16 '23 at 14:24
  • 1
    @AfshinOroojlooy yes. `npx prettier` will run `prettier` after you've installed it into your project with `npm i prettier`. – mikemaccana Jun 16 '23 at 14:25
  • @mikemaccana Thanks for the info. I installed `prettier`, and checked some file. Does it needs any configuration? I have a JS file with missing `;`, which I call `prettier --check sample.js`, it returns `[warn] Code style issues found in the above file. Forgot to run Prettier?`. Should not it return an error complaining about semicolon? – Afshin Oroojlooy Jun 16 '23 at 16:15
  • @AfshinOroojlooy `prettier --write` - see https://prettier.io/docs/en/cli.html – mikemaccana Jun 16 '23 at 16:16
  • @mikemaccana `--write` fixes the issues, I need to know the issue as well. – Afshin Oroojlooy Jun 16 '23 at 16:19
  • @AfshinOroojlooy BTW if you did want to run prettier without writing to disk first, you could make a JS app using the prettier API https://prettier.io/docs/en/api.html#prettierformatsource-options but you'd have to get the string from Python to JS and that's really difficult. You'd probably end up rewriting your whole program in JS. Unless writing to disk is killing your performance just write to disk. – mikemaccana Jun 16 '23 at 16:19
  • @mikemaccana, Besides, is there any way that I could pass the JS code to its API, instead of the address of the file, like: `prettier --check "var source = ['function goo() {}', 'foo = 3;' ];"` – Afshin Oroojlooy Jun 16 '23 at 16:20
  • Yes. See my previous comment. – mikemaccana Jun 16 '23 at 16:21
  • @mikemaccana Thanks, as you explained it seems that it is not easy to use `format`. – Afshin Oroojlooy Jun 16 '23 at 16:35
  • 1
    @AfshinOroojlooy it's not so much prettier being hard to use, it's that all programs in one language (or language VM) are hard to use from other languages. So you have a JS file as a Python string? OK prettier works on strings, but you have to get the Python string into JavaScript memory to become a JS string - which is the super hard part. Better to just write out the file to disk. – mikemaccana Jun 18 '23 at 18:41

1 Answers1

1

You should be piping the input to whatever linter you decide to use.

See this answer on piping input to another program from Python.

Regarding your specific use case, JSHint reads from stdin when the filename passed is '-'

The following should work:

import subprocess
code = "function goo() {}"
result = subprocess.run("jshint --verbose -".split(), capture_output=True, text=True, input=code).stdout
luigig44
  • 417
  • 1
  • 3
  • 10