Meteor project path from a smartpackage - node.js

I was looking for a way to look up the meteor project path from a smart package (e.g.: obtain the path of the directory where the .meteor folder is ...).
I was not able to do it using node's __dirname and __filename because somehow in meteor they are not avaiable.
Any tips ?

As of Meteor 0.6.0 this would be:
var path = Npm.require('path');
var basepath = path.resolve('.');

From a smartpackage (0.6.5+):
var path = Npm.require('path');
var base = path.resolve('.');
base in this case gets you the position of your package ..
/User/username/projects/project/.meteor/local/programm/server/...
.. might even be deeper
but we want
/User/username/projects/project/
.. so split at .meteor
base = base.split('.meteor')[0];
Or as two-liner
var path = Npm.require('path');
var base = path.resolve('.').split('.meteor')[0];;

This works for me in Meteor 0.5.0:
var require = __meteor_bootstrap__.require;
var path = require('path');
var basepath = (path.resolve('.'));

You can actually get access to node:
var __dirname = __meteor_bootstrap__.__dirname;

You could try (only on server side)
process.env.PWD which returns something like that for me (OSX):
'/Users/myusername/Desktop/myproject'
With that command you get the root of meteor project.

Related

node_modules path programmatically

I am using protractor and I want to get programmatically the npm node_modules path from the global system.
For example my selenium jar is installed here:
C:/Users/myuser/AppData/Roaming/npm/node_modules/protractor/node_modules/webdriver-manager/selenium/selenium-server-standalone-3.7.1.jar
and I wanted to get
C:/Users/myuser/AppData/Roaming/npm/node_modules/
or
C:/Users/myuser/AppData/Roaming/npm/node_modules/protractor/node_modules/
I wrote this small script, which will look for my jar in the paths
var path = require('path');
var fs = require('fs');
var paths = path.getModulePaths()
for (i=0;i<paths.length;i++) {
file = path.join(paths[i],'webdriver-manager','selenium','selenium-server-standalone-3.7.1.jar')
if (fs.existsSync(file)) {
var seleniumServerJar = file
continue
}
}
here I supposed that this function is available
var paths = path.getModulePaths()
but it's not. I used to write an equivalent in Python, which is:
import sys
print sys.path
I guess you are expecting to start a webdriver manager programatically. Try below code:
var pkgPath = require.resolve('protractor');
var protractorDir = path.resolve(path.join(path.dirname(pkgPath), '..', 'bin'));
var webdriverManagerPath = path.join(protractorDir, '/' + 'webdriver-manager'));

Nodejs absolute paths in windows with forward slash

