Copy files to sub-directories - javascript

Using gulp, is there any easy way to copy each file that matches some glob to a sub-directory relative to the original file's location?
For example:
The source glob might look like this:
'./**/*.txt'
This is what the file structure might look like beforehand:
./dir1/file1.txt
./dir2/file2.txt
./dir3/file3.txt
This is what the corresponding file structure would look like afterward:
./dir1/file1.txt
./dir1/sub/file1.txt
./dir2/file2.txt
./dir2/sub/file2.txt
./dir3/file3.txt
./dir3/sub/file3.txt

I'm still not sure whether native gulp provides any way of doing this. But it looks like one way of doing this would be to use the gulp-rename package.
var rename = require('gulp-rename');
gulp.src('./**/*.txt')
.pipe(rename(function (path) {
path.dirname += '/sub';
}))
.pipe(gulp.dest('./'));

Related

How to rename the original files of scripts in index.html using gulp?

I've written a gulp task to rename files so that they can be versioned. The problem is that the filenames of the files that the index.html scripts reference are not changed.
For example, in my index.html:
<script src=pub/main_v1.js"></script>
But if you actually navigate through the build folder to the subdirectory pub, you will find main.js.
Here is the custom gulp task:
const gulpConcat = require('gulp-concat');
const gulpReplace = require('gulp-replace');
const version = require('./package.json').version;
gulp.task('version', function () {
var vsn = '_' + version + '.js';
gulp.src('scripts/**/*.js')
.pipe(gulpConcat(vsn))
.pipe(gulp.dest('./prodBuild'));
return gulp.src('./prodBuild/index.html', { base: './prodBuild' })
.pipe(gulpReplace(/* some regex */, /* append vsn */))
.pipe(gulp.dest('./prodBuild'));
});
What do I need to fix/add so that the original filename changes to match that in the script tag?
Note: According to the gulp-concat docs, I should be able to find the concated files at prodBuild/[vsn], where [vsn] is _v1.js. However, it is no where to be found.
Update: The files rename properly in index.html, but I can't seem to get the renaming of the original files to work. Here's a snapshot of my build directory:
prodBuild/
pub/
main.js
someDir/
subDirA/
// unimportant stuff
subDirB/
file2.js
file3.js
// ...other files and folders...
EDIT:
The issue is that you return only one of the two tasks. The first task is simply ignored by gulp, since it is not returned. A simple solutions: Split it into two tasks, and reference the one from the other, like in this SO answer.
Old Answer
This looks like a perfect case for the gulp-rename. You could simply pipe your scripts through gulp-rename, like this:
.pipe(rename(function (path) {
path.basename += vsn;
path.extname = ".js"
}))
Gulp concat is, AFAIK, made for the concatination of files, not particularly for the renaming of them.

How to set up gulp to bundle several files into one?

This seems like a very simple question, but spent the last 3 hours researching it, discovering it can be slow on every save on a new file if not using watchify.
This is my directory tree:
gulpfile.js
package.json
www/
default.htm
<script src="toBundleJsHere/file123.js"></script>
toBundletheseJs/
componentX/
file1.js
componentY/
file2.js
componentZ/
file3.js
toPutBundledJsHere/
file123.js
Requirements.
On every creation or save of a file within the folder toBundleTheseJs/ I want this file to be rebundled into toBundleJsHere/
What do I need to include in my package.json file?
And whats the minimum I need to write into my gulp file?
This should be as fast as possible so think I should be using browserify and watchify. I want to understand the minimum steps so using package manager like jspm is overkill a this point.
thanks
First you should listen to changes in the desired dir:
watch(['toBundletheseJs/**/*.js'], function () {
gulp.run('bundle-js');
});
Then the bundle-js task should bundle your files. A recommended way is gulp-concat:
var concat = require('gulp-concat');
var gulp = require('gulp');
gulp.task('bundle-js', function() {
return gulp.src('toBundletheseJs/**/*.js')
.pipe(concat('file123.js'))
.pipe(gulp.dest('./toPutBundledJsHere/'));
});
The right answer is: there is no legit need for concatenating JS files using gulp. Therefore you should never do that.
Instead, look into proper JS bundlers that will properly concatenate your files organizing them according to some established format, like commonsjs, amd, umd, etc.
Here's a list of more appropriate tools:
Webpack
Rollup
Parcel
Note that my answer is around end of 2020, so if you're reading this in a somewhat distant future keep in mind the javascript community travels fast so that new and better tools may be around.
var gulp = require('gulp');
var concat = require('gulp-concat');
gulp.task('js', function (done) {
// array of all the js paths you want to bundle.
var scriptSources = ['./node_modules/idb/lib/idb.js', 'js/**/*.js'];
gulp.src(scriptSources)
// name of the new file all your js files are to be bundled to.
.pipe(concat('all.js'))
// the destination where the new bundled file is going to be saved to.
.pipe(gulp.dest('dist/js'));
done();
});
Use this code to bundle several files into one.
gulp.task('scripts', function() {
return gulp.src(['./lib/file3.js', './lib/file1.js', './lib/file2.js']) //files separated by comma
.pipe(concat('script.js')) //resultant file name
.pipe(gulp.dest('./dist/')); //Destination where file to be exported
});

