"Module not found: Error: Can't resolve" using Local Paths - node.js

I'm trying to use npm's "local paths" feature but I'm getting the error:
ERROR in ./src/pixi-environment/src/pixi-environment.js Module not
found: Error: Can't resolve 'pixi.js' in
'/Users/michaelosofsky/Developer/develop/locuslabs-js-sdk/src/pixi-environment/src'
I think I've set it all up correctly by following https://stackoverflow.com/a/14387210/2848676 and https://stackoverflow.com/a/42430086/2848676:
The local path relative to my project is ../../pixi.js_prerelease
From my project directory I installed with the command npm install --save ~/Developer/pixi.js_prerelease
My project's package.json got automatically updated with a dependency "pixi.js": "file:../../pixi.js_prerelease",
My project's node_modules directory automatically got a subdirectory called pixi.js created and it contains the files from ~/Developer/pixi.js_prerelease
The file that imports pixi.js does it like this:
const PIXI = require('pixi.js')
I also tried these approaches:
const PIXI = require('./node_modules/pixi.js/pixi.js')
const PIXI = require('./node_modules/pixi.js')
const PIXI = require('../../../node_modules/pixi.js/pixi.js')
const PIXI = require('../../../node_modules/pixi.js')
const PIXI = require('~/Developer/pixi.js_prerelease/pixi.js')
const PIXI = require('~/Developer/pixi.js_prerelease')
const PIXI = require('/Users/michaelosofsky/Developer/pixi.js_prerelease/pixi.js')
const PIXI = require('/Users/michaelosofsky/Developer/pixi.js_prerelease')
However, when I do npm test in my project's directory I get the error above.

Related

Import Dynamic ts File Into Project A from Project B

I have two Node based typescript projects A and B. Can I dynamically import a ts file into project A that resides in project B?
It's straight forward to dynamically import a file if it's local to the project e.g.
const myImport = await import('./my');
But as soon as I try to import a file that exists outside the Project A tsconfig rootDir I get an error:
const myImport = await import('c:/projectB/my.ts');
// Error: Cannot use import statement outside a module
If I don't specify the .ts extension I get error:
Error: Cannot find module.
Using require instead of import results in the same errors:
const myImport = require('c://projectB/my.ts');
// Error: Cannot use import statement outside a module
The typescript code across both projects is commonjs.
I'm trying to create a simple plugin architecture where ProjectA imports a plugin.ts file from ProjectB (with types). In old posts, people suggest copying files or creating symlinks. However, I'd like to publish project A as an NPM package so I don't think this approach will work.
Changing the path to point to the transpiled .js file (instead of the .ts) worked. The class can be instantiated successfully. Intellisense works the same as if the class was a local import. Note that my transpiled .js files are in a different folder than my source .ts files (in case that makes a difference).
const myImport = await import('c:/projectB/my'); // Note that no file extension is specified.
const myImportClass = new myImport();
myImportClass.myMethod();
The example above uses a hard coded absolute path for testing only. This might result in error: File is not under 'rootDir'. Simply work around this by using a variable e.g.
const myPath = 'c:/projectB/my';
const myImport = await import(myPath);
In my production code I'm using the following dynamic path:
const myPath = path.join(process.cwd(), myPath, myFileName);

How to get the root of project which installed my npm module?

I am developing an NPM package. Now I want to know the easiest way to get the root of the project which utilizes my custom package.
Within my package itself it is pretty easy to get the root in node.js like so:
__dirname
This points to the root of my package itself though. I would like to get the root of the project which actually performed the npm install of my package though.
Obviously, I could simply go up from the node_modules directory and assume that the root directory is there but this sounds really bad.
Is there a standard way to achieve this?
you could use app-root-path which is an npm module and its pretty neat.
npm i -S app-root-path
after that just do
var reqlib = require('app-root-path').require;
var myModule = reqlib('/lib/my-module.js');
You can use the info from: require.main
The Module object representing the entry script loaded when the
Node.js process launched. See "Accessing the main module".
const path = require('path');
console.log(path.dirname(require.main.filename));
Having this folder structure:
/app
entry.js
node_modules/
my-package/
index.js
app/entry.js
const myPackage = require('my-package');
app/node_modules/my-package/index.js
const path = require('path');
console.log(path.dirname(require.main.filename));
And when you call: node entry.js
You will get: /app printed to stdout.
KISS
const fullPath = path.dirname(require.main.filename);
const regexResp = /^(.*?)node_modules/.exec(fullPath);
const appRoot = regexResp ? regexResp[1] : fullPath;
console.log(appRoot); // outputs the directory which is the root of this project

