0

I am trying to work out if the following statements actually execute JavaScript - does bundle.js run, or is it just that the functions in bundle.js get loaded ready for some later statement to execute them?

Same question regarding var X = require('X');

My understanding is that this loads X.js into memory but does it initialize code? Or does the var = just load functions into memory?

<body >
</div>
    <script src="http://localhost:3000/dist/bundle.js"></script>
      <script type="text/javascript">
      (function () {
        var X = require('X');
        X(mountNode, endpointsRoot, locale, user);
      })();
      </script>

</body>
NiRUS
  • 3,901
  • 2
  • 24
  • 50
Duke Dougal
  • 24,359
  • 31
  • 91
  • 123
  • Yes, `` are executed, not only loaded. What they *do* we don't know without the content of the script, of course. – Bergi Dec 08 '15 at 03:56
  • the above code should throw an error *module not loaded*. Clientside AMD is quite different refer the comparision http://stackoverflow.com/questions/17446844/dynamic-require-in-requirejs-getting-module-name-has-not-been-loaded-yet-for-c – NiRUS Dec 08 '15 at 05:50
  • @nirus I'm running it through webpack with browserify - am I correct in understanding that this would resolve the require? – Duke Dougal Dec 08 '15 at 06:01
  • ok well then i have explained by considering the two libraries – NiRUS Dec 08 '15 at 18:10

2 Answers2

1

Ok to start off, The JavaScript is executed in the order you have defined it in the document, either its a piece of code or a physical file the script tag points to, but the complete parsing depends on the file size and network response hence multiple files start off in ascending order as defined and finish loading at different time intervals.

You can make script loading asynchronous by using defer and async attributes. Link.

To understand the execution flow checkout this stackoverflow link who has similar piece of code using jquery.

To get a clear answer to your question please read below to get a clear picture of respective libraries

RequireJS (AMD):

RequireJS lookup firstly happens by name of the JS file defined in config in entrypoint or as dependency defined in array of require methods.

Please read this link RequireJS

For example let see the below code:

bundle.js

define("X", [],function(){ //named definition without any dependencies.
  return function() {
    alert("Loaded");
  } 
});

index.html

<body>
<script src="require.js" type="text/javascript" charset="utf-8"></script>
<script src="bundle.js"></script>
<script type="text/javascript">
    require(["require", "X"],function (require) { //"X" is defined in the array of require definition
     var X = require("X");
     X();
    });
</script>
</body>

All the dependencies are wired-up with a callback in AMD to solve the loading time difference, in the sense these modules are made available when the callback is executed with the required modules loaded in the memory.

Browserify:

Emulates the Node JS module loading for client side on the browsers.

How stuff works:

Extra build step does the trick in concatenating all the dependency function definition that will be made available before require functions. All the code file are bundled into one single file which becomes available in a single scope at the runtime. Similar can be achieved in RequireJS using r.js optimizer.

Please read this link about browserify

Example code for illustrations:

mod1.js:

module.exports = function(){    
    alert("Loaded");
};

Build command:

browserify -r ./mod1.js:mod > bundle.js

This generates a file called bundle.js with a module name mod which can be included in the index.html as below

<body >
<script src="bundle.js"></script>
<script type="text/javascript">
      (function () {
        var X = require('mod');
        X();
      })();
      </script>
</body>

Here browserify stiches all the JS file starting from entrypoint code (Here its mod1.js) and recursively searches for require api and construct a closure scope on top of these modules.

Hence your bundle.js looks as below

require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"mod":[function(require,module,exports){
module.exports = function(){    
    alert("Loaded");
};
},{}]},{},[]);

Conclusion:

Browserify: Functions are loaded at one shot as all the files are concatenated into one single JS file. Hence all the definition and functions share the same closure scope and get initialized and made available in the memory. When you require a module definition-> If its a variable the value is returned or if its a function then pointer the function is returned where you can make a functional call.

AMD as RequireJS: This is quite different comparatively as the files are loaded on require call execution at runtime, which later executes the callback attached to that require definition once all the dependencies are resolved. Hence in this method memory is overloaded with functions progressively as and when require call happens (this is called as Lazy - loading).


Note: r.js is requireJS plugin used to optimize and concat all the JS file, same as browserify.

Community
  • 1
  • 1
NiRUS
  • 3,901
  • 2
  • 24
  • 50
0

Yes, that Javascript anonymous function is executed.

bundle.js is loaded in memory until its executed later. If bundle.js contains only definitions and no calls nothing will get executed but loaded in memory.

Require('X') loads 'X' into memory and initializes the code.

May be if you can share bundle.js and 'X' code it will be possible to identify functional calls.

s007
  • 728
  • 6
  • 12
  • You say bundle.js is executed later or by itself? Not quite sure what you mean can you explain further? The common by @bergi indicates that script tags are executed. – Duke Dougal Dec 08 '15 at 04:24
  • 1
    Execution of _script_ tags means execution of script content. Execution of script with just function definitions and no function call means "loading in memory only". If bundle.js contains only definitions and no calls nothing will get executed but loaded in memory. – s007 Dec 08 '15 at 04:39
  • 1
    @s007: I'd still call that execution. Function declarations do, after all, still write values into global variables. – Bergi Dec 08 '15 at 04:49
  • 1
    @s007: You should at least add that "*If bundle.js contains only …*" part to the second sentence of your answer, it's essential. – Bergi Dec 08 '15 at 04:51
  • So if X.js contains multiple functions, which function within X.js exactly gets assigned to X by the statement var X = require('X'); – Duke Dougal Dec 08 '15 at 05:59