How to go back 1 folder level with __dirname? - javascript

I am using gulp-karma and facing a simple problem but cannot seems to find what i am doing wrong .
gulp.task('test', function (done) {
karma.start({
configFile: __dirname + '..\\test\\' +'\karma.conf.js',
singleRun: true
}, done);
});
Here is the code i am using and i cannot seems to go 1 level back in the folder directory . When i do the above it just append the ..\ to the folder direcotry without going 1 level back (which is the usual use of ..\). Following is the folder structure .
parent|
test|karma.conf.js
webapirole|gulpfile.js
and my folder is inside the webapirole folder . i want to go back 1 folder back and go inisde the test folder which contains the karma.conf.js file. can anyone make me understand what i am doing wrong here ?
error i am getting
[18:06:32] Starting 'tdd'...
ERROR [config]: File C:\Users\Documents\WebApiRole..\test\karma.conf.js does not exist

TL;DR
Use path.join(__dirname, '..', 'test', 'karma.conf.js'). Prevent use of slashes.
Long Answer
As a lot of answers have pointed out, using path module is probably the best way.
However, most of the solutions here have gone back to using slashes like:
path.join(__dirname+'../test/karma.conf.js')
However, by doing this, you're beating the purpose of using path. One uses path to do operations irrespective of the underlying OS (Linux, Windows etc). Just to give a bit of insight, you can do the path operations directly as string operations (like __dirname + '../test/karma.conf.js'. You do not do this because Linux uses forward slashes ( / ), Windows uses backward slashes ( \ ). This makes your application prone to errors when you port it across operating systems.
Thus, the better way would be:
path.join(__dirname, '..', 'test', 'karma.conf.js')
And of course, coming back - prevent use of slashes in your path.join, instead spread out your params.

I am using (path) NPM for the above usage......
simply require path npm in js file.Then use
let reqPath = path.join(__dirname, '../../../');//It goes three folders or directories back from given __dirname.

__dirname is just a string. you can use ../ to traverse up the folder structure and path.join to resolve the path
path = require('path')
configFile: path.join(__dirname, '../test/karma.conf.js'),

You can use Path like this
const path = require('path');
path.join(__dirname, "../");

if you are sending the path as a string,
configFile: path.join(__dirname+'../test/karma.conf.js'),
this doesn't work.
Instead you have to use a comma, (the plus sign concatenates the two strings)
configFile: path.join(__dirname, '../test/karma.conf.js'),

from Root directory
(path.join(__dirname , 'views' ,'main.html')) -> will return Root:/views/main.html
from any sub-folder of Root
(path.join(__dirname , '../views/main.html')) -> same as above

