Intellij won't automatically resolve npm local dependencies - node.js

In my project for some reasons i'm using local npm dependencies like such in my package.json
{
"name": "my-super-project",
"version": "1.0.0",
"dependencies": {
...
"my-other-project": "file:../my-other-project",
},
"devDependencies": {
...
},
}
All the building and serving part works all fine though during development, there is no autocompletion suggested by IntelliJ in fact, it may suggest the import but really hidden under the More actions...
No direct suggestion
then when i click on it i have the suggestion i want.
Question being, why doesn't Intellij resolve my local dependencies as all other npm modules and suggest the import directly and how to possibly work around this or fix it ?
This is bringing confusion to the team when someone creates an element and someone else tries to importing, you have to write the exact name without Typo for intellij to suggest the appropriate import 3 clicks away within the usually unused because farfetched "more options".
I have tried digging through Settings > Editor > General > Code Completion & Postfix Completion without success, if someone has an idea would be greatly appreciated

Related

Using type-checker ESLint rules with a Nx monorepo

I am trying to use the rule "#typescript-eslint/naming-convention".
My understanding is that this rule requires linting with type information, described here: https://typescript-eslint.io/docs/linting/type-linting/
When trying to use 'plugin:#typescript-eslint/recommended-requiring-type-checking' I then get the following error:
You have used a rule which requires parserServices to be generated. You must therefore provide a value for the "parserOptions.project" property for #typescript-eslint/parser.
However I cannot see how parserOptions.project this should work when using a Nx monorepo.
In the monorepo, there is a variety of different files created for each project. At the top level there is a tsconfig.base.json, then each project has a tsconfig.json, and its own .eslintrc.json. I have tried a variety of combinations (including some great advice here) but I haven't managed to get anything working yet.
If changes to individual project files are required, I could add some custom generator logic, but ideally I'd work with global rules.
Also searching GitHub doesn't bring up any example repositories either.
Q: May anyone advise me how to use TypeScript linter rules which require type information with a Nx monorepo?
So it looks like you can use
"parserOptions": {
"project": ["./tsconfig.base.json"]
},
with Nx and that seems to work at the top level, meaning that you shouldn't need to edit individual .eslintrc files for each project.
You do also need to just apply the "parserOptions" and the "extends": ["plugin:#typescript-eslint/recommended-requiring-type-checking"] within the "overrides" array, just for TypeScript files only, as described in this answer: "parserOptions.project" has been set for #typescript-eslint/parser.
This was actually enough to get me working, running nx lint from the command line... my problem was that I also have an issue with WebStorm settings on top of all this too, which was obscuring things further. It might be this open issue, https://youtrack.jetbrains.com/issue/WEB-47201, but that is really a completely different question... my original question is answered.

NodeJS import file with the same name as a folder

