Where does the value of "file" argument come from - javascript

Here is a code snippet from a gulp file. I'd like to understand passing of argument "file" to internal functions. More importantly, I'd like to understand this idiom because I see it often in Javascript. My guess is that "tsResult.js" iterates through various javascript files in this Typescript project and the "file" argument is each such file. How can I decipher such usage below and in future
gulp.task('scripts', ['clean'], () => {
const tsResult = tsProject.src().pipe(sourcemaps.init()).pipe(tsProject());
return tsResult.js.pipe(sourcemaps.write({
includeContent: false,
sourceRoot: function (file) {
return path.relative(path.dirname(file.path), file.base);
}
}))
.pipe(gulp.dest(OUTPUT_FOLDER));
});

Many JS libraries make heavy use of a design pattern called Dependency Injection.
Basically, gulp-sourcemaps is giving you the option of overriding how the source root (the root URL where the file is located) is determined.
From the gulp-sourcemaps documentation:
Set the location where the source files are hosted (use this when includeContent is set to false). This is usually a URL (or an absolute URL path), not a local file system path. By default the source root is '' or in case destPath is set, the relative path from the source map to the source base directory (this should work for many dev environments). If a relative path is used (empty string or one starting with a .), it is interpreted as a path relative to the destination. The plugin rewrites it to a path relative to each source map.
The sourceRoot function is called, passing in the file that is currently being processed, and is expected to return the root path.

Related

Is it necessary to specify directory when using appendFileSync?

I'm going through some of the nodejs documentation and starting to familiarize myself with some of the more basic functions. Specifically looking at appendFileSync function.
When trying to append a file, is it necessary to specify the directory? I don't recall this being a requirement in previous versions of Node but it seems when the directory is not specified, a new file is created in the root instead of appending the file.
I'm just trying to append a basic txt file, with this it creates a new file:
const fs = require('fs');
fs.appendFileSync('notes.txt', 'Changing the text with appendFileSync');
However, when specifying the directory, it appends the file just fine making me think this is required:
const fs = require('fs');
fs.appendFileSync('./nodejs/notes-app/notes.txt', ' Colin, changed the
text with appendFileSync', function (err) {
if (err) throw err; console.log('Notes updated');
});
Node -v 12.13.0
NPM -v 6.12.0
As with all fs operations that take a file path, if you don't specify any sort an absolute path, then the path you do specify is combined with the current working directory. In a nodejs program, the default current working directory (if you don't change it programmatically) is taken from the environment in which you started the node program.
If want to control the path directly without regard to the current working directory, then specify an absolute path.
This is what the fs module documentation says about file paths:
String form paths are interpreted as UTF-8 character sequences identifying the absolute or relative filename. Relative paths will be resolved relative to the current working directory as specified by process.cwd().
Note: For some situations, a developer wants to access the file system relative to the installation of the module that is running. That is typically done by building a path that is relative to __dirname which is the location of the current module like this.
path.join(__dirname, "somefile.txt");
Of course, you can always specific a full path name starting from root if you want.

Noticed a context property being passed to webpack along with my configuration. Where does it come from?

I'm trying to understand how the internals of webpack work in order to contribute in the future. I noticed that when running webpack the webpack function in /lib/webpack.js fires with an options argument.
The value of this argument is my configuration object defined in webpack.config.js PLUS a context property that I never defined. Where does this context property come from? Is there a step that occurs before the webpack function fires?
Webpack needs to know where to start looking for files, which you will reference in either your Webpack config file or your JS source files that will be processed by Webpack.
By default, it reverts to the current working directory of where the CLI was used -- commonly the same directory where your Webpack config file exists -- however, you should always define this manually using the context key in your Webpack Config file (see https://webpack.js.org/configuration/entry-context/#src/components/Sidebar/Sidebar.jsx).
Webpack also uses this directory path (absolute path) as the prefix for any module resolution / aliasing used throughout in your source files, etc.

Can not get the js file in using requirejs

I'm trying to build client project using requireJs.
But when I published it on the nginx server, an error occurred.
This is my project directory structure
when it ran here, the browser threw a js error.
require(['config/require.conf'], function(){
'use strict';
require(['src/common/js/pageloader'], function(pageloader){
pageloader();
})
})
js error:
GET http://localhost:8011/src/homepage/config/require.conf.js require.js:1961
It seems like the error occurred because I use the relative path (lack of '/').
However, I add the slash as prefix of directory('/config/require.conf').
As a result, when the browser ran here, requirejs didn't add the suffix ".js" for the js file(config/require.conf.js).
Another error occurred~
GET http://localhost:8011/config/require.conf 404 (Not Found)
What should I do for the error? Thanks.
You can pass two things in the dependency list of a require call:
A module name. This is the default. When you pass a module name, RequireJS will convert the name to a path using baseUrl, paths, map, etc. from your RequireJS configuration.
A path. RequireJS considers that you are passing a path if the dependency: a) begins with '/', (which is your case), b) contains an HTML query (e.g. 'foo?bar=1'), c) ends with the .js extension, d) specifies a protocol (e.g. https://).
In this case, RequireJS uses the path as-is, without using its configuration to transform it, and it does not automatically add a .js extension to it.
Your usage is the 2nd case so you have to add .js to your path so that RequireJS can find your file:
require(['/config/require.conf.js'], function() {

Can not understand behavior of gulp.src()

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.

nodeJS require.paths resolve problem

I am trying to require a file relatively and mysteriously the following is happening
This works well which points to /Users/marcos/Desktop/Taper/lib/utils.js
myPath = "/Users/marcos/Desktop/Taper/lib/./utils";
require(myPath);
This doesn't but it should point to exactly the same file:
require.paths.unshift("/Users/marcos/Desktop/Taper/lib")
require("./utils"); //Doesn't work with './'
require("utils"); //Works Fine
Anyone knows why I can't still use ./ in this case for loading the path since
require("path").resolve("/Users/marcos/Desktop/Taper/lib", "./utils")
results in:
"/Users/marcos/Desktop/Taper/lib/utils"
anyway?
Thanks in advance
UPDATED:
From the documentation:
A module prefixed with '/' is an absolute path to the file. For
example, require('/home/marco/foo.js') will load the file at
/home/marco/foo.js.
A module prefixed with './' is relative to the file calling require().
That is, circle.js must be in the same directory as foo.js for
require('./circle') to find it.
Without a leading '/' or './' to indicate a file, the module is either
a "core module" or is loaded from a node_modules folder.
If the given path does not exist, require() will throw an Error with
its code property set to 'MODULE_NOT_FOUND'.
Here’s the original answer, which refers to require.paths (which is no longer supported):
From the documentation:
In node, require.paths is an array of strings that represent paths to be searched for modules when they are not prefixed with '/', './', or '../'.
(emphasis mine)
You can pass that using NODE_PATH
Example:
NODE_PATH=`pwd` node app.js
I created a new node module called rekuire.
It allows you to "require" without using relative paths.
It's a big time saver when it comes to testing/refactoring.
https://npmjs.org/package/rekuire

Categories

Resources