closure-compiler icon indicating copy to clipboard operation
closure-compiler copied to clipboard

Shadowed globals throw duplicate declaration error

Open talbenari1 opened this issue 5 years ago • 9 comments

The following code throws an error:

const Worker = 'foo';

For reference, here's what the error looks like:

stdin:1: ERROR - Duplicate let / const / class / function declaration in the same scope is not allowed.
const Worker = 'foo';
      ^^^^^^^^^^^^^^

1 error(s), 0 warning(s)

The same error is producible with any other global. I'm pretty sure it's not an error to shadow globals in JS, regardless of the environment (i.e. it's part of the ECMAScript spec).

I think the culprit is in the way externs are defined. Since they're functions, the compiler treats this situation as a redeclaration.

talbenari1 avatar Oct 02 '18 23:10 talbenari1

This applies even to globals which don't exist, such as Database and TypedArray.

tlhunter avatar Oct 02 '18 23:10 tlhunter

The easiest solution is to use a module here or custom set of externs that excludes the problematic names. It is true that the compiler doesn't have a distinction between "redeclarable" globals and those that can't be redeclared.

concavelenz avatar Oct 03 '18 22:10 concavelenz

@concavelenz should --assume_function_wrapper not have similar effect? I've run into this issue myself and I guess, I just have to pick a different name to stay clear of the conflict but I am compiling with --assume_function_wrapper because this is how my modules are eventually consumed.

I'm using the closure compiler to minify output from the TypeScript compiler, we start out with ES6 modules but we apply various transforms and output CommonJS modules but there doesn't seem to be a way to tell the compiler to treat the file as a CommonJS module, which is what I thought --assume_function_wrapper implied.

leidegre avatar Oct 28 '18 06:10 leidegre

--assume_function_wrapper doesn't really introduce sub-scopes (though I can see why you think it would). Instead, it enables optimizations on the "global" scope that would not otherwise be safe.

If you are using CommonJS modules, then --process_common_js_modules will recognize your files as a module and prevent name collisions (assuming they export something - or are imported by something else). However this also will bundle your modules together as a script - which might not be what you want either.

ChadKillingsworth avatar Oct 28 '18 19:10 ChadKillingsworth

@ChadKillingsworth thanks, I'll have a look.

leidegre avatar Oct 29 '18 09:10 leidegre

Is there any option to suppress this validation?

buckelieg avatar Nov 27 '19 14:11 buckelieg

Created internal Google issue http://b/145533139

blickly avatar Dec 02 '19 19:12 blickly

I don't think there's an existing suppression for that error, since in the common case it was warning about something that is also a VM error.

blickly avatar Dec 02 '19 19:12 blickly

I'm getting this error trying to compile a project with closure-library:

node_modules/google-closure-library/closure/goog/storage/mechanism/mechanismtestdefinition.js:18:4: ERROR - [JSC_VAR_MULTIPLY_DECLARED_ERROR] Variable mechanism declared more than once. First occurrence: node_modules/google-closure-library/closure/goog/storage/mechanism/iterablemechanismtester.js:22:4
  18| var mechanism;
          ^^^^^^^^^

node_modules/google-closure-library/closure/goog/storage/mechanism/mechanismtester.js:25:4: ERROR - [JSC_VAR_MULTIPLY_DECLARED_ERROR] Variable mechanism declared more than once. First occurrence: node_modules/google-closure-library/closure/goog/storage/mechanism/iterablemechanismtester.js:22:4
  25| var mechanism = null;
          ^^^^^^^^^^^^^^^^

node_modules/google-closure-library/closure/goog/storage/mechanism/mechanismtester.js:26:4: ERROR - [JSC_VAR_MULTIPLY_DECLARED_ERROR] Variable minimumQuota declared more than once. First occurrence: node_modules/google-closure-library/closure/goog/storage/mechanism/mechanismtestdefinition.js:21:4
  26| var minimumQuota = 0;
          ^^^^^^^^^^^^^^^^

pladaria avatar Jun 11 '21 11:06 pladaria