When installed globally, my node app looks in the global node_modules folder - node.js

I'm making an app to generate a component structure for a client project. The app needs to be run from the command line and so I've made it a published npm app that can be installed globally, however when I run the app, it's ignoring the directory I'm trying to run it from and instead just looking in it's own node_modules directory (I've tried this under nvm and regularly installed node)
I'm trying to set the project root using the following: var projectRoot = path.dirname(require.main.filename)
I've also tried by using __dirname, which also failed to work.
The specific problem I'm trying to solve (although this is only the first of a few, all of which seem to be caused by the app looking in the wrong place) is that the app needs to find a config file before it will run. I've included the example code for this below:
fs.stat(path.join(projectRoot, '/clarity.yml'), function (err, stat) {
if (err === null) {
console.log(chalk.green('clarity.yml detected!\nLoading your preferences...\n\n'))
config = yml.safeLoad(fs.readFileSync(path.join(projectRoot, '/clarity.yml'), 'utf8'))
questionTime()
} else if (err.code === 'ENOENT') {
console.error(chalk.red('clarity.yml not found. Please add one to the root of your project. A template can be found at https://git.io/v5Tt2 \nProcess aborted with errors'))
process.exit(1)
}
})
The most annoying part is that when I made this about a year ago, it worked without issue, however, I was running node v4.4.5 then and now I am using v8.0.0 (I've also tried it on v6.0.0 and v7.0.0 with the same result).

Related

Tailing a file with node-tail in a Vue/Vite/Electron application

I'm want to play around with building desktop applications using Electron and Vue.
Now I got an idea where I want to tail a local .txt file using node-tail, and store these changes somewhere. I saw this app also doing this, so I thought I would be able to do something similar within a Vue/Electron app.
With everything installed and trying to run this code with yarn electron:dev:
import { Tail } from 'tail';
let tail = new Tail("C:/logs/somelog.txt");
tail.on("line", function(data) {
console.log(data);
});
tail.on("error", function(error) {
console.log('ERROR: ', error);
});
I get this error:
Uncaught TypeError: Class extends value undefined is not a constructor or null
I did some searching on the error, and most of the results said removing your node_modules folder and npm i again could help, but this didn't do the trick.
Also I saw someone comment that these problems might happen if you mix yarn and npm. Now I did install everything at first using yarn and then the node-tail package using npm. This person said the same about removing and installing again. But this doesn't work for me.

How does this nodejs project reference a shared library folder?

I'm looking at this project and they have multiple node projects like:
api
project2
project3
shared
So the various projects reference the shared folder like:
if (process.env.NODE_ENV === 'development') {
const logging = require('shared/middlewares/logging');
middlewares.use(logging);
}
https://github.com/withspectrum/spectrum/blob/alpha/api/routes/middlewares/index.js#L6
And the logging.js file is in the shared folder:
// #flow
// Log requests with debug
const debug = require('debug')('shared:middlewares:logging');
module.exports = (
req: express$Request,
res: express$Response,
next: express$NextFunction
) => {
debug(`requesting ${req.url}`);
next();
So I tried to do something similiar in my node/express project but I am getting this error:
This dependency was not found:
* shared/middlewares/logging in ./src/middlewares/index.js
To install it, you can run: npm install --save shared/middlewares/logging
Is there something they did in their project to allow this to work?
Naturally you have to show relative path for "require()" if you use your own modules, e.g.
require('./path/to/custom/module/file')
// In this case smth like
require('../../../shared/middlewares/logging')
If you do not use relative path, it will search for installed package, and that's why you got an error with suggestion to install because it's not found.
There are several ways to tell node to search package in custom directory. You can check this link for examples. In "spectrum" project it's configured by setting up NODE_PATH environment variable, you can see it here and here
At those lines you can see NODE_PATH=./, which tells node to look for packages in the root directory.
That's it, hope now it's clear :)

Sharing code between React Native + Node

I am using React Native and Node.js. I want to share code between the two. My folder structure is as so.
myreactnativeapp/
mynodeserver/
myshared/
In the react native and node apps I have included the
package.json
"dpendencies" : {
"myshared": "git+https://myrepository/ugoshared.git"
}
This can then be included in each project via require/import etc. This all works fine and for production I'm happy with it. (Though I'd love to know a better way?)
The issue I'm facing is in development it's really slow.
The steps for a change to populate are:
Make changes in Shared
Commit Changes to git
Update the npm module
In development, I really want the same codebase to be used rather than this long update process. I tried the following:
Adding a symlink in node_models/shared - doesn't work in react-native package mangaer
Using relative paths ../../../shared - doesn't work in react-native package mangaer
Any other ideas?
Update 1
I created a script.sh which I run to copy the files into a local directory before the package manager starts. It's not ideal but at least I only have to restart the packager instead of messing with git etc.
#myreactnativeapp/start.sh
SOURCE=../myshared
MODULE=myshared
rm -rf ./$MODULE
mkdir ./$MODULE
find $SOURCE -maxdepth 1 -name \*.js -exec cp -v {} "./$MODULE/" \;
# create the package.json
echo '{ "name": "'$MODULE'" }' > ./$MODULE/package.json
# start the packager
node node_modules/react-native/local-cli/cli.js start
Then in my package.json I update the script to
"scripts": {
"start": "./start.sh",
},
So, the process is now.
Make a change
Start/Resetart the packager
Automatic:
Script copies all .js files under myshared/ -> myreactnativeapp/myshared/
Script creates a package.json with the name of the module
Because I've added the package.json to the copied files with the name of the module, in my project I can just include the items the same as I would if the module was included via the package manager above. In theory when I switch to using the package in production I wont have to change anything.
Import MyModule from 'myshared/MyModule'
Update 2
My first idea got tiresome restarting the package manager all the time. Instead i created a small node script in the shared directory to watch for changes. Whenever there is a change it copies it to the react native working directory.
var watch = require('node-watch')
var fs = require('fs')
var path = require('path')
let targetPath = '../reactnativeapp/myshared/'
watch('.', { recursive: false, filter: /\.js$/ }, function(evt, name) {
console.log('File changed: '+name+path.basename(__filename))
// don't copy this file
if(path.basename(__filename) === name) {
return
}
console.log(`Copying file: ${name} --> ${targetPath+name}`);
fs.copyFile(name, targetPath+name, err => {
if(err) {
console.log('Error:', err)
return;
}
console.log('Success');
})
});
console.log(`Starting to watch: ${__dirname}. All files to be copied to: ${targetPath}`)

