Can not understand behavior of gulp.src() - javascript

Here is my code:
'use strict';
var gulp = require('gulp'),
$ = require('gulp-load-plugins')(),
module.exports = function(options) {
gulp.task('test', function () {
gulp.src('external/bower_components/bootstrap-sass-official/assets/stylesheets/_bootstrap.scss')
.pipe(gulp.dest('dist/'));
});
};
This string gulp.dest('dest/') will save file _bootstrap.scss in 'dest/' folder.
If I change the string
gulp.src('external/bower_components/bootstrap-sass-official/assets/stylesheets/_bootstrap.scss')
to string
gulp.src('external/*/bootstrap-sass-official/assets/stylesheets/_bootstrap.scss')
then string
gulp.dest('dest/')
will save file _bootstrap.scss in dest/bower_components/bootstrap-sass-official/assets/stylesheets folder.
Can you explain and give me the link where to read about why in first case we have no lots of folder inside dest folder, and in the second case there are lots of folder inside dest folder?
If I understand correctly, in the second case, glob pattern will be converted to array of full files paths. It means that in my example glob nodejs module will convert glob pattern 'external/*/bootstrap-sass-official/assets/stylesheets/_bootstrap.scss' to
array ['external/bower_components/bootstrap-sass-official/assets/stylesheets/_bootstrap.scss']. So why do I have lots of nested folders inside 'dest/' folder in second case, but have no nested folders inside 'dest/' folder in first case?

