npm compressing module to compress two subfolders - node.js

I need a .tgz with the following folder structure:
./folder1/folder2/ "multiples files here".
The first folder will never contain files but is necessary.
I want to use the "compressing" npm module ( https://www.npmjs.com/package/compressing ).
But when I use it like in the following code, only folder2 is included. When I create another folder before folder 1 its the same, only folder2 is in there.
const compressing = require('compressing');
try{
compressing.tgz.compressDir('/folder1/folder2', 'destination.tgz')
}catch(e){
console.log(e)
}
I also tried to only specifiy the path to folder1 in the compressDir function, but then I get an error "TarStreamError: ENOENT: no such file or directory".
How can I achieve this?

You're getting the error because your path is incorrect. you are giving the function the path /folder1, meaning it tries to find the folder in the ROOT directory because of the initial /. instead use ./folder1 or just folder.

Related

How to copy only folders from a directory into another

I'm using ncp plugin to copy some folders from a directory into another, the source directory contains some files as well so I only want to copy the folders in it and their content, and this is what I tried:
async function copyAssets(exportFolderName) {
const assets = glob.sync("**/", { cwd: distPath });
return Promise.all(
assets.map((asset) => {
return ncpPromise(path.join(distPath, asset), path.join(exportPath, exportFolderName), {
clobber: false,
});
})
);
}
What I'm doing here is I get the folder names inside distPath using glob.sync and then I copy each folder and it's content into exportPath + exportFolderName.
My source folder looks like this:
But then I get some weird results:
As you can see the folders were not copied, instead it was their content that was copied.
How can I solve this ?
Thanks in advance,
I just tried to play with 'glob' and 'ncp' modules, and this is my little understanding -
glob.sync('**/') Gets directory names recursively
glob.sync('*/') Gets directory names non recursively
Since you want to exclude files from source directory, but copy all directories as a whole, I think you should go with latter glob.sync
Now, playing with ncp -
ncp(source, destination) Copies all files/directories in source to destination directory
So, I am guessing, the following would work for you -
ncp(path.join(distPath, asset), path.join(exportPath, exportFolderName, asset))
This should create the source asset directory, and then put files into it.

Nodejs difference between ./folderpath vs ../folderpath

I'm new in nodejs. I try to use some file in my filesystem. I would like to get them through some realtive path. Here is the structure:
-app
-resources
-tmp
-file1
-file2
-common
-common.js
-etc
So, I would like to reach the file1 and file2 in my resources/tmp folder from the common.js file in int common folder. I used two relative path methodic:
// First , wrong one
var tmpfolder = '../resources/tmp';
// Second, good one
var tmpfolder = './resources/tmp';
The file absolute path is something like this:
C:\Users\xy\Documents\work\nodejs\projects\project_wrapper_folder\project_folder\resources\tmp
If I log the first relative path I got this result:
C:\Users\xy\Documents\work\nodejs\projects\project_folder\resources\tmp
which is wrong, because it does not contains the wrapper folder.
But the second works fine.
Can somebody explain me this behaviour?
UPDATE
I see the meaning if '../', thanks your explanations!
I have tried #Lissy answer: "So baring that in mind ./ will resolve to the value of your project root..." that sounds great, but the result is not.
I have this logic in my app:
var tmpfolder = require('./otherFolder/orhetFile');
where otherFolder is the subfolder of my project_folder. So, when I used this here, I got an error called Cannot find module ...
But if I use this './' in fs module, here: /project_folder/otherFolder_2/otherFile_2 like:
var path = `./resources/tmp`;
fs.mkdirsSync(path);
It works!
these is strange for me. If './' means the current folder, than the example above sould not work (but it's works).
But if the './' means path of the project root, the example with require should work (but does not work).
Strange for me, is there some meaning of require or fs??
In Summary
./my-file means look at the root, whereas ../my-file, means come out of the current directory, and look in the parent folder.
Explanation of Relative and Absolute Paths in Node.js
The default document root is set with the NODE_PATH environment variable (however it would be terrible practice to modify that). So baring that in mind ./ will resolve to the value of your project root.
And so let tmpfolder = require('./resources/tmp'); would resolve to
C:\Users\......\project_wrapper_folder\project_folder\resources\tmp as you have seen
A relative path is denoted by not starting with ./, so for example let tmpfolder = require('my-scripts/some-script'); would look in the current directory for another folder called my-scripts.
Following on from that ../ is relative to the current directory, but goes out one (to it's parent) and looks from there. You can go out two directories by doing ../../my-dir and so on (this is not great practice though, as it can get hard to manage if you have ../../../../../../)
Better method
You can use the __dirname constant in Node to locate the directory name of the current module.
e.g.
fs.readFile(__dirname + '/../foo.bar');
Useful Links
I think you'll find this article on Better local require() paths for Node.js very useful.
Also, for a bit of further reading, here is the official Node.js documentation on paths
The .. means the previous dir. So you are getting out from project_wrapper_folder and then add to the script dir resources\tmp and that way the project_wrapper_folder is no longer in the relative path.
Lets assume you are inside a folder called app.
when you use ../resources/tmp, it will come out of the app folder and will search for tmp inside resources folder.
when you use ./resources/tmp, it will look within the app folder for resources folder and tmp inside it.
../ points to the parent directory while ./ points to current working directory.
A dot basically means "go one folder back in the path"
So:
'./' points at the folder you are in.(in your case the folder common/)
'../' points at the folder that contains the folder you are in. (in your case the folder app/)

Gulp - Copy multiple files to seperate paths

I am working on a web app that uses Node.js. In this app, I have a Gulp file. I am using Gulp 4. During my build process, I am attempting to copy multiple files to directories at once. My directory structure looks like this:
./
dest/
source/
child/
index.js
index.bak
file.js
README.md
My real directory structure is more involved. However, I am trying to copy ./source/file.js to ./dest/file.js and ./source/child/index.js to ./dest/child/index.js. Notice that I do not want to copy README.md or index.bak over to the ./dest directory. In an attempt to do this, I have the following function:
function copy() {
let files = [
'source/file.js',
'source/child/**/*.*'
];
return gulp
.src(files)
.pipe(gulp.dest('dest'))
;
}
My problem is, everything just gets copied to the dest directory. The directory structure does not get preserved. While would be fine if I could figure out how to copy files to different directories in a single task. I tried the following:
function copy() {
return gulp
.src('source/child/index.js')
.pipe(gulp.dest('dest/child'))
.src('source/file.js')
.pipe(gulp.dest('dest'))
;
}
However, that approach just generates an error that says:
TypeError: gulp.src(...).pipe(...).src is not a function
So, I'm stuck. I'm not sure how to copy multiple files to multiple directories from a single gulp task.
You need to use the base option as mentioned here ref. It will make sure your directory is copied as it is.
function copy() {
let files = [
'source/file.js',
'source/child/**/*.*'
];
return gulp
.src(files, {base: 'source/'})
.pipe(gulp.dest('dest'));
}

Node.js - res.sendFile - Error: ENOENT, stat - Even though path is correct

Here's my folder structure :
Root Folder
...
...
...
app.js
escape_iframe.html
...
from within app.js I'm doing :
res.sendFile('escape_iframe.html' , {root : __dirname});
and the error I'm getting is :
Error: ENOENT, stat '/app/escape_iframe.html'
which I guess is a horrible way of saying that the file can't be found in the path provided ?
Anyway, as you can tell I simply want to serve a file that is a sibling of app.js (which is the file form which the res.sendFile(... call is being made)
I also tried : res.sendFile('escape_iframe.html'); and I got : path must be absolute or specify root to res.sendFile
What am I doing wrong ?
Paths specified with a . are relative to the current working directory, not relative to the script file. So the file might be found if you run node app.js but not if you run node folder/app.js.
To make a path relative to the script, you must use the __dirname variable.
res.sendFile(__dirname + '/path/to/escape_iframe.html');
Path specified with . are relative to the path and any number of forward slashes are truncated as single slash. You might get this error when the process node filename.js is not able to locate the filename.
https://nodejs.org/api/errors.html#errors_enoent_no_such_file_or_directory
My suggestion would be ::
var path = require('path')
//process.cwd() returns the current directory of the project
res.sendFile(process.cwd(),'/path/to/escape_iframe.html');

Zip Files & Folders With No Base Directory

AWS Lambda requires a zip file that produces a file when it's unzipped.
However, every node.js zip library produces a zip file that contains a base folder, containing the files Lambda needs, which breaks Lambda, resulting in a 'Cannot find module' error.
For example, if I have a index.js file and a node_modules directory in the dist folder, when I use gulp-zip, I get an added root folder when the zip file is unzipped...
gulp.src(['./dist/**/*'])
.pipe(zip('dist.zip'))
.pipe(gulp.dest('./'))
// When unzipped, this results in a "dist" folder containing index.js and node_modules
I've tried 6 node zip libraries and none have a simple way of excluding the base directory.
Any thoughts?
I've used 'node-archiver', which can zip a directory to a destination directory (which I just set as an empty string).
https://github.com/archiverjs/node-archiver#directorydirpath-destpath-data
var archiver = require('archiver');
archive = archive.directory('./directoryToZip/', '' ); //option 2 is the dest
archive.pipe( outZip);
archive.finalize();

Resources