how can VS code support Go to definition - node.js

I have two JavaScript files: config.js, app.js. In app.js I want to use function defined in config.js so I could use require().
config.js
module.exports = {
somefunc: somefunc
}
app.js
var config = require('./config')
But I don't want to input the './' every time so I add a myRequire.js file.
myRequire.js
global.myRequire = function (p){
return require('./' + p)
}
In that case I could use myRequire('config') next time instead of myRequire('./config'), which might looks more concise.
app.js
require("./myRequire")
var config = myRequire('config')
config.somefunc()
But I met a problem, that I cannot use F12(Go to Definition) in VS Code to find the somefunc function. So could someone tell me what should I do to make it work in this case?

You are introducing a lot more problem than what you are trying to achieve. What if you are requiring a file from different file path '../../here', './over/there'.
If you really want to require something without a path. You can create your own npm module so you can require it globally without paths OR you create a folder with index.js in it and you require all the things you need.

Related

How to call require for more files in one line?

I have a protractor test and I made helper js files for each functionality (E.g. login, createObject, logout).
These separate js files are called from Test.js (the spec file).
I want to make the require for all 3 methods in config.js, but in just one call, all my tests contain a lot of helpers/methods files.
I've tried this:
in config.js,
onPrepare: function () {
'use strict';
global.Methods = require ('./method1.js' , './method2.js' , './method3.js');
}
but it doesn't work.
Can anyone tell me if this is possible or if there is a better way to do it?
Thank you in advance.
Since the require function only takes one file as an parameter you can put all your methods into one file called actions. This way you only have to make one require call to gain access to all your methods.
global.Methods = require('./actions.js');
or even better
global.Methods = new (require('./actions.js'));
Or simply require one file at a time
global.Methods1 = require ('./method1.js');
global.Methods2 = require ('./method2.js');
global.Methods3 = require ('./method3.js');

require.main.require works but not inside Mocha test

I have written a global function for requiring certain files of my app/framework:
global.coRequireModel = function(name) {
// CRASH happens here
return require.main.require('./api/_co' + name + '/_co' + name + '.model');
}
This module is in /components/coGlobalFunctions.
It is required in my main app app.js like this:
require('./components/coGlobalFunctions');
Then in other modules using "something" from the framework I use:
var baseScheme = coRequireModel('Base');
This works but not in the Mocha tests which give me a "Error: Cannot find module" right before the require.main.require call.
It seems that the test is coming from another source folder. But I thought the require.main.require would take out the aspect of having to relatively linking to modules.
EDIT:
An example test file living in api/user:
var should = require('should');
var app = require('../../app');
var User = require('./user.model');
...
require.main points to the module that was run directly from node. So, if you run node app.js, then require.main will point to app.js. If, on the other hand, you ran it using mocha, then require.main will point to mocha. This is likely why your tests are failing.
See the node docs of more details.
Because require.main was not index.html in my node-webkit app when running mocha tests, it threw errors left and right about not being able to resolve modules. Hacky fix in my test-helper.js (required first thing in all tests) fixed it:
var path = require('path')
require.main.require = function (name) {
// navigate to main directory
var newPath = path.join(__dirname, '../', name)
return require(newPath)
}
This feels wrong, though it worked. Is there a better way to fix this? It's like combining some of the above solutions with #7 to get mocha testing working, but modifying main's require just to make everything work when testing feels really wrong.
For other avoid-the-".."-mess solutions, see here:
https://gist.github.com/branneman/8048520
This is pretty old, but here is my solution.
I needed a test harness module to be published to a private registry and required by the mocha test suite. I wanted the calling test code to pass the code under test to the harness rather than requiring it directly:
var harness = require('test-harness');
var codeUnderTest = harness('../myCode');
Inside harness (which was found in the project node_modules directory), I used the following code to make require find the correct file:
if (!path.isAbsolute(target)) {
target = path.join(path.dirname(module.parent.paths[0]), target);
}
var codeUndertest = require(target);
...
return codeUnderTest;
This relies on the require path resolution that always starts with looking for a node_modules subdirectory relative to the calling file. Couple that with module.parent and you can get access to that search path. Then just remove the trailing node_modules part and concatenate the relative filename.
For other scenarios not using relative paths, this could be accomplished with the options parameter to require:
var codeUndertest = require(target, {paths: module.parent.paths});
...
return codeUnderTest;
And the two could be combined as well. I used the first form because I was actually using proxyquire which does not offer the paths option.

what does var io = require('../..')(server) do?