Gulp copy list of folders with contents

I would like to copy a list of folders to a destination with gulp
So far i've come up with a working solution, but its far from performant.
The structure of my directory is like this:
App
src
web
some files...
and i would like to copy it to
build
src
web
the files
The code i am using to accomplish this is:
var paths = [path.app + '/src/', path.app + '/app/'].concat(path.assets);
paths.forEach(function(value, index){
// value.replace(path.app, path.build);
gulp.src(value + '/**/*')
.pipe(gulp.dest(value.replace(path.app, path.build)));
});
Where the assets are my files (or other directories)
However there is a loop and no clear return value. I am wondering if there is a more performant way of doing this
I'm not sure I understand what you're trying to do here (where is your gulp task definition for example?), but it seems like you just want to copy everything below App to the build folder while preserving directory structure.
If that's the case, you don't have to loop over the files and replace folder names yourself. Gulp does it for you:
gulp.task('default', function () {
return gulp.src('App/**')
.pipe( gulp.dest('build') );
});
Everything before the ** is automatically stripped from the path of files written to build, so you end up with build/src, build/web, etc ...

How Do You Get Around Javascript File Order Using Gulp Or A Javascript Framework?

I'm using gulp to build a single javascript file with gulp-concat and gulp-uglify.
Original Files
//File 1
var Proj = Proj || {};
//File 2
Proj.Main = (function() {
var Method = function(){ /*Code*/ };
return { "Method":Method };
})();
//File 3
Proj.Page = (function() {
var Method = Proj.Main.Method;
return { "Method":Method };
})();
Gulp returns a bad minified file because these files are being concatenated in the wrong order. I know I can specify the order in .src([]) but I don't want to maintain the array as I add javascript files.
Is there a way to create references to these "namespaces" without having to worry about the order of the files concatenated? Or, is there a way for gulp to handle concatenation with the knowledge of these namespaces auto-magically?
EDIT:
I know I can specify the file order inside the .src([]). I want to develop without having to worry about the file order, whether it be through a gulp package or a javascript framework. Thank you for responses that help but I need a definitive "No. You cannot do this." or "Yes. Here's how..." to mark the thread as answered.
Well, one option is to try gulp-order.
Also, check out this answer to "gulp concat scripts in order?".
Basically, it mentions what you already said, about having to explicitly name the files in the order you want them to come in. I know you don't want to do that, but how else would gulp know which order you want your files in?
One thing worth pointing out, though, is that you have a group of files where the order doesn't matter, and then, say, 2 files where the order does matter, you can do something like this:
gulp.src([
'utils/*.js',
'utils/some-service.js',
'utils/something-that-depends-on-some-service'
])
gulp-concat doesn't repeat files, so everything that's not some-service.js or something-that-depends-on-some-service.js will get concatenated first, and then the last two files will be concatenated in the proper order.
Since it hasn't been mentioned, implementing webpack or browserify will absolutely solve this problem without implementing some sort of hacky feeling solution.
Here is a simple example of how to use it:
var source = require('vinyl-source-stream'), //<--this is the key
browserify = require('browserify');
function buildEverything(){
return browserify({
//do your config here
entries: './src/js/index.js',
})
.bundle()
.pipe(source('index.js')) //this converts to stream
//do all processing here.
//like uglification and so on.
.pipe(gulp.dest('bundle.js'));
}
}
gulp.task('buildTask', buildEverything);
And inside your files you use require statements to indicate which files require others.

How does one specify a custom search path with Browserify?

I have a large project that consists of hundreds of source files broken into several folders.
Something like this:
src/
AAA.js
subdir/
DDD.js
I would like to be able to specify dependencies with non-relative paths.
For instance, in DDD.js I would like to do this:
var AAA = require('AAA');
...rather than this:
var AAA = require('../AAA');
How can I achieve this with Browserify?
As stated in the documentation, Browserify uses browser-resolve under the hood.
When using the node API (as opposed to the CLI), you can specify a paths option which contains a list of directories to pass to browser-resolve.
The solution for my example would thus be something like this:
var browserify = require('browserify');
var b = browserify({
paths: [
__dirname + '/src'
]
});
b.add(__dirname + '/src/AAA.js');
b.bundle().pipe(process.stdout);
Or if you want to do it from the command line you can add your directory to the node search path:
NODE_MODULES=$NODE_MODULES:src browserify -o output.js input.js

Categories