require.main === undefined

180 views
Skip to first unread message

Kris Kowal

unread,
Mar 24, 2010, 6:56:55 PM3/24/10
to comm...@googlegroups.com
This is a grievance brought up by Hannes regarding the Modules/1.1.1
proposal. The proposal states that require.main *must* be an empty
object if there is no "main" module. Hannes would prefer that it be
"undefined" if there is no module. The latter view makes 1.1.1 a
strict extension of 1.0, since previous versions did not have a .main
and would therefore be undefined.

Mikael, can you clarify the problem?

Kris Kowal

Charles Jolley

unread,
Mar 24, 2010, 6:58:37 PM3/24/10
to comm...@googlegroups.com
I agree with Hannes model - though I personally don't care. The big reason is that if require.main === {} there is no way to tell if that means there is no main module or if the main module just happens to have no exports.

-Charles

> --
> You received this message because you are subscribed to the Google Groups "CommonJS" group.
> To post to this group, send email to comm...@googlegroups.com.
> To unsubscribe from this group, send email to commonjs+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/commonjs?hl=en.
>

Kris Kowal

unread,
Mar 24, 2010, 7:00:01 PM3/24/10
to comm...@googlegroups.com
On Wed, Mar 24, 2010 at 3:58 PM, Charles Jolley <cha...@sproutit.com> wrote:
> I agree with Hannes model - though I personally don't care.  The big reason is that if require.main === {} there is no way to tell if that means there is no main module or if the main module just happens to have no exports.

That's not the case; require.main must be the "module" not the
"exports", which means that if there is a main module, the "id"
property must at least be defined.

Kris Kowal

Wes Garland

unread,
Mar 24, 2010, 7:03:40 PM3/24/10
to comm...@googlegroups.com, comm...@googlegroups.com
There is no way for require.main to be strictly equal to an object
initializer. Different objects are never equal - strictly or otherwise
- in JavaScript.

We'd

Sent from my iPhone

Hannes Wallnoefer

unread,
Mar 24, 2010, 7:16:43 PM3/24/10
to comm...@googlegroups.com
2010/3/24 Kris Kowal <kris....@cixar.com>:

> This is a grievance brought up by Hannes regarding the Modules/1.1.1
> proposal.  The proposal states that require.main *must* be an empty
> object if there is no "main" module.  Hannes would prefer that it be
> "undefined" if there is no module.  The latter view makes 1.1.1 a
> strict extension of 1.0, since previous versions did not have a .main
> and would therefore be undefined.

Sorry for depositing my objection in the voting thread. Since you
started a new thread I'll write a few more words to explain my view:

As Daniel pointed out on the original thread, require.main == module
will throw a ReferenceError if both sides are undefined and module is
not declared. The only way this could fool you is by having something
like

var module;
if (require.main === module) ...

which is highly unlikely and easily debuggable. So with other things
the same, it's easier to check for require.main than for, say,
require.main.id or require.main.uri.

Hannes

> Mikael, can you clarify the problem?
>
> Kris Kowal
>

Mikeal Rogers

unread,
Mar 24, 2010, 7:18:21 PM3/24/10
to comm...@googlegroups.com
The problem is that Modules 1.0 didn't define a "module" object so modules written for Module 1.1 with this statement:

if (require.main === module) { }

Always evaluate to true because both are undefined, which is exactly the opposite behavior that you want. The change is so that modules written for 1.1 are backwards compatible with 1.0, without the change the comparisons fail.

Note that this does not effect existing 1.1 implementations because module is not undefined so the comparison will still fail.

-Mikeal

Kris Kowal

unread,
Mar 24, 2010, 7:21:21 PM3/24/10
to comm...@googlegroups.com
On Wed, Mar 24, 2010 at 4:18 PM, Mikeal Rogers <mikeal...@gmail.com> wrote:
> The problem is that Modules 1.0 didn't define a "module" object so modules
> written for Module 1.1 with this statement:
>
> if (require.main === module) { }
>
> Always evaluate to true because both are undefined, which is exactly the

Ah, I see where you're coming from. This is actually not the case.
"module" is an undeclared free variable in 1.0, so this expression
will actually throw an error, not evaluate to true. I think it's safe
for "main" to be undefined if there's no module.

Kris Kowal

Mikeal Rogers

unread,
Mar 24, 2010, 7:32:22 PM3/24/10
to comm...@googlegroups.com
There is something strange about my eval environment because I don't get an exception, but it doesn't really matter, once I implement the spec with the other changes this problem goes away entirely.

-Mikeal

Charles Jolley

unread,
Mar 24, 2010, 7:38:40 PM3/24/10
to comm...@googlegroups.com
OK I misread the spec. If main points to the module object then it is probably better to have an empty object so that this works:

if (!require.main.id) {
// no main module
}

Mikeal Rogers

unread,
Mar 24, 2010, 7:58:21 PM3/24/10
to comm...@googlegroups.com
wow, i didn't even think about this but it's a really good point.

Hannes Wallnoefer