I've build the project https://github.com/Automattic/socket.io/tree/master/examples/chat locally and it is working great. However, it would be nice to understand a little more about how a socket application works.
In the main startup script one of the modules that is pulled in with require is
var io = require('../..')(server)
what does require('../..') do?
thanks!
When a path to a directory is given to require, it will implicitly look for an index.js in that directory.
In this case, it's the equivalent of
var socket = require("../../index.js");
var io = socket(server);
In the example provided, they're just using some shorthand and throw away the intermediate value returned by the call to require.
Check out the module.require docs for more info.
Here, in your code
require('../..');
Will add File form the path, which have used SOCKET.IO, as you can see that you have not added Socket.io module.
Also, if no specific path give for file or folder, Module require will try to load index.js or index.node. if no such file exist then it will give error.

Add global function to every execution of NodeJS

In my project folder project I have a file utils.js like this
global.root_path = process.cwd();
global.custom_require = function() {
console.log('custom require called');
}
I would like to include this file in every execution of node so that in every js file in project i can call custom_require, or access global.root_path as I'm doing already with built-in function require.
Do you know if there is a solution (command line options, environment variable or whatever) to achieve this?
UPDATE
I don't want to include utils.js in every file, in that case I wouldn't need to modify global object.
Thanks!
Simply require it. Example app.js:
require('./utils.js');
var express = custom_require('express');
var app = express();
var port = process.env.PORT || 3000;
app.listen(port);
Then, you could just do (in terminal)
node app
As long as you require the code containing the global declarations on it, then you can use those globals from any file that's required after the fact.
You most probably don't want to have a custom "plugin" altering the behavior of all your applications when run locally, thus it'd be best to stay away from that kind of pattern. Instead, you might want to create a module, use npm link on it, and then npm link something in your project's directory, where something is the module name.
Then each project could just add one line like require('something'); at the very beginning. Changing something would immediately impact all the projects which included it, thanks to the behavior in npm link.

Nodejs + CoffeeScript + Mongoose : Define Module?

I'm trying to create a little application to store snippets of code using nodejs and mongodb
I'm using Coffeescript to write the app.
The problem is, i want to separate the code in modules
so i create this folder structure
/app
/lib
/models
/routes
core.coffee
The core.coffe is the "server" app using expressjs
so in this file i have
mongoose = module.exports.mongoose = require 'mongoose'
app = module.exports.app = express.createServer()
Snippet = module.exports.Snippet = require __dirname+'/lib/models/Snippet'
#App configurations
routes = require(__dirname+'/lib/routes/general')
In lib/models/Snippet
mongoose = module.parent.exports.mongoose
Snippet = new mongoose.Schema
title:
type: String
default:'Title'
mongoose.model 'Snippet',Snippet
exports.Snippet = mongoose.model 'Snippet'
In /lib/routes/general.coffee
app = module.parent.exports.app
mongoose = module.parent.exports.mongoose
Snippet = module.parent.exports.Snippet
app.get '/test', (req,res)->
snip = new Snippet()
res.send snip
But this don't work i get the following error message
TypeError: object is not a function
at Object.CALL_NON_FUNCTION_AS_CONSTRUCTOR (native)
How can I accomplish that?
I see a noteworthy typo:
Snippet = module.exports.Snippt = require __dirname+'/lib/models/Snippet'
Change module.exports.Snippt to module.exports.Snippet.
Let's start by looking at how you're using require. It looks like you're trying to load all the project's requirements in core.coffee, and then re-export them elsewhere. That's an odd way of doing it, most people just require those libraries in each module that needs them (for now at least, see the end of my answer).
For example, you need mongoose in lib/models/Snippet, so just require it there:
lib/models/Snippet:
mongoose = require 'mongoose'
Next, there's no need to use __dirname to require a relative path, require copes fine with a path starting with ./:
require './lib/models/Snippet'
I still wasn't able to get the code to work cleanly (I'm guessing we're not seeing the full code), but it might be enough to set you on the right path.
Finally, if you want to go down the route of exporting everything on the main module can I suggest taking a look at dave-elkan's layers project. The plain version doesn't support coffeescript, but I've created a fork that does.
It's very lightweight, and makes almost no assumptions about your project structure. The basic idea is that you give layers() your express app object and a directory. Layers will scan that directory and set up any subdirectories as layers on your app object.
In your case you'd pass in a rootPath: __dirname + '/lib' and your app object would get app.models.Snippet and app.routes.general added onto it. That's still not quite how I'd structure it, but you might be able to come up with something that matches your style from there.

Resources