I hope to explain this in a non-abstract way. I have a problem and I believe that I am pushing the boundaries of Node because there doesn't seem to be much documentation on this particular subject.
To start out, this is my file layout.
//main.js
var 1 = require('1.js');
var 2 = require('2.js');
The purpose of this first file is to load two child files into the process.
//1.js
console.log('Test');
module.exports = function msgUSR(text){
console.log(text);
}
The purpose of this file is to create an export, this export could very obviously be imported into Main.js , however, I have a situation where I need to import a function from 1.js into 2.js without reloading the entire file into memory.
for example.
//2.js
var msgUSR = require('1.js');
msgUSR('blah');
The problem with this setup is that when you require 1.js, it reloads the entire file, including any code that isn't an export.
How could I only import the exports of a file without loading the unrelated code.
Thank you! I know someone has a solution to this.
EDIT:
I understand that the code here wouldn't replicate any useful data. My point is, how do I require a function in another JS file that is already required by a parent file. Instead of writing two long hefty functions that are exactly alike in two different files, I need to be able to call the function from a sister file.
Here is why this is an issue.
If you were to require the file after the parent has required it, 'Test' would appear two times, symbolically meaning that other complex code would also be loaded.
My hopeful result from this question would be a result where I could require the file in such a way as to only import a function from it.
Thanks again.
The problem with this setup is that when you require 1.js, it reloads
the entire file, including any code that isn't an export.
When you require something the file will be loaded once and then is cached
How could I only import the exports of a file without loading the
unrelated code?
You would never have to reload the file once it is already required since Node will use the cached version.
The require function normally has 5 steps:
Resolving: To find the path of the file
Loading: To determine the type of the file content
Wrapping: To give the file its private scope. This is what makes both the require and module objects local to every file we require.
Evaluating: This is what the VM eventually does with the loaded code.
Caching: So that when we require this file again, we don’t go over all the steps another time.
Related
When we have this syntax
const { somePart } = require('./someModule');
Does the compiler loads entire module in RAM to get that part?
Consider that somePart is a small amount of code, while someModule is 1GB file.
If yes, is there a way to get a part of a large module without loading all of it?
Thanks.
PROBLEM DESCRIPTION.
I'm trying to follow https://github.com/lucascosta/facebook-js-ads-sdk to install the Javascript SDK for Facebook. Before anyone objects, I am absolutely aware of the compact version (https://developers.facebook.com/docs/javascript/quickstart), but that API is absolutely useless to me. I need the one produced by Lucas Costa, in order to be able to make changes to my ads account, which the recommended script by Facebook does not enable.
As usual installation instructions (see github.com/lucascosta/facebook-js-ads-sdk) are horribly predicated on mysterious conditions, that are unbeknown to me. I cannot get the SDK to work and would like someone to tell me explicitly what to do. The crux of the problem is the paradoxical situation: I am supposed to use a require('...') command (where??) to include the SDK (where is this supposed to be saved??) and yet require cannot be used on folders, but on scripts. Maybe somewhere there is a require.config file, I'm supposed to set up, but I have no idea, as, like I said, the instructions completely bypass any mention of the necessary starting conditions.
Here is what I have done so far. My folder-structure looks like this (I don't even know if this is right, as no-one explains it anywhere!):
[Serverroot]
— [folder with my website]
– facebook-ads-sdk (the folder one gets by downloading)
– css — pagestyles.css
– js — lib
require.js
— app
( some header scripts )
– img
( some images )
index.php
In index.php I have a block of html followed by some javascript. It is here, that I try to insert the setup / example code from . The browser cannot even get past the line const adsSdk = require('facebook-ads-sdk');. I have tried a number of things: require('./facebook-ads-sdk');, moving all this to the folder ./js/app in a script main.js and then writing in my html in index.php where main and require are located. Setting up a require.config (or requirejs.config) replacing require by requirejs, etc. and including the appropriate scripts in the <head> part of index.php. Nothing helps. Here are the errors: first with const adsSdk = require('facebook-ads-sdk'); I get
Error: Module name "facebook-ads-sdk" has not been loaded yet for context: _. Use require([])
Okay. How do I ‘load the Module for the context _’?? Reading requirejs.org/docs/start.html is of no help here. I tried require([], function() {require('facebook-ads-sdk')}); Same error. I tried require(['facebook-ads-sdk']);
I tried using the following commands in my script in index.php:
require.config({
shim: {
'facebook': {
exports: 'adsSdk',
},
},
paths: {
'sdk': './facebook-ads-sdk',
}
});
var adsSdk = require(['sdk']);
Then I get the error
Failed to load resource: http:// .... /facebook-ads-sdk.js the server responded with a status of 404 (Not Found)
Ie, the browser thinks I'm trying to include a script facebook-ads-sdk.js, but I’m supposed to(???) ‘require’ the entire folder! What is going on? Can someone please give me thorough instructions about the necessary folder structure and command, in order to get this SDK working?
Why is this so infuriatingly vaguely described online? Is there some kind of mysterious way of installing SDKs, about which ‘everyone’ knows, but never mentions?
UPDATE: SOLUTION. For any future google-searches for this same problem: via the following simple methods, one can install & embed the Javascript-FB-Ads-SDK:
install via npm install --save facebook-ads-sdk a copy of the npm modul Lucas Costa’s facebook-ads SDK.
Copy this folder to your website’s architecture (actually you possibly just need one subfolder / file).
in your HTML include the script (via <script type='text/javascript' src='...'></script>) with the src pointing to the file in the facebook-ads-sdk folder: /dist/iife.js.
In your page’s script, you now have access to then API via the global variable fb.
alternatively to 3:
3’. in your HTML headers make sure to include the require.js script via a <script>-tag. Then in your website’s javascript apply the following commands anywhere:
require.config({
paths: {
'sdk': './[FOLDERNAME OF SDK]/dist/iife',
}
});
require(['sdk']);
Credit and special thanks goes to #SLaks and #KhauriMcClain (I would give you up-points if I could) for this solution.
The instructions are assuming that you're using a bundling system like Webpack or Browserify.
If you are, the instructions "just work"; you can require() it and everything will work fine.
If you're building a non-trivial codebase, you really should use such a system.
If you aren't, you can reference iife.js in a <script> tag and that will create global variables.
You need to change the way you are using require.
You cannot use the synchronous require method to load dependencies if they have not been loaded before. Hence const adsSdk = require('facebook-ads-sdk'); will not work. You will need to use the form require(['name-of-script'], callback).
Require does not allow you to load an entire folder. You have to find the exact script you are trying to work with so var adsSdk = require(['sdk']); will not work.
Ultimately your code should look something like:
require(['some-facebook-script'], function(someFacebookScript) {
// Do some work here
});
The parameter passed to the callback function will be the loaded module you are trying to consume. When using the asynchronous version (as I just demonstrated) the return from require is not useful.
I have the following situation.
EntryA
require("./test.js");
EntryB
require("./test.js");
test.js
module.exports = "something";
I want tuse webpack to compile these javascript files. On the html page i just want to include the EntryA.js. Every thing that is common between EntryA and EntryB should come in a sperate file. Now, when test.js is required, that common file should be downloaded from the net.
is this possible and ghow should i proceed?
Webpack offers two ways to split out your JS.
Use multiple entry points (As you have done).
Define split points via require.ensure (or System.import in Webpack 2).
Approach 1 is really intended to be used by traditional 'multi' page websites and requires you to import the appropriate entry point on the correct page. NOTE: You can use the CommonsChunkPlugin to extract out all the shared code but it still must be manually referenced.
Approach 2 is more geared towards single page apps and will automatically load in new scripts as necessary.
I'm in the process of converting a Grunt file to a Gulp file. My Grunt file contains the following line
var config = grunt.file.readJSON('json/config.json');
What this line is doing is that it is setting some variables which it then injects into the html it generates, specifically related to languages.
I tried converting the file automatically with grunt2gulp.js but it always fails with config being undefined. How would I write grunt.file.readJSON using gulp?
The easiest way to load a JSON file in node/io.js is to use require directly:
var config = require('json/config.json');
This can substitute any readJSON calls you have and also works generally. Node/io.js have the ability to synchronously require json files out of the box.
Since this is a .json file, Benjamin's answer works just fine (just require() it in).
If you have any configs that are valid JSON but not stored in files that end in a .json extension, you can use the jsonfile module to load them in, or use the slightly more verbose
JSON.parse(require('fs').readFileSync("...your file path here..."))
(if you have fs already loaded, this tends to be the path of least resistance)
The one big difference between require (which pretty much uses this code to load in json files) and this code is that require uses Node's caching mechanism, so multiple requires will only ever import the file once, and then return points to the parsed data, effectively making everything share the same data object. Sometimes that's great, sometimes it's absolutely disastrous, so keep that in mind
(If you absolutely need unique data, but you like the convenience of require, you can always do a quick var data = require("..."); copied = JSON.parse(JSON.stringify(data));)
I have just started working with nodejs. I wonder if there is a way to "require" a file only once in an app. I am using a class framework for getting classic OOPS in my JS project. Each "class" is contained in its own JS file. I want to "require" the class framework in each file so that they can function independently but want the framework's init code to be executed only once.
I can use a flag to implement this myself but a built-in way would be nice. Search for "require once" leads me to all PHP related questions.
require is always "require once". After you call require the first time, require uses a cache and will always return the same object.
Any executable code floating around in the module will only be run once.
On the other hand, if you do want it to run initialisation code multiple times, simply throw that code into an exported method.
edit: Read the 'Caching' section of http://nodejs.org/docs/latest/api/modules.html#modules
If you really want the top level code in your module (code that is not contained within methods or functions in your module) to execute more than once you can delete it's module object that is cached on the require.cache object like this:
delete require.cache[require.resolve('./mymodule.js')];
Do this before you require the module for the second time.
Most of the time though you probably only want the module's top level code to run once and any other time you require the module you only want to access what that module exports.
var myMod = require("./mymodule.js"); //the first time you require the
//mymodule.js module the top level code gets
//run and you get the module value returned.
var myMod = require("./mymodule.js"); //the second time you require the mymodule.js
//module you will only get the module value
//returned. Obviously the second time you
//require the module it will be in another
//file than the first one you did it in.