unread,
Mar 24, 2010, 8:13:44 PM3/24/10
to comm...@googlegroups.com
2010/3/25 Charles Jolley <cha...@sproutit.com>:

> OK I misread the spec.  If main points to the module object then it is probably better to have an empty object so that this works:
>
> if (!require.main.id) {
>  // no main module
> }

How is this better than the if (!require.main) we currently have?

Charles Jolley

unread,
Mar 24, 2010, 8:19:00 PM3/24/10
to comm...@googlegroups.com
>>
>> if (!require.main.id) {
>> // no main module
>> }
>
> How is this better than the if (!require.main) we currently have?

if (require.main.id === module.id) {
// this module is main
} else {
// this module is not main - in fact there may be no main at all!
}

vs

if (require.main && (require.main.id === module.id)) {
...
} else {
...

Ash Berlin

unread,
Mar 24, 2010, 8:22:56 PM3/24/10
to comm...@googlegroups.com
On 25 Mar 2010, at 00:19, Charles Jolley wrote:
>>> if (!require.main.id) {
>>> // no main module
>>> }
>>
>> How is this better than the if (!require.main) we currently have?
>
> if (require.main.id === module.id) {
> // this module is main
> } else {
> // this module is not main - in fact there may be no main at all!
> }
>
> vs
>
> if (require.main && (require.main.id === module.id)) {
> ...
> } else {
> ...
> }
>

Err, redundant. The spec says that if require.main is referentially identical to the 'module' object from the main module.

if (require.main === module) {
}

Done. No need to check the id's match as the *objects* are identical.

Charles Jolley

unread,
Mar 24, 2010, 8:25:04 PM3/24/10
to comm...@googlegroups.com
OK you win. :-)

Anyway - for me Modules 1.1.1 is OK as is or could change to allow require.main === undefined. I am convinced that both are equally easy.

-C

Wes Garland

unread,
Mar 24, 2010, 9:13:07 PM3/24/10
to comm...@googlegroups.com
On Wed, Mar 24, 2010 at 7:32 PM, Mikeal Rogers <mikeal...@gmail.com> wrote:
There is something strange about my eval environment because I don't get an exception, but it doesn't really matter, once I implement the spec with the other changes this problem goes away entirely.

Are you using strict-mode?  Do you have an error reporter? 

[~/hg/gpsee/embrace/gpsee-js] WesMac-3:wes# ./gpsee-js
js> options("strict");
"anonfunfix"
js> var require=function() {};
js> require.main === module;
typein:3: strict warning: reference to undefined property require.main
false

 or, in an evalcx scope:

[~/hg/gpsee/embrace/gpsee-js] WesMac-3:wes# ./gpsee-js
js> options("strict");
"anonfunfix"
js> var scope=evalcx('');
js> scope.require = function(){};
(function () {})
js> evalcx("require.main === module", scope)
typein:5: strict warning: reference to undefined property require.main
typein:5: ReferenceError: module is not defined
js>

Either way, you should be get a thrown ReferenceError and hopefully a strict mode warning (I am a big fan of strict mode :) )

Can you describe what environment you have that does not throw an exception when you try to reference an undefined property of an object?  The only ways to accomplish that, that I can think of, involve native classes with catch-alls.  And I would argue, really really vehemently, that neither require, nor Function.prototype or Object.prototype be implemented with catch-alls.

Wes




--
Wesley W. Garland
Director, Product Development
PageMail, Inc.
+1 613 542 2787 x 102

Hannes Wallnoefer

unread,
Mar 25, 2010, 1:51:37 AM3/25/10
to comm...@googlegroups.com
2010/3/25 Charles Jolley <cha...@sproutit.com>:

> OK you win. :-)
>
> Anyway - for me Modules 1.1.1 is OK as is or could change to allow require.main === undefined.  I am convinced that both are equally easy.

Except we have to change (according to the spec page) 7 perfectly
working sets of code.

I'm sorry, but changing a ratified spec based on the misapprehension
of a single person does not exactly boost my confidence in this whole
process.

Hannes

Kris Kowal

unread,
Mar 25, 2010, 1:55:04 AM3/25/10
to comm...@googlegroups.com
On Wed, Mar 24, 2010 at 10:51 PM, Hannes Wallnoefer <han...@gmail.com> wrote:
> I'm sorry, but changing a ratified spec based on the misapprehension
> of a single person does not exactly boost my confidence in this whole
> process.

There's no cause for alarm. As always, unanimity is important; I for
one have no intention of going forward without your hand up. I think
that we're on the cusp of reverting to require.main === undefined; I'm
just waiting for Mikeal to weigh in.

Kris Kowal

Mikeal Rogers

unread,
Mar 25, 2010, 2:39:36 AM3/25/10
to comm...@googlegroups.com
It's a non-issue for me at this point. Charles has an interesting use case where {} is nicer to use than undefined but I don't think it's enough to hold up the process.

+1 for reverting.


--
Reply all
Reply to author
Forward
0 new messages