Skip to content

Conversation

@ChadKillingsworth
Copy link
Collaborator

Feature referenced by multiple issues and PRs, but especially by #1773.

Adds support for CommonJS module rewriting to handle named (non-path based) module lookups. This implements Node Module Resolution in the compiler natively.

One note: the compiler does not discover source files but depends on all necessary files to be passed in as source. I have work started for the Java npm version which takes an entry point then discovers and passes all required files.

As it's required by the algorithm, this also adds support for JSON files to be passed to the compiler as source. These files are rewritten to module exports. This rewriting is dependent on the file name ending with ".json". That's the same restrictions node has.

I only enabled this support for CommonJS modules, but it will definitely be wanted for ES6 modules as well.

@ChadKillingsworth
Copy link
Collaborator Author

@ChadKillingsworth ChadKillingsworth changed the title Implement the node module resolution algorithim for CommonJS modules Implement the node module resolution algorithm for CommonJS modules Oct 22, 2016
@brad4d brad4d self-assigned this Oct 26, 2016
@brad4d
Copy link
Contributor

brad4d commented Oct 26, 2016

@ChadKillingsworth, can you use goog.module instead of goog.provide when rewriting JSON files as modules?

@ChadKillingsworth
Copy link
Collaborator Author

Wouldn't it be rewritten twice that way?

@brad4d
Copy link
Contributor

brad4d commented Oct 28, 2016

@MatrixFrog tells me it doesn't really matter whether goog.module or goog.provide is used here. Continuing review...

@brad4d
Copy link
Contributor

brad4d commented Oct 28, 2016

This change is causing failures for some internal tests.
I don't yet know why.

@brad4d
Copy link
Contributor

brad4d commented Oct 29, 2016

Looks like a red herring. The tests were already broken.

try {
// JSON objects need wrapped in parens to parse properly
input.getSourceFile().setCode("(" + input.getSourceFile().getCode() + ")");
} catch (Exception e) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What exceptions do we expect here exactly?
Why is it OK to just ignore them?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the same Error as handling as other parse points use.


Node root = input.getAstRoot(this);
if (root == null) {
continue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there valid cases where root == null? What are they?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thought was for invalid JSON. Since we wrap the JSON in parens, I think it will always have at least a root node.


n.addChildToFront(
IR.exprResult(
IR.call(IR.getprop(IR.name("goog"), IR.string("provide")), IR.string(moduleName)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for use with Node.js, right?
Shouldn't we be rewriting this to look like a non-JSON Node.js module then, rather than a goog.provide()?
Perhaps Node.js modules get rewritten to look like goog.provide() anyway?
Even if that's so, isn't it safer to rewrite this as a Node.js module & allow the later pass to rewrite it again as a goog.provide(). Otherwise, we're duplicating the logic here & risking inconsistent behavior.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed this yesterday & agreed to leave it as-is.

}

// Load as a file
String fullModulePath = nodeModulesFolder.getKey() + "node_modules/" + requireName;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't MODULE_SLASH be used here?

// /foo/ -> bar/node_modules/baz/foo_bar_baz.js
// /foo/node_modules/bar/ -> baz/foo_bar_baz.js
for (String modulePath : modulePaths) {
String[] nodeModulesDirs = modulePath.split("/node_modules/");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use MODULE_SLASH here & several other places below?

…ules.

Adds support to rewrite JSON files passed in as source to module exports.
@ChadKillingsworth
Copy link
Collaborator Author

@brad4d Review items should now be addressed.

@brad4d
Copy link
Contributor

brad4d commented Nov 2, 2016

@ChadKillingsworth What's the resolution for the literal slashes in strings? I don't see a response to those questions.

@brad4d
Copy link
Contributor

brad4d commented Nov 2, 2016

@ChadKillingsworth nevermind about the '/' question. I see now.
The registry always uses '/' & you only need to use MODULE_SLASH for actual file paths.

@MatrixFrog
Copy link
Contributor

If we used the wrong slash somewhere I'm sure one of our valiant Windows users will let us know quite soon, so I'm not too worried about it :) (Does Travis run tests on Windows machines? Or can we make it do so if it doesn't already?)

@ChadKillingsworth
Copy link
Collaborator Author

Travis doesn't run tests on windows.:( I think for now we're safe with just the "/" character. If someone complains - I'll be happy to fix it.

@brad4d
Copy link
Contributor

brad4d commented Nov 2, 2016

FYI, internal review appears to be complete.
I'm just waiting on test runs to complete successfully before submitting.

@brad4d
Copy link
Contributor

brad4d commented Nov 2, 2016

@MatrixFrog should I be concerned about the Travis failure on this PR?

@ChadKillingsworth
Copy link
Collaborator Author

I can fix travis magically.

@brad4d
Copy link
Contributor

brad4d commented Nov 3, 2016

One of the suggested code improvements from our internal tools actually broke the code. :(
I had to undo the change and restart the global presubmit this morning.

@brad4d
Copy link
Contributor

brad4d commented Nov 4, 2016

Global presubmit looks good, so I'm submitting the change.

@blickly blickly closed this in 8c8a050 Nov 4, 2016
@ChadKillingsworth ChadKillingsworth deleted the module-registry branch November 13, 2016 13:30
alexeykomov pushed a commit to alexeykomov/closure-compiler that referenced this pull request Feb 8, 2017
…les.

Adds support to rewrite JSON files passed in as source to module exports.

Closes google#2094

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=138143265
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants