Feat: add import-style=commonjs_strict option to the compiler

This commit is contained in:
Peter Marton 2018-02-08 14:07:15 -08:00
parent 25625b956a
commit 1062d985b9
3 changed files with 33 additions and 10 deletions

View File

@ -144,6 +144,7 @@ Some examples:
The `import_style` option is left to the default, which is `closure`.
- `--js_out=import_style=commonjs,binary:protos`: this contains the options
`import_style=commonjs` and `binary` and outputs to the directory `protos`.
`import_style=commonjs_strict` doesn't expose the output on the global scope.
API
===

View File

@ -276,7 +276,8 @@ string GetEnumPath(const GeneratorOptions& options,
string MaybeCrossFileRef(const GeneratorOptions& options,
const FileDescriptor* from_file,
const Descriptor* to_message) {
if (options.import_style == GeneratorOptions::kImportCommonJs &&
if ((options.import_style == GeneratorOptions::kImportCommonJs ||
options.import_style == GeneratorOptions::kImportCommonJsStrict) &&
from_file != to_message->file()) {
// Cross-file ref in CommonJS needs to use the module alias instead of
// the global name.
@ -1675,8 +1676,18 @@ void Generator::GenerateProvides(const GeneratorOptions& options,
//
// // Later generated code expects foo.bar = {} to exist:
// foo.bar.Baz = function() { /* ... */ }
printer->Print("goog.exportSymbol('$name$', null, global);\n", "name",
*it);
// Do not use global scope in strict mode
if (options.import_style == GeneratorOptions::kImportCommonJsStrict) {
string namespaceObject = *it;
// Remove "proto." from the namespace object
namespaceObject.erase(0, 6);
printer->Print("goog.exportSymbol('$name$', null, proto);\n", "name",
namespaceObject);
} else {
printer->Print("goog.exportSymbol('$name$', null, global);\n", "name",
*it);
}
}
}
}
@ -3321,6 +3332,8 @@ bool GeneratorOptions::ParseFromOptions(
import_style = kImportClosure;
} else if (options[i].second == "commonjs") {
import_style = kImportCommonJs;
} else if (options[i].second == "commonjs_strict") {
import_style = kImportCommonJsStrict;
} else if (options[i].second == "browser") {
import_style = kImportBrowser;
} else if (options[i].second == "es6") {
@ -3430,10 +3443,17 @@ void Generator::GenerateFile(const GeneratorOptions& options,
GenerateHeader(options, printer);
// Generate "require" statements.
if (options.import_style == GeneratorOptions::kImportCommonJs) {
if ((options.import_style == GeneratorOptions::kImportCommonJs ||
options.import_style == GeneratorOptions::kImportCommonJsStrict)) {
printer->Print("var jspb = require('google-protobuf');\n");
printer->Print("var goog = jspb;\n");
printer->Print("var global = Function('return this')();\n\n");
// Do not use global scope in strict mode
if (options.import_style == GeneratorOptions::kImportCommonJsStrict) {
printer->Print("var proto = {};\n\n");
} else {
printer->Print("var global = Function('return this')();\n\n");
}
for (int i = 0; i < file->dependency_count(); i++) {
const string& name = file->dependency(i)->name();
@ -3477,7 +3497,8 @@ void Generator::GenerateFile(const GeneratorOptions& options,
GenerateExtension(options, printer, *it);
}
if (options.import_style == GeneratorOptions::kImportCommonJs) {
if ((options.import_style == GeneratorOptions::kImportCommonJs ||
options.import_style == GeneratorOptions::kImportCommonJsStrict)) {
printer->Print("goog.object.extend(exports, $package$);\n",
"package", GetFilePath(options, file));
}

View File

@ -63,10 +63,11 @@ struct GeneratorOptions {
bool binary;
// What style of imports should be used.
enum ImportStyle {
kImportClosure, // goog.require()
kImportCommonJs, // require()
kImportBrowser, // no import statements
kImportEs6, // import { member } from ''
kImportClosure, // goog.require()
kImportCommonJs, // require()
kImportCommonJsStrict, // require() with no global export
kImportBrowser, // no import statements
kImportEs6, // import { member } from ''
} import_style;
GeneratorOptions()