Setting NODE_PATH from within NodeJS application - node.js

We have a node project that does not require our own submodules from a relative path, but instead needs the NODE_PATH environment variable be set to lib to find all submodules.
I wanted to handle this standard case within the program source code but it seems like it is impossible by now.
I found several solutions which all do not work as expected.
module.paths.push("./lib");
Was suggested in another stackoverflow article but this causes an error message in the newer Node versions and refers the developer to using NODE_PATH.
Instead I tried to do the following as the very first line of my program.
process.env['NODE_PATH']="./lib";
This does not cause an error message but it does not work either. I think that this variable is read on the application start and not read lateron when requiering stuff.

All information you can find out from the source: module.js
... NODE_PATH error is thrown only when accessing via require.paths.
Search for _nodeModulePaths function: Module instance has generic Array object paths, with all lookup paths in it.
module.paths.unshift('./foo-baz');
var x = require('some-lib-name');
console.log(x);
So now, if you have the required module under ./foo-baz/some-lib-name/ it would be properly picked up.
What node version and what system you have?

Related

How can I make vscode assume a node.js context, so that it doesn't assume `fetch` exists?

By default, when editing a JavaScript file in VSCode, it will assume that the fetch function and related types exist in the current context. This makes sense for JavaScript designed to run in the browser, but when running on node.js the fetch function does not exist unless it is installed via node-fetch. I find that in this context, VSCode is misleading, as it will not highlight an error when you trying calling the fetch function, or access other types such as Request and Response, even though they do not exist unless you have node-fetch installed.
How can I configure vscode to assume a node.js context, and therefore assume that fetch does not exist unless I explicitly import it from node-fetch?
Why web types are there by default
From the docs for tsconfig.json compilerOptions.lib:
TypeScript includes a default set of type definitions for built-in JS APIs (like Math), as well as type definitions for things found in browser environments (like document).
How to change the defaults
Create a tsconfig.json or jsconfig.json, and set the compilerOptions.lib array to not contain "DOM", which means that lib.dom.d.ts (the "DOM standard library" type definitions file that comes with TypeScript) will not be assumed. You should specify which ECMA Script standard you want to write your source code in.
The config file also has fields to control what files it takes effect on: files, include, and exclude. If you specify none of them, include will default to **, which matches everything beside and recursively under subdirectories beside the config file.
Having to create this file could be seen as annoying if you just want to write a single JS file (ie. now you have a whole config file just for one source file!). I don't know if there are alternatives that are more convenient for such a use case. If anyone knows, please edit this answer.
I looked briefly into TypeScript triple-slash directives, which allow specifying things on a per-file basis, but I think you can only add things (ie. I don't think you can use them to remove a lib).
At the time of this writing, there are VS Code settings that can be applied at the user-settings scope that affect settings for implicit projects (JS/TS files which don't have a project config file) (js/ts.implicitProjectConfig.*), but none of them are for setting the compileOptions.lib field, and my gut says it's probably not going to happen (but don't quote me on that).
You probably also want types for the Node API
Use npm to install a version of #types/node. Make sure the major version number of the version you install matches the major version number of the version of Node JS you want to script to be runnable on.
Fun irrelevant facts to this question
Continuing on the point about VS Code's user-settings for implicit projects, VS Code puts some defaults in effect (on top of those that TypeScript itself does) if no project is detected. You can poke through the code at github.dev/microsoft/vscode by doing "Find in Files", using extensions/typescript-language-features/**/* as the "files to include" field, and compilerOptions as the find query. compilerOptions.lib seems to not be something that VS Code touches in such a scenario.

Freeling Python API working on sample, get Import error on other code

I'm trying out Freeling's API for python. The installation and test were ok, they provide a sample.py file that works perfectly (I've played around a little bit with it and it works).
So I was trying to use it on some other python code I have, in a different folder (I'm kind of guessing this is a path issue), but whenever I import freeling (like it shows on the sample.py):
import freeling
FREELINGDIR = "/usr/local";
DATA = FREELINGDIR+"/share/freeling/";
LANG="es";
freeling.util_init_locale("default");
I get this error:
ModuleNotFoundError: No module named 'freeling'.
The sample.py is located on the ~/Freeling-4.0/APIs/Python/ folder, while my other file is located in ~/project/, I dont know if that can be an issue.
Thank you!
A simple solution is to have a copy of freeling.py in the same directory as your code, since python will look there.
A better solution is to either paste it in one of the locations where it usually checks (like the lib folder in its install directory), or to tell it that the path where your file is should be scanned for a module.
You can check out this question to see how it can be done on Windows. You are basically just setting the PYTHONPATH environment variable, and there will only be minor differences in how to do so for other OSes. This page gives instructions that should work on Linux systems.
I like this answer since it adds the path at runtime in the script itself, doesn't make persistent changes, and is largely independent of the underlying OS (apart from the fact that you need to use the appropriate module path of course).
You need to set PYTHONPATH so python can find the modules if they are not in the same folder.

In typescript, how to restrict a typing reference to a certain file?

I'm trying to cleanly write some universal javascript code, for node and browser.
Most of the code is env-agnostic, however, some implementation parts detect the environment (node or browser) and conditionally execute different code.
I would like to activate node typings ONLY for those specific files. However, I couldn't find a way to do so. Either:
node typings, when referenced in even one file only, are made effective for all files (bad, since I could inadvertently rely on node specificities)
if not referencing node typings at all, typescript obviously complains about a lot of unknown definitions, which would be painful to patch by hand
Do anyone has a clean way of activating some type definitions for a selected set of files ?
It's not possible at this time.
A solution: building node-dependant and node-independant files separately. This could be done automatically with a script.

Intellij IDEA resolve local require() path [ node.js ]

I'm trying to avoid relative require() calls in my express setup. I'd also like to avoid placing my code in the node_modules folder. In short, I'm trying to implement any of the methods described in this gist.
Any of those solutions will work fine for executing code with node or npm. However, I'm trying to find a solution that will also be supported by Intellij IDEA's code resolver, i.e. trying to make sure "go to declaration" and autocomplete hinting works.
I've tried the following
Setting NODE_PATH in the run configuration.
Using a global prefix, i.e. require( global.__base + "mylib").
Adding a symlinked folder to node_modules/.
Adding a symlink from a lib/ folder to node_modules/lib/ does work, but comes with two caveats:
Changes to the source files aren't picked up automatically, so I have to manually "synchronize" node_modules/lib, and
When "going to declaration", IntelliJ (of course) opens node_modules/lib/mylib instead of lib/mylib. This can lead to confusion as the actual file and the symlinked file can be open in separate windows.
Instead of a different way to require local paths (all these methods do work with node after all), I'd be happy with a way to hint to IDEA that it should search the lib/ folder for sources.
So, I realised that if you add a library through Project Structure > Libraries, it won't actually be enabled.
Instead, go to Preferences > Languages & Frameworks > Javascript > Libraries and add a new library. Set the framework type to node_modules, Visibility to Project and add your lib folder.
After adding it, make sure the Enabled checkbox is checked.
That's it, Intellij can now resolve your require('mylib') paths.
Use whatever method from the gist mentioned in the question to actually get node to resolve the paths.

Bringing in other local scripts with Component package manager?

I'm just getting started with Component package manager. I understand that I can require in other local modules by adding the module to the local key in the component.json file, but what if I don't want to treat every file as a module?
In the (very minimal) documentation for Component, it's developer TJ says that I can add any other relevant scripts (that live in the same directory) to the scripts array. And yet, on doing so, I'm unable to require or reference any of the peripheral scripts' methods from my main file.
The require method fails on trying to load in the script, and any attempt to reference the methods or variables from that script from the 'bootstrap' file are futile. My build.js shows that the script has been compiled in, but I just can't seem to figure out the correct way to reference it from other scripts...
Help?
I just thought I'd post the answer to this question so anybody with the same problem can find it quickly/painlessly.
The answer is to reference the script with a pointer to it's current directory like so:
var script = require('./script.js');
Note the ./ at the beginning of the file name.
An easy mistake to make/rectify.

Resources