Can I have absolute paths with forward slashes in windows in nodejs? I am using something like this :
global.__base = __dirname + '/';
var Article = require(__base + 'app/models/article');
But on windows the build is failing as it is requiring something like C:\Something\Something/apps/models/article. I aam using webpack. So how to circumvent this issue so that the requiring remains the same i.e. __base + 'app/models/src'?
I know it is a bit late to answer but I think my answer will help some visitors.
In Node.js you can easily get your current running file name and its directory by just using __filename and __dirname variables respectively.
In order to correct the forward and back slash accordingly to your system you can use path module of Node.js
var path = require('path');
Like here is a messed path and I want it to be correct if I want to use it on my server. Here the path module do everything for you
var randomPath = "desktop//my folder/\myfile.txt";
var correctedPath = path.normalize(randomPath); //that's that
console.log(correctedPath);
desktop/my folder/myfile.txt
If you want the absolute path of a file then you can also use resolve function of path module
var somePath = "./img.jpg";
var resolvedPath = path.resolve(somePath);
console.log(resolvedPath);
/Users/vikasbansal/Desktop/temp/img.jpg
it's 2020, 5 years from the question was published, but I hope that for somebody my answer will be useful. I've used the replace method, here is my code(express js project):
const viewPath = (path.join(__dirname, '../views/')).replace(/\\/g, '/')
exports.articlesList = function(req, res) {
res.sendFile(viewPath + 'articlesList.html');
}
I finally did it like this:
var slash = require('slash');
var dirname = __dirname;
if (process.platform === 'win32') dirname = slash(dirname);
global.__base = dirname + '/';
And then to require var Article = require(__base + 'app/models/article');. This uses the npm package slash (which replaces backslashes by slashes in paths and handles some more cases)
The accepted answer doesn't actually answer the question most people come here for.
If you're looking to normalize all path separators (possibly for string work), here's what you need.
All the code segments have the node.js built-in module path imported to the path variable.
They also have the variable they work from stored in the immutable variable str, unless otherwise specified.
If you have a string, here's a quick one-liner normalize the string to a forward slash (/):
const answer = path.resolve(str).split(path.sep).join("/");
You can normalize to any other separator by replacing the forward slash (/).
If you want just an array of the parts of the path, use this:
const answer = path.resolve(str).split(path.sep);
Once you're done with your string work, use this to create a path able to be used:
const answer = path.resolve(str);
From an array, use this:
// assume the array is stored in constant variable arr
const answer = path.join(...arr);
I recommend against this, as it is patching node itself, but... well, no changes in how you require things.
(function() {
"use strict";
var path = require('path');
var oldRequire = require;
require = function(module) {
var fixedModule = path.join.apply(path, module.split(/\/|\\/));
oldRequire(fixedModule);
}
})();
This is the approach I use, to save some processing:
const path = require('path');
// normalize based on the OS
const normalizePath = (value: string): string {
return path.sep === '\'
? value.replace(/\\/g, '/')
: value;
}
console.log('abc/def'); // leaves as is
console.log('abc\def'); // on windows converts to `abc/def`, otherwise leave as is
Windows uses \, Linux and mac use / for path prefixes
For Windows : 'C:\\Results\\user1\\file_23_15_30.xlsx'
For Mac/Linux: /Users/user1/file_23_15_30.xlsx
If the file has \ - it is windows, use fileSeparator as \, else use /
let path=__dirname; // or filePath
fileSeparator=path.includes('\')?"\":"/"
newFilePath = __dirname + fileSeparator + "fileName.csv";
Use path module
const path = require("path");
var str = "test\test1 (1).txt";
console.log(str.split(path.sep)) // This is only on Windows

how to use gulp-filter with main-bower-files to filter on directory in the middle

I want to filter just the files which include the directory ui-router somewhere in the middle of the path.
I have the following code:
var gulp = require('gulp');
var mainBowerFiles = require('main-bower-files');
var debug = require('gulp-debug');
var gulpFilter = require('gulp-filter');
gulp.task('default',function() {
var bower_files = mainBowerFiles();
var js_filter = gulpFilter(['**/*.js']);
gulp.src(bower_files)
.pipe(js_filter)
.pipe(debug({title: 'unicorn:'}))
var js_filter = gulpFilter(['**/ui-router/**']);
gulp.src(bower_files)
.pipe(js_filter)
.pipe(debug({title: 'unicorn1:'}))
});
The output is:
[12:10:53] unicorn: bower_components\ngstorage\ngStorage.js
[12:10:53] unicorn: bower_components\ui-router\release\angular-ui-router.js
[12:10:53] unicorn: bower_components\x2js\xml2json.min.js [12:10:53]
unicorn1: 0 items
Meaning that ['**/*.js'] works to filter out all js files.
But ['**/ui-router/**'] does not work. What is problematic with this pattern?
I read the following doc https://github.com/isaacs/node-glob and i don't see why it should not work.
You can filter the result of main-bower-files:
var files = mainBowerFiles(/\/ui\-router\//);
After hacking with this a long time i found the issue.
In gulp-filter the vinyl file.relative property is sent.Comment from Sindre Sorhus
In our case the files are without globs(What i understand) and therefore we get just the name of the file without the directory.
The solution is to write instead of gulp.src(bower_files) gulp.src(bower_files,{base:__dirname})
Here we say gulp from where to start the relative file.

Find absolute base path of the project directory

Until now we could get the absolute path of a file to open later as readStream with this code snippet:
var base = path.resolve('.');
var file = base + '/data/test.csv';
fs.createReadStream(file)
Since Meteor 0.6.5 the base path is pointing to .meteor/local/build/programs/...
There is also the Assets API, which but can not give us back a path but only the read document. We but need a stream to process some bigger data files?
Another way to find your project's root directory now is this:
var base = process.env.PWD
Note that this is not the same as process.cwd(). Instead it is the directory where you ran the meteor command, which is typically what you are looking for. Note also that this probably won't be very helpful when running your app from a deployed bundle.
I ran into the same predicament when I updated to 0.6.5.
What I'm currently doing is getting the path like this:
var meteor_root = Npm.require('fs').realpathSync( process.cwd() + '/../' );
This returns on dev mode:
/my/application/.meteor/local/build/programs
and on bundled mode:
/my/application/build/app/programs
So from here I'm getting to my application's "root" path like so:
var application_root = Npm.require('fs').realpathSync( meteor_root + '/../' );
// if running on dev mode
if( Npm.require('path').basename( Npm.require('fs').realpathSync( meteor_root + '/../../../' ) ) == '.meteor' ){
application_root = Npm.require('fs').realpathSync( meteor_root + '/../../../../' );
}
The only case in which this would fail is if you happen to name your application's folder ".meteor" but that's an edge case.
Relative to that you can access whatever else you need to.
Additionally, you can also get direct access to to the assets folder that the meteor bundler creates:
var assets_folder = meteor_root + '/server/assets/' + Npm.require('path').basename( application_root );
This is likely to be temporary as I expect better file/path interaction APIs to be added eventually..
Hope that helps
Since version 1.3, the documented function
Assets.absoluteFilePath(assetPath)
seems to be the best way to get the project path reliably.
Meteor Github
Hey you do not need to hardcode like the above answers... take a look to This package
After install it you can access the root path of your meteor just wih Meteor.rootPath
For Meteor 0.8.3,
__meteor_bootstrap__.serverDir gives out the working directory, when run in server mode.
example
if (Meteor.isServer) {
console.log(__meteor_bootstrap__.serverDir);
}
you could get project basic root path by
process.env.PWD
As of Meteor 1.2.1, this works for me:
var absoluteBasePath = path.resolve('../../../../../.');
The same result using split:
var absoluteBasePath = path.resolve('.').split(path.sep + '.meteor')[0];
Using process.cwd():
var absoluteBasePath = path.resolve(process.cwd(), '../../../../../');
var absoluteBasePath = path.resolve(process.cwd()).split(path.sep + '.meteor')[0];

How do I get the ‘program name’ (invocation location) in Node.js?

I want the equivalent of $PROGRAM_NAME in Ruby, or ARGV[0] in C-likes, for Node.js. When I have a Node script that looks something like this,
#!/usr/bin/env node
console.log(process.argv[0])
… I get “node” instead of the name of the file that code is saved in. How do I get around this?
You can either use this (if called from your main.js file):
var path = require('path');
var programName = path.basename(__filename);
Or this, anywhere:
var path = require('path');
var programName = path.basename(process.argv[1]);
Use __filename? It returns the currently executing script.
http://nodejs.org/docs/latest/api/globals.html#globals_filename
For working with command line option strings check out the optimist module by Substack. Optimist will make your life much easier.
var inspect = require('eyespect').inspector();
var optimist = require('optimist')
var path = require('path');
var argv = optimist.argv
inspect(argv, 'argv')
var programName = path.basename(__filename);
inspect(programName, 'programName')
To install the needed dependencies:
npm install -S eyespect optimist

Resources