rauschma / exploring-js

20 stars 0 forks source link

Chapter: Modules #20

Open rauschma opened 6 years ago

rightpad commented 6 years ago

In section 22.1, underneath the code snippit reads:

myModule is a global variable.

However the code snippit doesn't have a variable named myModule, did you mean myLibrary?

mathiasbynens commented 5 years ago

It might be useful to mention the .mjs extension, which is increasingly getting adopted by tooling as a signal that the file is a JavaScript module as opposed to a classic script.

The experimental modules implementation in Node.js only works for .mjs. Recently, the Node.js Modules Working Group agreed on the “minimal kernel” for what will one day become the unflagged implementation, and it states that .mjs will continue to be supported out-of-the-box. (There is a plan to allow other extensions as well at the cost of additional configuration.)

rauschma commented 5 years ago

@mathiasbynens The plan is to do both at the same time: Switch to .mjs (once it is supported without a flag by Node.js) and explain the rationale behind .mjs. With “Impatient JS”, I stick to established things.

rauschma commented 5 years ago

@da-moo Thanks! A fix will be in the next release.

mcast commented 5 years ago

First, thanks for compiling a useful set of explanations!

export default foo();

Did you mean the () in that?

When I try it, I seem to be exporting the result of calling the function (which makes sense because () invoked it), but this doesn't fit either ther apparent intent of the statement or the notion of exports being static.

ubuntu@pettle:~/tmp$ node --experimental-modules B.mjs 
(node:7610) ExperimentalWarning: The ESM module loader is experimental.
called foo
first line of B
bar = string result
ubuntu@pettle:~/tmp$ cat A.mjs 
function foo() {
  console.log("called foo");
  return "string result";
}
export default foo();
ubuntu@pettle:~/tmp$ cat B.mjs 
console.log("first line of B");
import bar from './A.mjs';
console.log("bar = " + bar);
ubuntu@pettle:~/tmp$ node --experimental-modules B.mjs 
(node:7634) ExperimentalWarning: The ESM module loader is experimental.
called foo
first line of B
bar = string result
ubuntu@pettle:~/tmp$ node -v
v8.11.4

Or would this describe the intent of the example?

export default foo(); // export the return value of calling foo()

rauschma commented 2 years ago

@mcast Good point. Both do indeed make sense. I’ll try to make this clearer in the next release.

ApolloTang commented 2 years ago

Thank you for this book. I'm enjoying reading it!

I have a question:

RE: section https://exploringjs.com/impatient-js/ch_modules.html#naming-modules

image

could you please explain why underscore-casing does not work for default import and why it is not a good choice for functions?

Thanks!

docwarems commented 2 years ago

Axel, this article (or chapter) made by day.

I've been a Java programmer almost from the Java beginnings, who had to move to TS/node a year ago and work on a node project which have been developed for years. The different module and import/export paradigms from JS, TS, node, nest drove me crazy. And if you work through tutorials on each of these technics you get always only the module view from this technics perspective. In the project I'm working all these technics are mixed and I haven't got a true view on how the module system works even for one year. Consequently refactorings habe been a big pain because I usually needed most of the time with updating dependencies by trial & error because there was no true understanding.

Your article is the first source I found where everything is put together in a compact way starting with the history and how it evolved.

Now I understand my project a lot better. Thank you very much!

vovochka-dev commented 1 year ago

Thank you, for your work. I have question about default export.

// Default exports export default function f() {} // declaration with optional name

and

27.7.1 The two styles of default-exporting There are two styles of doing default exports.

First, we can label existing declarations with export default:

export default function myFunc() {} // no semicolon!
export default class MyClass {} // no semicolon!

I tried to figure out what existing declarations really mean, maybe it's about hoisting thing. But then I realized that this is actually named function expression and named class expression.

After export default have to be expression, not declaration (or existing expression). ESM creators have even considered another more explicit syntax with '=': export default = function myFunc() {}; Under the hood implicitly we set value (expression) to default variable.

const funcExpression = function myFunc() {}
export default myFuncExpression;

const classExpression = class MyClass {}
export default classExpression;

So, is it existing declarations or expressions?

rauschma commented 1 year ago

I tried to figure out what existing declarations really mean, maybe it's about hoisting thing. But then I realized that this is actually named function expression and named class expression.

@vovochka-dev: I should probably remove the word “existing”. I agree that that word makes this sentence slightly confusing.

They really are declarations – check out the three grammar rules for export default in the ECMAScript specification. Two of them are for declarations.

rauschma commented 1 year ago

@ApolloTang:

could you please explain why underscore-casing does not work for default import and why it is not a good choice for functions?

The common practice for JavaScript is to use camel case for functions. I’m going back and forth on underscore case: Maybe it shouldn’t be used at all (except for constants).

vovochka-dev commented 1 year ago

I tried to figure out what existing declarations really mean, maybe it's about hoisting thing. But then I realized that this is actually named function expression and named class expression.

@vovochka-dev: I should probably remove the word “existing”. I agree that that word makes this sentence slightly confusing.

They really are declarations – check out the three grammar rules for export default in the ECMAScript specification. Two of them are for declarations.

Thank you, Indeed it's declaration:

export default function add(a, b) {return a + b;}
console.log(add(2,2)) //4

One more thing. When I understood it was "aha moment" about export default const problem. Consider some changes:

// Not legal JavaScript! export default const foo = 1, bar = 2, baz = 3; +// Legal JavaScript +export const foo = 1, bar = 2, baz = 3;

And also Cheat sheet does not contain this syntax:

export function f() {} export const one = 1; export {foo, b as bar}; +export const foo = 1, bar = 2, baz = 3;

yanjankaf commented 1 year ago

I'm having trouble understanding this part,?

On the plus side, AMD modules can be executed directly. In contrast, CommonJS modules must either be compiled before deployment or custom source code must be generated and evaluated dynamically (think eval()). That isn’t always permitted on the web.


I think the author is trying to say something like this

Since you have a script element you can load as many scripts as you want dynamically, but can't you do the same in common JS? check some conditions, then call require?

So basically since the common.js modules are not supported by javascript by default, you need to compile this to javascript, but why would you do this? if the node supports the require function let it use it. well ofcourse if you are putting the code you have written using require, you need some sort of polyfill for that,

I have no idea about this sentence - "Custom source code must be generated and evaluated dynamically (think eval())"