I have the following file structure: ([] are folders)
[MySQL]
ConnectionPool.ts
Connection.ts
MySQL.ts
In my code, I am using typescript to develop the app, which will be built to javascript for the production version. The development version is tested directly from the uncompiled typescript files, using babel with the following configurations:
{
"presets": [
["#babel/preset-env", {
"targets": {
"node": "current"
}
}],
"#babel/preset-typescript"
],
"plugins": [
"#babel/plugin-transform-runtime",
[
"module-resolver",
{
"alias": {
... list of some aliases
}
}
]
]
}
My problem is the following, I do most of my imports like this:
import ConnectionPool from 'MySQL/ConnectionPool`
which works for me, as when I run my dev code, the compiler correctly identifies the file extension to .ts, and it also correctly identifies the built versions file extension to .js.
But if I want to import my MySQL.ts file, I can't do it this way, as I will get the following error: Error: Cannot find module './'. If I specify in my import statement the file extension, everything works correctly, but then, when I build my code, there will be no more .ts files in there, so I will get errors there.
Strangely, on the frontend, where I use webpack, I get no complaints about importing files without extension whose name is the same as a folders name in the same directory. What solutions do I have for this issue, which does not revolve around renaming my files or folders in the structure?
Rename your file MySQL.ts to index.ts and move it into the folder MySQL
In the meantime, I resolved my problem by explicitly specifying .ts as the file extension, and when building the code, using the babel-plugin-transform-rename-import to replace the .ts extensions to .js extension.
I won't accept this as the correct answer, as this is too hacky for me, so if a better solution comes up, I am still open for it.
I don't believe what you want to do is possible, node will automatically include either the file or the directory but if both of them are called the same thing node will have no idea which one to import and it will always prefer one over the other.
Using import Example from 'example' will have node search either for any files called example.js or directories called example with an index.js and it will only load one of them.
The reason webpack does it correctly is because webpack will never bundle a "directory", it will take what you've specified as an import and try all of the resolves extensions until it finds one and then it will import that file, so you'll never have conflicting files with directories with webpack.
I thought maybe a solution is to use aliasing in your typescript config so that you can use import Example from '#example' and differentiate between your directories and files that way. Then you can also do import Example from 'example' if you just want to load the file itself. But even then I don't think that will even work because once it gets compiled to javascript you'll just have the same issue as before with conflicting paths.
That being said, while I understand being a little bit obsessed with naming conventions and small things, I really don't think you should be storing "mysql" outside of the "mysql" directory, for two reasons. The first reason is that it's part of that directory, that's what that directory is for, it contains the "mysql" stuff, so why would you want to store it outside. Secondly using a "index.ts" communicates something to other developers, when I open up a new project or directory I'm immediately looking for something called "index.ts" or similar, otherwise I have no idea where to even begin. Using "index.ts" is a good way to communicate to anyone that "this file right here is the one you're looking for, everything starts here". That being said, just call it index.ts and store it where it belongs.
You can try in your tsconfig.json to set moduleResolution to the classic strategy:
{
"compilerOptions": {
"moduleResolution": "classic"
}
}
Unfortunately, looking at the code, this seems to be impossible in your setup:
import is handled by module-resolver
module-resolver calls the NPM package resolve
resolve.sync checks for the no-extension case before testing extensions.
Given that most systems are going to follow Node module resolution, I think you're out of luck, without some manual aliases or moving files around.
FWIW, NodeJS says that extensions in import are mandatory.

How to update typescript typings

Will somebody please help me understand how to update typings via the typings.json?
When I update certain libraries, their typings become deprecated. This is all well and good, but running typings install --save or any combination of typings install with any of my given libraries throws errors a-la "unable to find angular-protractor", etc.
The problem is that I can't understand how you're supposed to derive the version number. I understand that it is derived from the timestamp of the commit or whatever, but that seems like a terrible way to try to update something as simple as a typing. Particularly since, the only way I've found to be able to upgrade them, is find them and update typings.json manually.
For example:
{
"globalDependencies": {
"angular-protractor": "registry:dt/angular-protractor#1.5.0+20160425143459",
}
}
So, version 1.5.0+20160425143459 is deprecated, but I have no idea what the new one is since it won't tell me, and the angular-protractor definition on github in the definitely typed repo doesn't seem to provide any info past the major/minor/patch.
I'm sure I'm missing something simple. Thanks for any help.

Groovy and IntelliJ - getting code compiled

I have IntelliJ 12 and some groovy code (along with a pile of java code) in a project.
In intelliJ, i can see class A's import of some groovy code, and i have also included the library that has that code.
However, while the package itself is in one colour (for the import), the actual class being imported is in red, which implies an issue of some sort. Hovering the mouse over it reveals no issue though.
When i run a "make" or a "rebuild project" is where the problems start - i get
Groovyc: unable to resolve class com.blah.blah.blah.A
How can i resolve this?
Currently, my project setup is like so:
Under "Libraries" in (Project Structure -> Project Settings -> Libraries) I have:
the jar file with all the groovy code
the src jar file with all the groovy code
In the "Modules" section i have the - well, i don't know what to call it, the column isn't labelled - the library name from the libraries section associated with the src and class files, and the little "export" button beside it is ticked.
Incidentally, opening the class in intelliJ never shows the source code, which given the source is included struck me as weird.
Is there anything else I should need to do?
I've worked this one out, but if anybody knows why groovy cannot be in the "Resource Patterns" list and wants an upvote, do chime in
Oh, right.
I removed the !?*.groovy entry from the list of, um, entries in the File : Settings -> Compiler -> Resource Patterns thingy.
It doesn't seem to matter if "use external build" is on or off for this, but the !?*.groovy; entry cannot be there.
I wonder if anybody knows why?
I had the same problem and had to Add Framework Support and add Groovy to the project to get round this problem.
I created the project using gradle.
I just got your question in my Google results as I had a similar issue. My problem was that I was able to get the groovy code in my IntelliJ 12 project to compile ok, but it wasn't getting wired in properly when I tried to run unit tests within the IDE.
After some investigation, I uncovered that groovy and logback libraries were all set up in the project to be available in the runtime stage of the Maven build of the project, but that resulted in them not being available in the test stage. To fix this, I ended up manually updating the groovy-all and the logback libraries scope from runtime to provided under File->Project Structure->Modules->Dependencies. This allowed me to both compile and test within the IDE while including the Groovy modules as well as the Java modules.
Perhaps you had something similar going on in your project?
Six years later, I also just got this question near the top of my search results.
In my project my Unable to load class 'groovy.text.SimpleTemplateEngine' problem was actually due to a codenarc issue. I was able to resolve the issue by adding the following to build.gradle:
// codenarc version issue work-around
configurations.codenarc {
resolutionStrategy.eachDependency { DependencyResolveDetails d ->
if (d.requested.group == 'org.codehaus.groovy') {
d.useVersion '2.4.7'
}
}
}