Like Pranav Totla said, hardcode the path with forward slashes ( "/" ) or backward slashes ( "\" ) makes the application prone to errors when it came across different operating systems.
Use the built in "path" module to prevent errors.
// Import "path"
const path = require('path');
// To go down on the three from index.html:
path.join(__dirname, 'css', 'style.css')
// To go up on the three from style.css:
path.join(__dirname, '..', 'img', 'cat.jpg')
// Three
root/
| |_css/
| |_img/
|
|_index.html

we can use path module to go back one level from the current directory
Example:
path.join(__dirname, '..', 'test', 'conf.js')
__dirname -- present directory
.. -- one level
test -- folder name
config.js -- file (test folder inside)

Try putting a \\ before the ..\\.
Without it, the path your generating has a folder called WebApi... as part of it. You can see this in the path being output from the error message.
Like this:
gulp.task('test', function (done) {
karma.start({ configFile: __dirname + '\\..\\test\\' +'\karma.conf.js', singleRun: true }, done);
});
You may also want to look into using the path library from npm. It makes combining paths a lot easier by handling adding and removing extra path separator characters as needed.

Here is all you need to know about relative file paths:
Starting with / returns to the root directory and starts there
Starting with ../ moves one directory backward and starts there
Starting with ../../ moves two directories backward and starts there (and so on...)
To move forward, just start with the first sub directory and keep moving forward.

this will move you 2 directory back irrespective of any operating system:
import { join, sep } from 'path';
join(__dirname, sep, "..", sep, "..");

Related

How to use a glob pattern in the scripts section of angular.json?

I have a hybrid AngularJS/Angular application that will take some time to complete migration to fully be an Angular app. While this process occurs, I'd like to move away from the previous build system to using the CLI and webpack to manage all of the old AngularJS scripts as well. This is possible as I've done it before by adding all of my scripts to the scripts section in angular.json like the following:
"scripts": [
"src/app/angularjs/app.js",
"src/app/angularjs/controllers/main.js",
"src/app/angularjs/services/someService.js",
"src/app/angularjs/controllers/someController.js"
],
This works well and the CLI builds via ng serve and ng build continue to work for the hybrid bootstrapped app as needed. The problem I'm running into now is manually listing each file for the current application I'm migrating is not ideal. I have hundreds of scripts that need to be added, and what I need is to be able to use a globbing pattern like the following:
"scripts": [
"src/app/angularjs/**/*.js"
],
The problem is this syntax from what I can tell is not supported. The glob pattern is supported in the assets section of angular.json as stated here but not in the scripts section: https://angular.io/guide/workspace-config#assets-configuration
In the scripts section I can't find a similar solution. It does have an expanded object API, but nothing that solves the problem I can tell to select all .js files from a particular directory as listed here: https://angular.io/guide/workspace-config#styles-and-scripts-configuration
Is it possible by some means to use a glob pattern or similar approach to select all files of a directory for the scripts section in angular.json so I don't have to manually list out hundreds of individual .js files?
The Bad News
The scripts section does not support the same glob patterns that the assets section does.
The Good News(?)
Since you're transitioning away from AngularJS, you hopefully won't have any new files to import in the future, so you could just generate the list of all the files you need to import.
Make your way to the src/app/angular directory and run the following:
find . -iregex '.*\.\(js\)' -printf '"%p",\n'
That will give you your list, already quoted for your convenience. You may need to do a quick search/replace (changing "." to "src/app/angularjs"), and don't forget to remove the last comma, but once you've done that once you should be all set.
The Extra News
You can further filter out unwanted files with -not, so (per your comment) you might do:
find . -iregex '^.*\.js$' -not -iregex '^.*_test\.js$' -printf '"%p",\n'
And that should give you all your .js files without your _test.js files.
KISS
Of course, this isn't a complex pattern, so as #atconway points out below, this will work just as well:
find . -iname "*.js" -not -iname "*_test.js" -printf '"%p",\n'
I'll keep the above, though, for use in situations where the full power of regex might come in handy.
I wanted to extend an anser of #JasonVerber and here is a Node.JS code and therefore (I believe) cross-platform.
Firstly install find package and then save contents from the snippet in some file.js.
Afterwards, specify paths so that they resolve to where you wan't to get your files from and where to put the resulting file to.
After that node file-name.js and this will save all found file paths to the resultPath in result.txt ready to Ctrl+A, Ctrl+C, Ctrl+V.
const find = require('find');
const path = require('path');
const fs = require('fs');
// BEFORE USAGE INSTALL `find` package
// Path to the folder where to look for files
const sourcePath = path.resolve(path.join(__dirname, 'cordova-app', 'src'));
// Path that will be removed from absolute path to files
const pathToRemove = path.resolve(path.join(__dirname, 'cordova-app'));
// Path where to put result.txt
const resultPath = path.resolve(path.join(__dirname, './result.txt'));
// Collects the file paths
const res = [];
// Path with replaced \ onto /
const pathToRemovehReplaced = pathToRemove.replace(/\\/g, '/');
// Get all fils that match a regex
find.eachfile(/\.js$/, sourcePath, file => {
// First remove all \ with / and then remove the path from root to source so that only relative path is left
const fileReplaced = file.replace(/\\/g, '/').replace(`${pathToRemovehReplaced}/`, '');
// Surround with quoutes
res.push(`"${fileReplaced}"`);
}).end(() => {
// Write file and concatenate results with newline and commas
fs.writeFileSync(resultPath, res.join(',\r\n'), 'utf8');
console.log('DONE!');
});
The result I got while testing (/\.ts$/ for regex)
"src/app/app.component.spec.ts",
"src/app/app.component.ts",
"src/app/app.module.ts",
"src/environments/environment.prod.ts",
"src/environments/environment.ts",
"src/main.ts",
"src/polyfills.ts",
"src/test.ts"

__webpack_public_path__ does not work after reloading the page

We are working on a Vue.js application which is built with webpack. The requirement is that our application not only has to be accessible via the base path / but also via a custom path, so that the application could be accessable next to other services. With webpacks \__webpack_public_path__ I was able to set the base path on the fly regarding a specified base path, like if the current path has got /foo/ in it, the base path should start at .../foo/.
While navigating through the application everything looks good, as long as I open the app at the base path. The problem is that after I navigate to any sub path and reload the page, no files can be found. The server will first provide the index.html and there I need to use relative paths, since the base path must be determined dynamically. But if any other than the base path is opened, the relative paths in the index.html won't point to the correct bundle.js and the \__webpack_public_path__ will not be set...
Currently we have got two entry points in our webpack config. The first one is a JS file where we the global variable \__webpack_public_path__ will be set relatively based on the current visited URL. So lets say the base path should start at /foo/ and the visited URL is https://www.host.com/some/path/foo/sub/sub1. Therefore the relatively base path will be /some/path/foo/ and assets will be found at i.e. /some/path/foo/assets. All other paths used in the webpack config, like in the file-loader or any other plugin, are relative.
// webpack.config.js
...
module.exports = (env, argv) => ({
...
entry: ['#babel/polyfill', './src/main/js/constants/webpack-public-path.js', './src/main/js/index.js'],
output: {
filename: 'assets/js/bundle.js',
path: path.resolve(__dirname, relativeOutputPath),
publicPath: '/'
},
module: {
...
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'file-loader',
options: {
name: 'assets/fonts/[name].[ext]'
}
}
...
},
...
});
// webpack-public-path.js
__webpack_public_path__ = (() => {
const BASE_PATH = '/foo/';
let path = window.location.pathname;
return path.includes(BASE_PATH) ? path.substring(0, path.indexOf(BASE_PATH) + BASE_PATH.length) : '/';
})();
Has anyone ever faced a similar problem? Is it possible, that the relative paths in the index.html can be defined afterwards or maybe are defined at build time by webpack?
I got a solution for my problem. What I had to do was to load all necessary assets manually in the index.html. Unfortunatly I have to maintain the determination of the dynamic base path on two different files (index.html and the webpack-public-path.js) but at least it's working now. So in the index.html I insert respective tags into the DOM manually and therefore load all needed assets based on the determined base path.