Working when run, but not when built

Im on macOS. I am creating a simple electron app. When I run the app with electron . everything works perfectly with no errors. Now that my app is finished, I wanted to build and distribute it. So I setup electron-builder and I got that to work just fine. However, when I run the MyApp.app in the build folder, I get an error saying:
Uncaught Error: ENOENT: no such file or directory, scandir './img/'
I call scandir here:
const fs = require('fs');
var files = [];
fs.readdirSync("./img/").forEach(file => {
files.push(file);
})
Why is this working when I run it with node, but is not working in the build? How can I fix this issue?
Why is this working when I run it with node, but is not working in the
build? How can I fix this issue?
It's difficult to tell without having more information about the whole app's structure, it may depend on how your code is actually called or required from the html file.
Anyway, using the __dirname global variable to build the directory path usually solves this kind of problem. Please try:
const fs = require('fs');
const path = require('path');
var files = [];
fs.readdirSync(path.join(__dirname, 'img')).forEach(file => {
files.push(file);
});

node.js on heroku: Error: Cannot find module 'csv'

I'm using a common node package 'csv' to do CSV parsing. It works great on my local mac, but not on heroku. In the "heroku log", I get Cannot find module 'csv'.
Yes, I have it in my package json file:
{
"name":"rimes",
"version":"0.0.1",
"dependencies":{
"sys":"",
"url":"",
"http":"",
"querystring":"",
"oauth":"0.9.10",
"fs":"",
"csv":"0.3.0",
"request":"",
"node-cache":"",
"underscore":""
}
}
and I require it in my app.js
var sys = require('sys'),
http = require('http'),
url = require('url'),
qs = require('querystring'),
OAuth= require('oauth').OAuth,
fs = require('fs'),
csv = require('csv'),
myreq = require('request'),
NodeCache = require('node-cache'),
us = require('underscore');
What can I do to fix this on heroku?
Thank you,
~Todd
So when you require packages on node, you also need to install them in your node_modules folder. They must be in the node_modules folder as well as "required" in your code. They can only be declared in your "package.json."
If you go into your project directory (the file where package.json is located) and run:
npm install
it should install your missing dependencies into your 'node_modules' folder.
Then if you re-deploy your app to heroku it should work.

Require dependency of another dependency in node modules

I've got a simple node app that has single dependency on another app on github. The dependency installs just fine with npm install, but when I try to require something installed there, it says it's not available. For example, the github app installs Mongoose as a dependency. I thought that this parent app would be able to access that module since it is in a child:
var mongoose = require('mongoose')
The structure looks something like this:
/app
/node_modules
/github_dependency [parent module]
/node_modules
/mongoose [child module]
Do I just have to include mongoose as a dependency as well in the parent app or is there a way of getting access to that module by way of the child?
Do I just have to include mongoose as a dependency as well in the parent app or is there a way of getting access to that module by way of the child?
While it's possible for you to e.g. require('github/node_modules/mongoose'), the standard practice is to install all of your dependencies explicitly (i.e., you should include mongoose as a dependency of your app) and require('mongoose').
For a more robust case, which is good in situations such as testing, you can use the following function:
var Module = require('module');
var path = require('path');
function requireFrom(self, parent, name) {
var pPath = Module._resolveFilename(parent, self);
var m = new Module(pPath, module);
m.filename = pPath;
m.paths = Module._nodeModulePaths(path.dirname(pPath));
return m.require(name);
}
which can be used as follows
requireFrom(module, 'github_dependency', 'mongoose')

Resources