1

I did somewhat an accident discovery that I was able to load my data-main js file in a file that doesn't load requireJS

<script type="text/javascript" src="requirejs.config.js" data-main="theme.js"></script>
<script type="text/javascript" src="requirejs.js"></script>

and it perfectly loads my theme.js file

is this an intentional feature of requirejs? or a bug?

I hope this isn't a bug.

the contents of my requirejs.config.js are below

var require = {
    baseUrl: '/js/',
    paths: {
        'jquery': "lib/jquery/jquery",
        'bootstrap': "lib/bootstrap/js/bootstrap"
    },
    shim: {
        'bootstrap': ['jquery']
    },
    map: {
        '*': {
            'jquery': 'jQueryNoConflict'
        },
        'jQueryNoConflict': {
            'jquery': 'jquery'
        }
    }
}

I check every samples here and seems they are not doing what I accidentally discovered.

http://requirejs.org/docs/api.html#data-main

2
  • From those docs - "You will typically use a data-main script to set configuration options and then load the first application module." And you're not doing that, you have a separate call for the config file and put the first application module in the data-main. I can only assume that you're getting lucky in that it's loading the scripts in the correct order by chance, it's certainly not guaranteed with that setup. Commented Nov 13, 2015 at 15:23
  • My best guess is this: RequireJS needs to use special tricks to actually "find" the script node that it was executed from. It's likely it made a mistake and assumed the first one was its origin, and then used data attributes from that one. I don't know for sure. Commented Nov 13, 2015 at 15:30

2 Answers 2

1

I've been able to reproduce the behavior your report with RequireJS 2.1.20. You can see here the code that performs the check:

if (isBrowser && !cfg.skipDataMain) {
    //Figure out baseUrl. Get it from the script tag with require.js in it.
    eachReverse(scripts(), function (script) {

The eachReverse loop looks at all script elements in reverse order. Due to the way the DOM works, only the script element that loads RequireJS and those elements before it in the HTML will be looped over because the HTML is still in the process of being parsed by the browser when this code executes. (Consequently, the DOM nodes for the script elements after the one that loads RequireJS do not exist yet.) The function in the loop searches until it runs into a script element that has data-main. It could be the one that loaded RequireJS, or it could be any before it.

I don't know whether to consider this a bug or a feature with an unexpected side-effect. One might want to change the logic to check that the src attribute of the script element also points to a file containing RequireJS. However, it seems to me this would be brittle. (It cannot be just a naive file name comparison because if you decide to change the file name, the code will break.)

Sign up to request clarification or add additional context in comments.

1 Comment

"It cannot be just a naive file name comparison because if you decide to change the file name, the code will break." well I was thinking the same reason. I was debugging same line of code and I found this github.com/jrburke/requirejs/issues/1182 what can you say about that?
0

Your data-main is on the wrong script tag

<script type="text/javascript" src="requirejs.config.js"></script>
<script type="text/javascript" src="requirejs.js" data-main="theme"></script>

Also you don't need the .js

as per the require.js docs

<!--when require.js loads it will inject another script tag
    (with async attribute) for scripts/main.js-->
<script data-main="scripts/main" src="scripts/require.js"></script>

EDIT:

Applogies... I misread the question.

I just had a quick look at the requirejs source code and the reason why this works is because it is finding all script elements (document.getElementsByTagName('script');) and iterating over them to find a data-main attribute. So actually in theory you could define more than one script with a data-main and it will load all of them.

2 Comments

I think he knows he did it wrong. He wants to know how/why this still works anyway.
applogies, misread your question. Have updated my answer which should hopefully shed some light.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.