npm package.json OS specific dependency

Is there a way to specify OS specific dependencies in a npm package.json file?
For example, I would only want to install 'dbus' (https://npmjs.org/package/dbus) as a dependency for my module if the user is running Linux. I would have a different dependency for Mac and Windows.
There's a possible good way of doing this, depending on your setup.
npm package.json supports an os key,
and also optionalDependencies
os can be used to specify which OS a module can be installed on.
optionalDependencies are module dependencies that if they cannot be installed, npm skips them and continues installing.
In this way you can have your module have an optional dependency for each OS, and only the one which works will be loaded/installed ^.^
EDIT: As #Sebastien mentions below, this approach is dangerous.
For any given OS, at least one of your dependencies is "required" and the rest "optional". Making all versions of the dependency optional means that if your installation fails for a legitimate reason, it will silently skip installation and you will be missing a dependency you really need.
I think the short answer is no. I can think of a couple of workarounds though - the simplest is to just add everything to package.json regardless of OS, and then require() the correct one at runtime.
If that doesn't work for you, you might be able to use an install script to get the result you're going for - https://docs.npmjs.com/misc/scripts
I haven't tested this but I think it would work:
Add something like this to your package.json:
,"scripts": {
"install": "node install_dependencies.js"
}
And then add a install_dependencies.js file that checks the OS and runs the appropriate npm install ... commands.
There's also the bindings-shyp module:
https://www.npmjs.com/package/bindings-shyp
Helper module for loading your native module's .node file
This is a helper module for authors of Node.js native addon modules. It is basically the "swiss army knife" of require()ing your native module's .node file.
Throughout the course of Node's native addon history, addons have ended up being compiled in a variety of different places, depending on which build tool and which version of node was used. To make matters worse, now the gyp build tool can produce either a Release or Debug build, each being built into different locations.
This module checks all the possible locations that a native addon would be built at, and returns the first one that loads successfully.
Quoting #npm_support at:
https://twitter.com/npm_support/status/968195526989512705
2/2 If you'd like to avoid installation problems related to dependencies, one route is for you to write a wrapper that's required as a regular dependency, and to make sure that it has optionalDeps (and also ensure that the wrapper verifies you have everything needed to work).
But IMHO it looks more like a workaround than solving the problem for real.
I can understand that npm wants to preserve portability and avoid to deal with platform specifics, but it has to be done anyway and IMHO doing this at runtime is not optimal (specialty if one wants do optimize code size).
So today I have no optimal solution to share but an open discussion for proposal.
Can't "conditional dependencies" be supported in npm ?
The 1st thing that came to my mind was to to add a "override" section that will change (+add, -remove, =replace) current parsed sections.
For example:
dependencies: { "common-stuff": "*" }
overrides: {
"os: { linux: { dependencies: { "+best-linux-module" } } }
}
And other option suggested by a developer I know, would be to introduce a provides keyword, then several modules could provide a same semantic than would be satisfied by resolver (a la debian), but it's generating similar overhead.
I am looking for a generic approach not only focused on OS support but also on other flavors of package (depending on engines for instance).
Do you know any related issue in NPM tracker ? if not I am considering to file a bug to be tracked at:
https://github.com/npm/npm/issues?q=dependencies+conditional
Feedback welcome on this idea.

Resources