Browserify adding unwanted directories

Setting up gulp for the first time. I've got it correctly compiling the files, it's just sticking them in the wrong place, and I can't quite figure out what to change to get it right.
After they compile, I have it adding the .conveyor.js suffix and then I want it to place them in the /scripts directory. But it's placing them in /scripts/src/js/ — it's adding a couple subdirectories. The raw dev files themselves are in src/js/ directories in a separate location, but I don't want that to carry over. Here's my gulp setup:
module.exports = function() {
var files = [
'./src/js/dashboard.js',
'./src/js/pages.js',
'./src/js/poll.js'
];
var tasks = files.map(function(entry) {
return browserify({
entries: [entry],
paths: ['./node_modules', './src/js/']
})
.bundle()
.pipe(source(entry))
.pipe(rename({
extname: '.conveyor.js'
}))
.pipe(gulp.dest('../scripts/'));
});
return es.merge.apply(null, tasks);
};
The way I understand it, "files" are all of the files it looks for to compile. "paths" allow you to specify directories that your require statements can be relative to so you don't have to do a bunch of period-forwardslashing. and then "dest" is where you want the files to end up. But I'm clearly misunderstanding something.
The offender is here
.pipe(source(entry))
entry is set to the exact path you are using for the files path. Hence the duplication.
source() in this isn't the source of the file, but ends up being the file that gets created.
You would want to modify the object to provide just the file name as the entry and the source path is separated. Also, you can drop the rename method, I think.

Webpack multiple named chunks ignoring names at runtime

I am having trouble with webpacks code splitting functionality. I am trying to have 2 named chunks for two routes in my application which are not often visited. mysite.com/settings and mysite.com/access.
here is my webpack.config.coffee
module.exports =
contentBase: "#{__dirname}/src/"
cache: true
entry:
app: './src/coffee/app'
head: './src/coffee/head'
output:
path: path.join(__dirname, 'build')
publicPath: '/'
filename: '[name].js'
chunkFilename: '[name]-[chunkhash].js'
plugins: []
And here is my router.coffee
access: (slug) ->
_this = #
require.ensure ['../view/page/access-page.coffee'], (require) ->
AccessPage = require '../view/page/access-page.coffee'
accessPage = AccessPage.getInstance()
accessPage.render() unless accessPage.isRendered
_this.showPage accessPage
, 'access'
settings: (slug) ->
_this = #
require.ensure ['../view/page/settings-page.coffee'], (require) ->
SettingsPage = require '../view/page/settings-page.coffee'
settingsPage = SettingsPage.getInstance()
settingsPage.render() unless settingsPage.isRendered
_this.showPage settingsPage
, 'settings'
I am not using the webpack dev-server, instead I am watching simply by using the following cmd-line tool
webpack -d --progress --colors --watch
The problem is that it ignores the names when requiring the files, as you can see the format is '[name]-[hash].js' it generates files with the correct format e.g. settings-2j3nekj2n3ejkn2.js but during development, when I attempt to load the page, the browser complains that '-2j3nekj2n3ejkn2.js' cannot be found, somehow the mapping of the files, ignores the names. If I leave out the names, then it works.
So the question is how can I setup mulitple named chunks correctly. Thanks in advance.
Note I have checked out their examples in the docs at https://github.com/webpack/docs/wiki/code-splitting
and I have followed their optimization docs aswell at
https://github.com/webpack/docs/wiki/optimization
But I am stuck
Well the simple answer is - [name= is not supported in chunkName.
The awesome guys at Webpack have actually heard my cries and implemented it
Here is the commit
https://github.com/webpack/webpack/commit/03c87c11a4219ae6ec6bfe87e570a0dacceac859
As a result of the following issue I made
https://github.com/webpack/webpack/issues/358
It is already available as of Beta ^1.3.2

Traverse '__dirname' in Node.js Application

I'm trying to get the parent of the current __dirname in my node application.
Here is my current line of code:
mu.root = __dirname + '/theme';
Yet, I want to reach out of the current directory and into another one of it's sibilings.
Here is my directory structure:
lib
this_file.js
theme
theme_file.file
How would I go about doing this without having to parse the result of __dirname?
You could use ../ to traverse to the parent of the current directory and path.join to resolve the path:
var path = require('path');
...
path.join(__dirname, "../whiceverdirectoryname");
Use path.dirname(__dirname)
Here's the doc.

Categories