Well indeed it is a little weird, since very implicit behaviour of node-glob. But in fact it is what you want to expect. For example think of the case you have multiple folders in external which will both have files bootstrap-sass-official/assets/stylesheets/_bootstrap.scss'). Then you can't save two files with the same name in your dest.
Without having looked into node-glob source, I think it mitigates this case by chopping of the files path after /*/ and will automatically attach it to your dest path.
Having said that is implicit behaviour, you can easily avoid it by assigning the array yourself gulp.src(['firstfile.js']) if you really need the array or want to add files in the future.
Since Gulp docs don't offer too much info on globbing patterns, I found those links to be the best help. Read up on node-glob and Gulp on smashing.

Related

Gulp Copy content from one file to another file

I am trying to copy the content from one file to another. I am trying the following code but its throwing me an error.
gulp
.src('core/core.config.local.tpl.js')
.pipe(gulp.dest(core/core.config.js));
Error: EEXIST: file already exists, mkdir 'C:\Users\krish\Documents\test\app\core\core.config.js'
at Error (native)
Is there any other process that I could use to copy content?
gulp.dest expects a directory as an argument. All files are written to this destination directory. If the directory doesn't exist yet, gulp tries to create it.
In your case gulp.dest tries to create a directory core/core.config.js, but fails since a regular file with the same name already exists.
If your goal is to have the regular file at core/core.config.js be overwritten with the contents of core/core.config.local.tpl.js on every build, you can do it like this:
var gulp = require('gulp');
var rename = require('gulp-rename');
gulp.task('default', function() {
gulp.src('core/core.config.local.tpl.js')
.pipe(rename({ basename: 'core.config'}))
.pipe(gulp.dest('core'));
});
I think you were missing the quotes only when entering the the question here, right?
gulp.dest() expects a folder to copy all the files in the stream, so you cannot use a single file name here (As the error says: "mkdir failed"). See: https://github.com/gulpjs/gulp/blob/master/docs/API.md#gulpdestpath-options
When you do your gulp.src() you can set a base path to build the relative path from and so gulp can copy your single file to the given output folder. See: https://github.com/gulpjs/gulp/blob/master/docs/API.md#optionsbase
As you also want to rename the file, you need something like gulp-rename: https://www.npmjs.com/package/gulp-rename

How can I dynamically require an npm dependency file loaded with webpack?

I want to do something like:
var dynamicRequire = require.context('./', true);
console.log(dynamicRequire.keys());
dynamicRequire('react/foo/bar');
But the console.log only shows files from the local directory, not the npm packages. When webpack builds i can see it get included as number 234 but the mapping from that path to that number is lost. How can I accomplish this? Thanks!
I'm not sure, what your problem exactly is here, but I suspect, that for your purpose you have just forgotten to provide require.context with second argument, which is a flag, that decides, whether the webpack should look into your subfolders and pick your files there also. So you could use require.context('./', true, [some regexp maybe ?]).
Let me know if that's not addressing your problem.

I'd like to reuse code from another module in my Nodejs backend

I'm using the Yeoman Generator Angular Fullstack and I'd like to reuse JS code from different directories within my server directory. I'm referencing the file that has the functions I want like:
var something = require('/.path');
I get the error: "Cannot find module" in my terminal.
I tried a number of variations of the path working through all of the levels from server level down to file level where the given functions are contained. I looked at a few tutorials:
http://www.sitepoint.com/understanding-module-exports-exports-node-js/
AND
https://www.launchacademy.com/codecabulary/learn-javascript/node/modules
I clearly missed something. Each module of my nodejs has a controller with an exports.create function. All of my code for each module is contained within my exports.create function accept for other required modules. I have no problem requiring underscore or other libraries in my Node/Bower modules by the way.
To be as detailed as can be, I expected
var something = require('./directory/directory.controller.js');
var something = require('/.path');
The path you are using is likely incorrect. Probably you want to open the file called path.js contained in the same folder of the file from which you are importing it. In order to do that, you should change the import as follows :
var something = require('./path');
./path is a relative path where . stands for current directory.
/.path is an absolute path. In this case require is importing a hidden file in the root directory. I guess is not what you want.

Node.js package self-reference

Can package require itself and its subsystems?
For instance there is module:
src/deep/path/to/module.js
which need to require
src/another/module.js
Instead of:
require('./../../../another/module.js');
Can one just:
require('<self>/another/module.js');
?
For instance this might be useful in testing: test unit can reference its test object without long up-and-down-style path.
I have two considerations (but they do not satisfies this issue completely):
If package is already in node_modules folder it can reference to itself by its
canonical name (that in its package.json).
Package can create symlink to itself in its own node_modules folder (sic!). Haven't try it yet, possible will lead to infinite loop in some resolving cases.
Solution 1
Split it to different sub-projects, put each one into different folders. As an example:
sub.project.1/
sub.project.2/
in sub.project.1/
# cd ../sub.project.1
npm link
# cd ../sub.project.2
npm link sub.project.1
Then in sub.project.2 you can do it simply:
var something = require("sub.project.1")
This can remove the '../../...' relative path.
Note: it can be done in same folder/project, by doing this,
in the sub folders, the project self can be easily referred.
For example when both sub.project.1 and sub.project.2 replaced by my.project. And of course, all the names should be the name in package.json initialized by npm.
Solution 2
Create a link in the folder node_modules/
# cd node_modules
ln -s .. myProjectRootDir
#
# where: .. : means parent directory in linux shell
# '#' means comments in linux shell
#
Then it can be used under same level directory trees:
var something = require("myProjectRootDir/path/to/js/file")
Thus the "../../..." can change to path read more easily.
And if myProjectRootDir happens to be the project name and
package name in package.json, it's ok.
Solution 3
There are npm packages: require-self, install-self,
they do the similar things.
Solution 4
Write a new .js file where it's easy to require,
then put all the annoying relative references into it.
For example write it at node_modules/mymods.js
// mymod.js
module.exports.mod_one = require("../path/to/mod/one.js");
//...
Then require('mymod') can gives all the other modules.
This is not the best solution, all references of requiring
need to be doing by hand. But it's a single file, so it's
manageable, and centralize the references for future deployments.
One of the cons of this solution is, if you put it in
node_modules/ folder and this folder is ignored in git repository, you need to take care when pushing or branching the git repo.
When deleting the node_modules folder, the file can also be deleted by accidents.
There could be more solutions I don't know.
Well you can shorten it a little bit. You don't need the leading ./ in this case
require("../../../another/module.js");
And a little further by removing the trailing .js
require("../../../another/module");
Another answer is suggesting the use of process.cwd() but be very careful with this. Your require calls will only work if the app is initialized from the same directory.
From the sounds of it though, 4 directories is already pretty deep. You might want to considering fragmenting your large project into smaller, single-purpose modules. We would need more information on the project to know if that was the right decision though.
I often use process.cwd() to make things like this a little more manageable. This returns where the node application is actually running from and lets you create the path in a little cleaner fashion.
Something maybe like var x = require(process.cwd() + '/lib/module')
Without seeing exactly what you're trying to do; I'm not sure if this will be helpful, but you can do things like var connect = require('express/connect') as well. Basically you can pass an installed local module, and then create paths off of it as well.

Gulpfile Javascript Concat Issue

I am trying to get my gulp file working right and I am not sure whats wrong. Here is the file. https://gist.github.com/digilord/9265640 The section I am having issues with is the js:dev. When a coffeescript file is changed it drops the resulting js file into the app/js directory. The js:dev rule isn't picking up that change. Can anyone tell me what I am missing?
Immediate solution: gulp-watch needs the glob information to find new files. You can pass your glob to its glob option. Something like:
return gulp.src('app/js/*.coffee')
.pipe(watch({glob: 'app/js/*.coffee'}))
Meanwhile if you were to use gulp.watch() it wouldn't pick up new files either but only because of a bug in its dependency, which a fix is coming soon for.
I have to also mention that your gulpfile is needlessly complex. Your coffee and js operations could be in the same stream instead of creating intermediate js files. I also don't really know why some of your streams are repeated twice. Stay dry:
var coffeeGlob = 'app/js/*.coffee';
gulp.task('js:dev', ['clean:dev'], function() {
return gulp.src(coffeeGlob)
.pipe(watch({glob: coffeeGlob}))
.pipe(coffee({bare: true}).on('error', gutil.log))
.pipe(concat('app.js'))
.pipe(gulp.dest('build/js'))
.pipe(reload());
});
As I mentioned on IRC the boilerplate you based it on might not be up to date with best practices, and I recommend basing on something newer like Yeoman's gulp generator's gulpfile.

Categories

Resources