Javascript: get package.json data in gulpfile.js - javascript

Not a gulp-specific question per-se, but how would one get info from the package.json file within the gulpfile.js; For instance, I want to get the homepage or the name and use it in a task.

This is not gulp specific.
var p = require('./package.json')
p.homepage
UPDATE:
Be aware that "require" will cache the read results - meaning you cannot require, write to the file, then require again and expect the results to be updated.

Don't use require('./package.json') for a watch process, as using require will resolve the module as the results of the first request.
So if you are editing your package.json those edits won't work unless you stop your watch process and restart it.
For a gulp watch process it would be best to re-read the file and parse it each time that your task is executed, by using node's fs method
var fs = require('fs')
var json = JSON.parse(fs.readFileSync('./package.json'))

This is a good solution #Mangled Deutz. I myself first did that but it did not work (Back to that in a second), then I tried this solution:
# Gulpfile.coffee
requireJSON = (file) ->
fs = require "fs"
JSON.parse fs.readFileSync file
Now you should see that this is a bit verbose (even though it worked). require('./package.json') is the best solution:
Tip
-remember to add './' in front of the file name. I know its simple, but it is the difference between the require method working and not working.

If you are triggering gulp from NPM, like using "npm run build" or something
(This only works for gulp run triggers by NPM)
process.env.npm_package_Object
this should be seprated by underscore for deeper objects.
if you want to read some specific config in package.json like you want to read config object you have created in package.json
scripts : {
build: gulp
},
config : {
isClient: false.
}
then you can use
process.env.npm_package_**config_isClient**

Related

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.

"Uncaught ReferenceError: require is not defined" with Angular 2/webpack

I am working an HTML template from a graphic design company into my Angular 2 project using node and webpack.
The HTML pulls in various scripts like this:
<script src="js/jquery.icheck.min.js"></script>
<script src="js/waypoints.min.js"></script>
so I am requiring them in my component.ts:
var icheckJs = require('../js/jquery.icheck.min');
var waypointsJs = require('../js/waypoints.min');
There are several other scripts too and some SASS which appears to be working correctly.
webpack is happy and build it all and an 'npm start' is successful too. However, when it reaches the browser, I get this complaint:
Uncaught ReferenceError: require is not defined node_modules/angular2/platform/browser.js:1 Uncaught ReferenceError: require is not defined
which is actually thrown by this line from url.js:
var punycode = require('punycode');
Is this a CommonJs require? I hadn't used this in web development before a few weeks ago so I'm still untangling the various requires from webback, CommonJs et at.
An extract from my webpack.config.js for the .js loader looks like this:
{ test: /\.js$/, loader: 'script' }
How do I work around this error?
WebPack can do this alone. You need to make sure you load the initial chunk first using a script src tag. It will typically be the value of the entry: key in the WebPack config with -bundle appended. If you're not doing explicit chunking, your entry chunk should be both an initial and entry chunk and have the WebPack runtime in it. The WebPack runtime contains and loads the require function before your code runs.
Your components or whatever you're requiring need to be required from the entry file since your scripts will start there. Basically, if you're not explicitly chunking, the entry point JS file is the only one you can include with script src. Everything else needs to be required from it. What you include will typically have bundle in the JS filename. By default, it should be main-bundle.js.
For anyone that is looking for an answer but the above doesn't work:
Short
Add or Replace current target in webpack.config.js to target: 'web'
A bit longer
Webpack has different targets, if you've experimented with this and changed your target to node it will use 'require' to load chuncks.
The best thing is to make your target (or to add) target: 'web' in your webpack.config.js. This is the default target and loads your chuncks in a way the browser can handle.
I eventually found this solution here.
You can do this in one line assumed that you have
the bundle in dist/bundle.js
the source file client code that will render the page in the browser in
client/client.js
webpack && webpack ./client/client.js dist/bundle.js \
&& webpack-dev-server --progress --color
You need to run webpack again since if some sources in the library change you will get the last changes then in the dist/bundle.js package (of course you can add like a grunt file watch task for this). webpack-dev-server will run the server then.

Module not found when using rekuire, requirish, or rfr to solve nodejs require relative issue

I'd like to avoid the complex relative path issue described here by using one of the recommended solutions. I've come across three similar libraries:
rekuire
node-rfr aka Require from Root
requirish
I've tried all three and all are failing with "module not found" or a similar error which makes me believe I'm doing something fundamentally wrong. I'm relatively inexperienced with npm/node. I'm only using node in the browser using browserify to bundle my app into a single JS file.
Here's my extremely simple hello world example:
Structure:
lib/Bob.js
app.js
Bob.js
function Bob() {
return "I am bob";
}
module.exports = Bob;
app.js
var Bob = require('./lib/Bob.js');
console.log(Bob());
Bundling into a single JS:
browserify app.js -o bundle.js
Chrome's console successfully outputs "I am Bob".
Now if I try and of the libraries, let's say requirish:
REQUIRISH:
npm install requirish
app.js changes
'use strict';
require('requirish')._(module);
var Bob = require('lib/Bob');
console.log(Bob());
Bundling changes
browserify -t requirish app.js > bundle.js
I get the following error:
Error: Cannot find module '/lib/Bob' from '/Users/ngb/projects/MyApp/src/main/resources/public/js/hello'
at /Users/ngb/.nvm/v0.10.30/lib/node_modules/browserify/node_modules/resolve/lib/async.js:42:25
RFR:
'use strict';
var rfr = require('rfr');
var Bob = rfr('lib/Bob');
console.log(Bob());
Building
browserify app.js -o bundle.js -d
Chrome's console outputs the following error:
Uncaught Error: Cannot find module 'lib/Bob'
The Browserify can find module by parse string "require".
If you want to use both side client and server, use rfr for server side and browserify-rfr for browserify's transform.
In my opinion, the "rfr" is the best because this module does not override original require.
------- Notice! Additional Information,
As today browserify-rfr version leaves my local file path to bundle.js. This may cause another problem, so I chose requirish. Since the requirish changes behavior of original require by pushing a new path to module.paths, you always notice that and alert your coworker!
thanks!
https://www.npmjs.com/package/requirish

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.

browserify detect custom require()

I want to use a custom require() function in my application.
Namely I have node's standard require() and a custom one I wrote to require files starting from the root called rootRequire() which internally all it does is:
// rootRequire.js
var path = require('path');
var rootPath = __dirname;
global.rootRequire = function (modulePath) {
var filepath = path.join(rootPath, modulePath);
return require(filepath);
};
module.exports = rootRequire;
But even though rootRequire() internally uses node's require(), it does not pick up any files required through that method
Example:
require('rootRequire.js');
rootRequire('/A.js'); // server side it works, in the browser I get an error saying can't find module A.js
Perhaps, this will answer your question on why it is not working on browser.
Quoting the owner's comment: "Browserify can only analyze static requires. It is not in the scope of browserify to handle dynamic requires".
Technically, you are trying to load files dynamically from a variable with your custom require. Obviously, node.js can handle that.
In case of browserify, all requires are statically loaded and packaged when you run the CLI to build the bundle.
HTH.
What i recommend doing here is this:
First create a bundle to be required of anything you might use in rootRequire().
Something like browserify -r CURRENT_PATH/A.js -r CURRENT_PATH/B.js > rootRequirePackages.js
Then, in your webpage, you can include both rootRequirePackages.js and your regular browserified file.
Perhaps just use RequireJS ? It's simple to set up and relatively easy to use.

Categories

Resources