Creating directory at wrong place after packaging Electron

Electron version: 0.37.5
Operating system: Ubuntu 15.10
I packaged my project using electron-packager. Normally, I create a directory named downloads in application directory where my main.js file exists. After packaging, I have locales and resources directories along with other files, and inside resources directory, there is another named app and there's also electron.asar file. Inside app folder there are my project files.
When I run the executable, it creates the directory at the same location, instead of creating it under /resources/app/. How can I fix this problem?
My createDirectories function:
// create directory if it does not exist
function createDirectory(directory, callback) {
Fs.mkdirs(directory, function (err) {
if (err) {
console.error(err);
} else {
return callback();
}
})
}
I give downloads/images/ as a parameter to this function, for example. Fs.mkdirs is a method of fs-extra module.
My directory parameter is downloads/images/ and downloads/videos/
Writing app data to the application installation directory is generally a bad idea since the user running the app may not have permission to write files to the application installation directory. What you should probably do instead is store whatever your application downloads at the location returned by app.getPath('userData').

Why can node not find my module?

I am using node v0.12.5 with nwjs and I have defined my own custom module inside of my project so that I can modularise my project (obviously).
I am trying to call my module from another module in my project but every time I attempt to require it I get the error could not find module 'uploader'.
My uploader module is currently very simple and looks like:
function ping_server(dns, cb) {
require('dns').lookup(dns, function(err) {
if (err && err.code == "ENOTFOUND") {
cb(false);
} else {
cb(true);
}
})
}
function upload_files()
{
}
module.exports.ping_server = ping_server;
module.exports.upload_files = upload_files;
With the idea that it will be used to recursively push files to a requested server if it can be pinged when the test device has internet connection.
I believe I have exported the methods correctly here using the module.exports syntax, I then try to include this module in my test.js file by using:
var uploader = require('uploader');
I also tried
var uploader = require('uploader.js');
But I believe node will automatically look for uploader.js if uploader is specified.
The file hierarchy for my app is as follows:
package.json
public
|-> lib
|-> test.js
|-> uploader.js
|-> css
|-> img
The only thing I am thinking, is that I heard node will try and source the node_modules folder which is to be included at the root directory of the application, could this be what is causing node not to find it? If not, why can node not see my file from test.js given they exist in the same directory?
UPDATE Sorry for the confusion, I have also tried using require('./uploader') and I am still getting the error: Uncaught Error: Cannot find module './uploader'.
UPDATE 2 I am normally completely against using images to convey code problems on SO, but I think this will significantly help the question:
It's clear here that test.js and uploader.js reside in the same location
When you don't pass a path (relative or absolute) to require(), it does a module lookup for the name passed in.
Change your require('uploader') to require('./uploader') or require(__dirname + '/uploader').
To load a local module (ie not one from node_modules) you need to prefix the path with ./. https://nodejs.org/api/modules.html#modules_modules
So in your case it would be var uploader = require('./uploader');
This problem stemmed from using Node Webkit instead of straight Node, as stated in their documentation all modules will be source from a node_modules directory at the root of the project.
Any internal non C++ libraries should be placed in the node_modules directory in order for Node webkit to find them.
Therefore to fix, I simply added a node_modules directory at the root of my project (outside of app and public) and placed the uploader.js file inside of there. Now when I call require('uploader') it works as expected.
If you're developing on a mac, check your file system case sensitivity. It could be that the required filename is capitalized wrong.

Resources