Git Product home page Git Product logo

rules_closure's Introduction

Closure Rules for Bazel (αlpha) Bazel CI build status

JavaScript Templating Stylesheets Miscellaneous
closure_js_library closure_js_template_library closure_css_library closure_js_proto_library
closure_js_binary closure_java_template_library closure_css_binary phantomjs_test
closure_js_test closure_py_template_library closure_proto_library (Experimental)
closure_grpc_web_library (Experimental)

Overview

Closure Rules provides a polished JavaScript build system for Bazel that emphasizes type safety, strictness, testability, and optimization. These rules are built with the Closure Tools, which are what Google used to create websites like Google.com and Gmail. The goal of this project is to take the frontend development methodology that Google actually uses internally, and make it easily available to outside developers.

Closure Rules is an abstract build system. This is what sets it apart from Grunt, Gulp, Webpacker, Brunch, Broccoli, etc. These projects all provide a concrete framework for explaining how to build your project. Closure Rules instead provides a framework for declaring what your project is. Closure Rules is then able to use this abstract definition to infer an optimal build strategy.

Closure Rules is also an austere build system. The Closure Compiler doesn't play games. It enforces a type system that can be stricter than Java. From a stylistic perspective, Closure is verbose like Java; there's no cryptic symbols or implicit behavior; the code says exactly what it's doing. This sets Closure apart from traditional JavaScript development, where terseness was favored over readability, because minifiers weren't very good. Furthermore, the Closure Library and Templates help you follow security best practices which will keep your users safe.

What's Included

Closure Rules bundles the following tools and makes them "just work."

  • Bazel: The build system Google uses to manage a repository with petabytes of code.
  • Closure Compiler: Type-safe, null-safe, optimizing JavaScript compiler that transpiles ECMASCRIPT6 to minified ES3 JavaScript that can run in any browser.
  • Closure Library: Google's core JavaScript libraries.
  • Closure Templates: Type-safe HTML templating system that compiles to both JavaScript and Java. This is one of the most secure templating systems available. It's where Google has put the most thought into preventing things like XSS attacks. It also supports i18n and l10n.
  • Closure Stylesheets: CSS compiler supporting class name minification, variables, functions, conditionals, mixins, and bidirectional layout.
  • PhantomJS: Headless web browser used for automating JavaScript unit tests in a command line environment.
  • Protocol Buffers: Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data. This is used instead of untyped JSON.

Mailing Lists

Caveat Emptor

Closure Rules is production ready, but its design is not yet finalized. Breaking changes will be introduced. However they will be well-documented in the release notes.

Setup

First you must install Bazel. Then you add the following to your WORKSPACE file:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "io_bazel_rules_closure",
    sha256 = "9498e57368efb82b985db1ed426a767cbf1ba0398fd7aed632fc3908654e1b1e",
    strip_prefix = "rules_closure-0.12.0",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/rules_closure/archive/0.12.0.tar.gz",
        "https://github.com/bazelbuild/rules_closure/archive/0.12.0.tar.gz",
    ],
)

load("@io_bazel_rules_closure//closure:repositories.bzl", "rules_closure_dependencies", "rules_closure_toolchains")
rules_closure_dependencies()
rules_closure_toolchains()

# Only needed if you want to run your tests on headless Chrome
load("@io_bazel_rules_closure//closure:defs.bzl", "setup_web_test_repositories")
setup_web_test_repositories(
    chromium = True,
)

You are not required to install the Closure Tools, PhantomJS, or anything else for that matter; they will be fetched automatically by Bazel.

Overriding Dependency Versions

When you call rules_closure_dependencies() in your WORKSPACE file, it causes a few dozen external dependencies to be added to your project, e.g. Guava, Guice, JSR305, etc. You might need to customize this behavior.

To override the version of any dependency, modify your WORKSPACE file to pass omit_<dependency_name>=True to rules_closure_dependencies(). Next define your custom dependency version. A full list of dependencies is available from repositories.bzl. For example, to override the version of Guava:

load("@io_bazel_rules_closure//closure:repositories.bzl", "rules_closure_dependencies", "rules_closure_toolchains")
rules_closure_dependencies(
    omit_com_google_guava=True,
)
rules_closure_toolchains()

load("@bazel_tools//tools/build_defs/repo:java.bzl", "java_import_external")
java_import_external(
    name = "com_google_guava",
    licenses = ["notice"],  # Apache 2.0
    jar_urls = [
        "https://mirror.bazel.build/repo1.maven.org/maven2/com/google/guava/guava/24.1-jre/guava-24.1-jre.jar",
        "https://repo1.maven.org/maven2/com/google/guava/guava/24.1-jre/guava-24.1-jre.jar",
    ],
    jar_sha256 = "31bfe27bdf9cba00cb4f3691136d3bc7847dfc87bfe772ca7a9eb68ff31d79f5",
    exports = [
        "@com_google_code_findbugs_jsr305",
        "@com_google_errorprone_error_prone_annotations",
    ],
)

Examples

Please see the test directories within this project for concrete examples of usage:

Reference

closure_js_library

load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_library")
closure_js_library(name, srcs, data, deps, exports, suppress, convention,
                   no_closure_library)

Defines a set of JavaScript sources.

The purpose of this rule is to define an abstract graph of JavaScript sources. It must be used in conjunction with closure_js_binary to output a minified file.

This rule will perform syntax checking and linting on your files. This can be tuned with the suppress attribute. To learn more about what the linter wants, read the Google JavaScript Style Guide.

Strict dependency checking is performed on the sources listed in each library target. See the documentation of the deps attribute for further information.

Rule Polymorphism

This rule can be referenced as though it were the following:

  • filegroup: srcs will always be empty and data will contain all transitive JS sources and data.

Arguments

  • name: (Name; required) A unique name for this rule. The standard convention is that this be the same name as the Bazel package with srcs = glob(['*.js']). If it contains a subset of the .js srcs in the package, then convention states that the _lib suffix should be used.

  • srcs: (List of labels; optional) The list of .js source files that represent this library. This can include files marked as @externs or @nocompile. This attribute is required unless the exports attribute is being defined.

  • data: (List of labels; optional) Runfiles directly referenced by JS sources in this rule. For example, if the JS generated injected an img tag into the page with a hard coded image named foo.png, then you might want to list that image here, so it ends up in the webserver runfiles.

  • deps: (List of labels; optional) Direct dependency list. These can point to closure_js_library, closure_js_template_library, closure_css_library and closure_js_proto_library rules.

  • exports: (List of labels; optional) Listing dependencies here will cause them to become direct dependencies in parent rules. This functions similarly to java_library.exports. This can be used to create aliases for rules in another package. It can also be also be used to export private targets within the package. Another use is to roll up a bunch of fine-grained libraries into a single big one.

  • suppress (List of String; optional; default is []) List of codes the linter should ignore. Warning and error messages that are allowed to be suppressed, will display the codes for disabling it. For example, if the linter says:

    foo.js:123: WARNING lintChecks JSC_MUST_BE_PRIVATE - Property bar_ must be marked @private
    

    Then the diagnostic code "JSC_MUST_BE_PRIVATE" can be used in the suppress list. It is also possible to use the group code "lintChecks" to disable all diagnostic codes associated with linting.

    If a code is used that isn't necessary, an error is raised. Therefore the use of fine-grained suppression codes is maintainable.

  • convention (String; optional; default is "CLOSURE") Specifies the coding convention which affects how the linter operates. This can be the following values:

  • no_closure_library (Boolean; optional; default is False) Do not link Closure Library base.js. If this flag is used, an error will be raised if any deps do not also specify this flag.

    All closure_js_library rules with nonempty srcs have an implicit dependency on @closure_library//:closure/goog/base.js. This is a lightweight file that boostraps very important functions, e.g. goog.provide. Linking this file by default is important because:

    1. It is logically impossible to say goog.require('goog').
    2. The Closure Compiler will sometimes generate synthetic code that calls these functions. For example, the ProcessEs6Modules compiler pass turns ES6 module directives into goog.provide / goog.require statements.

    The only tradeoff is that when compiling in WHITESPACE_ONLY mode, this code will show up in the resulting binary. Therefore this flag provides the option to remove it.

closure_js_binary

load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_binary")
closure_js_binary(name, deps, css, debug, language, entry_points,
                  dependency_mode, compilation_level, formatting,
                  output_wrapper, property_renaming_report, defs)

Turns JavaScript libraries into a minified optimized blob of code.

This rule must be used in conjunction with closure_js_library.

Implicit Output Targets

  • name.js: A minified JavaScript file containing all transitive sources.

  • name.js.map: Sourcemap file mapping compiled sources to their raw sources. This file can be loaded into browsers such as Chrome and Firefox to view a stacktrace when an error is thrown by compiled sources.

Rule Polymorphism

This rule can be referenced as though it were the following:

  • filegroup: srcs will be the .js and .js.map output files and data will contain those files in addition to all transitive JS sources and data.

  • closure_js_library: srcs will be the .js output file, language will be the output language, deps will be empty, data will contain all transitive data, and no_closure_library will be True.

Arguments

  • name: (Name; required) A unique name for this rule. Convention states that such rules be named foo_bin or foo_dbg if debug = True.

  • deps: (List of labels; required) Direct dependency list. This attribute has the same meaning as it does in closure_js_library. These can point to closure_js_library and closure_js_template_library rules.

  • css: (Label; optional) CSS class renaming target, which must point to a closure_css_binary rule. This causes the CSS name mapping file generated by the CSS compiler to be included in the compiled JavaScript. This tells Closure Compiler how to minify CSS class names.

    This attribute is required if any of JavaScript or template sources depend on a closure_css_library. This rule will check that all the referenced CSS libraries are present in the CSS binary.

  • debug: (Boolean; optional; default is False) Enables debug mode. Many types of properties and variable names will be renamed to include $ characters, to help you spot bugs when using ADVANCED compilation mode. Assert statements will not be stripped. Dependency directives will be removed.

  • language: (String; optional; default is "ECMASCRIPT3") Output language variant to which library sources are transpiled. The default is ES3 because it works in all browsers. The input language is calculated automatically based on the language attribute of closure_js_library dependencies.

  • entry_points: (List of String; optional; default is []) List of unreferenced namespaces that should not be pruned by the compiler. This should only be necessary when you want to invoke them from a <script> tag on your HTML page. See Exports and Entry Points to learn how this works with the @export feature. For further context, see the Closure Compiler documentation on managing dependencies.

  • dependency_mode: (String; optional; default is "LOOSE") In rare circumstances you may want to set this flag to "STRICT". See the Exports and Entry Points unit tests and the Closure Compiler's managing dependencies documentation for more information.

  • compilation_level: (String; optional; default is "ADVANCED") Specifies how minified you want your JavaScript binary to be. Valid options are:

    • ADVANCED: Enables maximal minification and type checking. This is strongly recommended for production binaries. Warning: Properties that are accessed with dot notation will be renamed. Use quoted notation if this presents problems for you, e.g. foo['bar'], {'bar': ...}.

    • SIMPLE: Tells the Closure Compiler to function more like a traditional JavaScript minifier. Type checking becomes disabled. Local variable names will be minified, but object properties and global names will not. Namespaces will be managed. Code that will never execute will be removed. Local functions and variables can be inlined, but globals can not.

    • WHITESPACE_ONLY: Tells the Closure Compiler to strip whitespace and comments. Transpilation between languages will still work. Type checking becomes disabled. No symbols will be renamed. Nothing will be inlined. Dependency statements will not be removed. ProTip: If you're using the Closure Library, you'll need to look into the CLOSURE_NO_DEPS and goog.ENABLE_DEBUG_LOADER options in order to execute the compiled output.)

  • formatting: (String; optional) Specifies what is passed to the --formatting flag of the Closure Compiler. The following options are valid:

    • PRETTY_PRINT
    • PRINT_INPUT_DELIMITER
    • SINGLE_QUOTES
  • output_wrapper: (String; optional) Interpolate output into this string at the place denoted by the marker token %output%. Use the marker token %output|jsstring% to do JS string escaping on the output. The default behavior is to generate code that pollutes the global namespace. Many users will want to set this to "(function(){%output%}).call(this);" instead. See the Closure Compiler FAQ for more details.

  • property_renaming_report: (File; optional) Output file for property renaming report. It will contain lines in the form of old:new. This feature has some fringe use cases, such as minifying JSON messages. However it's recommended that you use protobuf instead.

  • defs: (List of strings; optional) Specifies additional flags to be passed to the Closure Compiler, e.g. "--hide_warnings_for=some/path/". To see what flags are available, run: bazel run @io_bazel_rules_closure//third_party/java/jscomp:main -- --help

Support for AngularJS

When compiling AngularJS applications, you need to pass custom flags to the Closure Compiler. This can be accomplished by adding the following to your closure_js_binary rule:

closure_js_binary(
    # ...
    defs = [
        "--angular_pass",
        "--export_local_property_definitions",
    ],
)

closure_js_test

load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_test")
closure_js_test(name, srcs, data, deps, css, html, language, suppress,
                compilation_level, entry_points, defs)

Runs JavaScript unit tests inside a headless web browser.

This is a build macro that composes closure_js_library, closure_js_binary, and phantomjs_test.

A test is defined as any function in the global namespace that begins with test, setUp, or tearDown. You are not required to @export these functions. If you don't have a global namespace, because you're using goog.module or goog.scope, then you must register your test functions with goog.testing.testSuite.

Each test file should require goog.testing.jsunit and goog.testing.asserts because they run the tests and provide useful testing functions such as assertEquals().

Any JavaScript file related to testing is strongly recommended to contain a goog.setTestOnly() statement in the file. However this is not required, because some projects might not want to directly reference Closure Library functions.

No Network Access

Your test will run within a hermetically sealed environment. You are not allowed to send HTTP requests to any external servers. It is expected that you'll use Closure Library mocks for things like XHR. However a local HTTP server is started up on a random port that allows to request runfiles under the /filez/WORKSPACE_NAME/ path.

Rule Polymorphism

This rule can be referenced as though it were the following:

  • filegroup: srcs will be the outputted executable, data will contain all transitive sources, data, and other runfiles.

Arguments

phantomjs_test

load("@io_bazel_rules_closure//closure:defs.bzl", "phantomjs_test")
phantomjs_test(name, data, deps, html, harness, runner)

Runs PhantomJS (QtWebKit) for unit testing purposes.

This is a low level rule. Please use the closure_js_test macro if possible.

Rule Polymorphism

This rule can be referenced as though it were the following:

  • filegroup: srcs will be the outputted executable, data will contain all transitive sources, data, and other runfiles.

Arguments

  • name: (Name; required) Unique name for this rule.

  • data: (List of labels; optional) Additional runfiles for the local HTTP server to serve, under the /filez/ + repository path. This attribute should not be necessary, because the transitive runfile data is already collected from dependencies.

  • deps: (List of labels; required) Labels of Skylark rules exporting transitive_js_srcs. Each source will be inserted into the webpage in its own <script> tag based on a depth-first preordering.

  • html: (Label; optional; default is "@io_bazel_rules_closure//closure/testing:empty.html") HTML file containing DOM structure of virtual web page before <script> tags are automatically inserted. Do not include a doctype in this file.

  • harness: (Label; required; default is "@io_bazel_rules_closure//closure/testing:phantomjs_harness") JS binary or library exporting a single source file, to be used as the PhantomJS outer script.

  • runner: (Label; optional; default is "@io_bazel_rules_closure//closure/testing:phantomjs_jsunit_runner") Same as deps but guaranteed to be loaded inside the virtual web page last. This should run whatever tests got loaded by deps and then invoke callPhantom to report the result to the harness.

closure_js_template_library

load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_template_library")
closure_js_template_library(name, srcs, data, deps, globals, plugin_modules,
                            should_generate_js_doc,
                            should_generate_soy_msg_defs,
                            bidi_global_dir,
                            soy_msgs_are_external,
                            defs)

Compiles Closure templates to JavaScript source files.

This rule is necessary in order to render Closure templates from within JavaScript code.

This rule pulls in a transitive dependency on the Closure Library.

The documentation on using Closure Templates can be found here.

For additional help on using some of these attributes, please see the output of the following:

bazel run @com_google_template_soy//:SoyToJsSrcCompiler -- --help

Implicit Output Targets

  • src.js: A separate JavaScript source file is generated for each file listed under srcs. The filename will be the same as the template with a .js suffix. For example foo.soy would become foo.soy.js.

Rule Polymorphism

This rule can be referenced as though it were the following:

  • filegroup: srcs will be the generated JS output files and data will contain all transitive JS sources and data.

  • closure_js_library: srcs will be the generated JS output files, data will contain the transitive data, deps will contain necessary libraries, and no_closure_library will be False.

Arguments

  • name: (Name; required) A unique name for this rule.

  • srcs: (List of labels; required) A list of .soy source files that represent this library.

  • data: (List of labels; optional) Runfiles directly referenced by Soy sources in this rule. For example, if the template has an <img src=foo.png> tag, then the data attribute of its rule should be set to ["foo.png"] so the image is available in the web server runfiles.

  • deps: (List of labels; optional) List of closure_js_library, closure_js_template_library and closure_js_proto_library targets which define symbols referenced by the template.

  • globals: (List of labels; optional) List of text files containing symbol definitions that are only considered at compile-time. For example, this file might look as follows:

    com.foo.bar.Debug.PRODUCTION = 0
    com.foo.bar.Debug.DEBUG = 1
    com.foo.bar.Debug.RAW = 2
    
  • plugin_modules: (List of labels; optional; default is []) Passed along verbatim to the SoyToJsSrcCompiler above.

  • should_generate_js_doc: (Boolean; optional; default is True) Passed along verbatim to the SoyToJsSrcCompiler above.

  • should_generate_soy_msg_defs: (Boolean; optional; default is False) Passed along verbatim to the SoyToJsSrcCompiler above.

  • bidi_global_dir: (Integer; optional; default is 1) Passed along verbatim to the SoyToJsSrcCompiler above. Valid values are 1 (LTR) or -1 (RTL).

  • soy_msgs_are_external: (Boolean; optional; default is False) Passed along verbatim to the SoyToJsSrcCompiler above.

  • defs: (List of strings; optional) Passed along verbatim to the SoyToJsSrcCompiler above.

closure_java_template_library

load("@io_bazel_rules_closure//closure:defs.bzl", "closure_java_template_library")
closure_java_template_library(name, srcs, data, deps, java_package)

Compiles Closure templates to Java source files.

This rule is necessary in order to serve Closure templates from a Java backend.

Unlike closure_js_template_library, globals are not specified by this rule. They get added at runtime by your Java code when serving templates.

This rule pulls in a transitive dependency on Guava, Guice, and ICU4J.

The documentation on using Closure Templates can be found here.

For additional help on using some of these attributes, please see the output of the following:

bazel run @com_google_template_soy//:SoyParseInfoGenerator -- --help

Implicit Output Targets

  • SrcSoyInfo.java: A separate Java source file is generated for each file listed under srcs. The filename will be the same as the template, converted to upper camel case, with a SoyInfo.java suffix. For example foo_bar.soy would become FooBarSoyInfo.java.

Rule Polymorphism

This rule can be referenced as though it were the following:

  • filegroup: srcs will be the compiled jar file and data will contain all transitive data.

  • java_library: srcs will be the generated Java source files, and data will contain the transitive data.

Arguments

  • name: (Name; required) A unique name for this rule.

  • srcs: (List of labels; required) A list of .soy source files that represent this library.

  • data: (List of labels; optional) Runfiles directly referenced by Soy sources in this rule. For example, if the template has an <img src=foo.png> tag, then the data attribute of its rule should be set to ["foo.png"] so the image is available in the web server runfiles.

  • deps: (List of labels; optional) Soy files to parse but not to generate outputs for.

  • java_package: (List of labels; required) The package for the Java files that are generated, e.g. "com.foo.soy".

closure_py_template_library

TODO

closure_css_library

load("@io_bazel_rules_closure//closure:defs.bzl", "closure_css_library")
closure_css_library(name, srcs, data, deps)

Defines a set of CSS stylesheets.

This rule does not compile your stylesheets; it is used in conjunction with closure_css_binary which produces the minified CSS file.

This rule should be referenced by any closure_js_library rule whose sources contain a goog.getCssName('foo') call if foo is a CSS class name defined by this rule. The same concept applies to closure_js_template_library rules that contain {css('foo')} expressions.

Rule Polymorphism

This rule can be referenced as though it were the following:

  • filegroup: srcs will be the generated JS output files and data will contain all transitive CSS/GSS sources and data.

  • closure_js_library: srcs is empty, data is the transitive CSS sources and data, and no_closure_library is True. However the closure_css_library rule does pass special information along when used as a dep in closure_js_library. See its documentation to learn more.

Arguments

  • name: (Name; required) A unique name for this rule. Convention states that this end with _lib.

  • srcs: (List of labels; required) A list of .gss or .css source files that represent this library.

    The order of stylsheets is srcs is undefined. If a CSS file overrides definitions in another CSS file, then each file must be specified in separate closure_css_library targets. That way Bazel can order your CSS definitions based on the depth-first preordering of dependent rules.

    It is strongly recommended you use @provide and @require statements in your stylesheets so the CSS compiler can assert that the ordering is accurate.

  • data: (List of labels; optional) Runfiles directly referenced by CSS sources in this rule. For example, if the CSS has a url(foo.png) then the data attribute of its rule should be set to ["foo.png"] so the image is available in the web server runfiles.

  • deps: (List of labels; optional) List of other closure_css_library targets on which the CSS files in srcs depend.

  • orientation: (String; optional; default is "LTR") Defines the text direction for which this CSS was designed. This value can be:

    • LTR: Outputs a sheet suitable for left to right display.
    • RTL: Outputs a sheet suitable for right to left display.

    An error will be raised if any deps do not have the same orientation. CSS libraries with different orientations can be linked together by creating an intermediary closure_css_binary that flips its orientation.

closure_css_binary

load("@io_bazel_rules_closure//closure:defs.bzl", "closure_css_binary")
closure_css_binary(name, deps, renaming, debug, defs)

Turns stylesheets defined by closure_css_library rules into a single minified CSS file.

Closure-specific syntax such as variables, functions, conditionals, and mixins will be evaluated and turned into normal CSS. The documentation on using these features can be found here.

Unlike most CSS minifiers, this will minify class names by default. So this rule can be referenced by the css flag of closure_js_binary, in order to let the Closure Compiler know how to substitute the minified class names. See the renaming documentation below for more information.

Implicit Output Targets

  • name.css: A minified CSS file defining the transitive closure of dependent stylesheets compiled in a depth-first preordering.

  • name.css.map: CSS sourcemap file. This tells browsers like Chrome and Firefox where your CSS definitions are located in their original source files.

  • name.css.js: JavaScript file containing a goog.setCssNameMapping() statement which tells the Closure Compiler and Library how to minify CSS class names. The use of this file is largely handled transparently by the build system. The user should only need to worry about this file when rendering Soy templates from Java code, because its contents will need to be parsed into a map using a regular expression, which is then passed to the Soy Tofu Java runtime.

Rule Polymorphism

This rule can be referenced as though it were the following:

  • filegroup: srcs will be the generated .css, .css.map, and .css.js output files. data will contain all transitive CSS/GSS sources and data.

  • closure_css_library: srcs is the output .css file, data is the transitive CSS sources and data, and orientation is the output orientation.

Arguments

  • name: (Name; required) A unique name for this rule. Convention states that such rules be named foo_bin or foo_dbg if debug = True.

  • deps: (List of labels; required) List of closure_css_library rules to compile. All dependencies must have their orientation attribute set to the same value.

  • renaming: (Boolean; optional; default is True) Enables CSS class name minification. This is one of the most powerful features of the Closure Tools. By default, this will turn class names like .foo-bar into things like .a-b. If debug = True then it will be renamed .foo_-bar_.

    In order for this to work, you must update your JavaScript code to use the goog.getCssName("foo-bar") when referencing class names. JavaScript library targets that reference CSS classes must add the appropriate CSS library to its deps attribute. The css attribute of the closure_js_binary also needs to be updated to point to this CSS binary target, so the build system can verify (at compile time) that your CSS and JS binaries are both being compiled in a harmonious way.

    You'll also need update your templates to say {css('foo-bar')} in place of class names. The closure_js_template_library must also depend on the appropriate CSS library.

  • debug: (Boolean; optional; default is False) Enables debug mode, which causes the compiled stylesheet to be pretty printed. If renaming = True then class names will be renamed, but still readable to humans.

  • orientation: (String; optional; default is "NOCHANGE") Specify this option to perform automatic right to left conversion of the input. You can choose between:

    • NOCHANGE: Uses same orientation as was specified in dependent libraries.
    • LTR: Outputs a sheet suitable for left to right display.
    • RTL: Outputs a sheet suitable for right to left display.

    The input orientation is calculated from the orientation flag of all closure_css_library targets listed in deps. If the input orientation is different than the requested output orientation, then 'left' and 'right' values in direction sensitive style rules are flipped. If the input already has the desired orientation, this option effectively does nothing except for defining GSS_LTR and GSS_RTL, respectively.

  • vendor: (String; optional; default is None) Creates browser-vendor-specific output by stripping all proprietary browser-vendor properties from the output except for those associated with this vendor. Valid values are:

    • WEBKIT
    • MOZILLA
    • MICROSOFT
    • OPERA
    • KONQUEROR

    The default behavior is to not strip any browser-vendor properties.

  • defs: (List of strings; optional) Specifies additional flags to be passed to the Closure Stylesheets compiler. To see what flags are available, run: bazel run @com_google_closure_stylesheets//:ClosureCommandLineCompiler -- --help

closure_js_proto_library

load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_proto_library")
closure_js_proto_library(name, srcs, add_require_for_enums, binary,
                         import_style)

Defines a set of Protocol Buffer files.

Documentation

Implicit Output Targets

  • name.js: A generated protocol buffer JavaScript library.

  • name.descriptor: A protoc FileDescriptorsSet representation of the .proto files.

Rule Polymorphism

This rule can be referenced as though it were the following:

  • filegroup: srcs will be empty and data will contain all transitive JS sources and data.

  • closure_js_library: srcs will be the generated JS output files, data will contain the transitive data, and deps will contain necessary libraries.

Arguments

  • name: (Name; required) A unique name for this rule. Convention states that such rules be named foo_proto.

  • srcs: (List of labels; required) A list of .proto source files that represent this library.

  • add_require_for_enums: (Boolean; optional; default is False) Add a goog.require() call for each enum type used. If false, a forward declaration with goog.forwardDeclare is produced instead.

  • binary: (Boolean; optional; default is True) Enable binary-format support.

  • import_style: (String; optional; default is IMPORT_CLOSURE) Specifies the type of imports that should be used. Valid values are:

    • IMPORT_CLOSURE // goog.require()
    • IMPORT_COMMONJS // require()
    • IMPORT_BROWSER // no import statements
    • IMPORT_ES6 // import { member } from ''

closure_proto_library

load("@io_bazel_rules_closure//closure:defs.bzl", "closure_proto_library")
closure_proto_library(name, deps)

closure_proto_library generates JS code from .proto files.

deps must point to proto_library rules.

Rule Polymorphism

This rule can be referenced as though it were the following:

  • closure_js_library: srcs will be the generated JS files, and deps will contain necessary libraries.

  • name: (Name; required) A unique name for this rule. Convention states that such rules be named *_closure_proto.

  • deps: (List of labels; required) The list of proto_library rules to generate JS code for.

rules_closure's People

Contributors

alexeagle avatar blickly avatar buchgr avatar comius avatar concavelenz avatar cpovirk avatar cushon avatar damienmg avatar davido avatar dslomov avatar eustas avatar gkdn avatar hochhaus avatar jart avatar jdramaix avatar kchodorow avatar lauraharker avatar laurentlb avatar mihaimaruseac avatar mollyibot avatar nreid260 avatar pcj avatar philwo avatar rluble avatar sgammon avatar tjgq avatar vladmos avatar vrana avatar wchargin avatar yannic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rules_closure's Issues

Debug mode

It would be nice if there was a flag or something that cause the build system to print to stderr the Closure commands that are actually being run.

Investigate use of clang-format for style enforcement

As discussed in #55, Closure Library uses clang-format to enforce style conventions and formatting in their project, since Closure Compiler linter.jar does not really do much in the way of formatting. It might be nice if Closure Rules was able to incorporate this.

Why is this important? Because Google's JavaScript and Closure style guides are by far the most difficult and onerous. Far more complicated than C++, Java, or Python style. Especially if you're used to the anarchy of non-Google JavaScript development, where style is shunned entirely in favor of succinctness. So I imagine newcomers would be rather shell-shocked by Google's style conventions at first introduction. It would be fabulous if a tool could help them.

I personally do not have the cycles to take this on. Right now I'm focused on making the features that we have, work as advertised. If others could investigate this further, it would be awesome.

CC: @hochhaus (since it won't allow me to assign directly to you)

Can't run on App Engine

The current version of the soy library that is included by the closure rules library is built with JDK 8, which prevents any consumers of this library from deploying to the traditional GAE platform. Could you consider rolling back to 2015-04-10 or forward to the next version if it switches back to using JDK 7?

Unable to import rules

Built bazel from HEAD this morning, and tried following instructions in the readme to import the closure rules. I get this error:
ERROR: no such package '@io_bazel_rules_closure//closure': Invalid branch, tag, or commit: Ref tags/0.0.1 can not be resolved.

The relevant portion of my workspace file:

git_repository(
    name = "io_bazel_rules_closure",
    remote = "https://github.com/bazelbuild/rules_closure.git",
    tag = "0.0.1",
)

load("@io_bazel_rules_closure//closure:defs.bzl", "closure_repositories")
closure_repositories()

goog.provide somehow prevents the compiler from checking goog.require statements

I'm using bazel 0.2.2, installed following the instructions in bazel.io

Repro:

  • Create a new folder
  • sync the sources for bazelbuild/rules_closure
  • cd rules_closure/closure/compiler/test

edit hello.js and add the following line to the top of the file:

goog.require('foo');

Now verify that the build behaves as expected (it should fail)

bazel build :hello_bin

Now add the following line to the top of hello.js:

goog.provide('bar');

Build again:

bazel build :hello_bin

The build should have failed, however the library just builds fine.

Just to rule out a bug in the compiler I tried to repro using the closure compiler service here: http://closure-compiler.appspot.com (see https://developers.google.com/closure/compiler/docs/gettingstarted_ui for deatils about it) and it works as expected.

This behavior seems related to the "--depencency_mode=LOOSE" flag int he compiler.

I might be missing something important here but: why does the closure_js_binary rule specify that flag by default if I don't specify a 'main' value in the rule configuration?

Consider js2-closure integration

With clang-format based style enforcement (#85) out for review we should consider also adding https://github.com/jart/js2-closure support. The two seem like they could work very well together as a save hook from an editor. If rules_closure could automatically regenerate the "provides index" the entire setup would be very user friendly I think.

closure library required dependency for closure_template_js_library

If compiling without first adding dependency on the closure library:

    deps = [
        "@io_bazel_rules_closure//closure/library",
    ],

this error is printed when building the template library:

JavaScript strict dependency checking failed D:

These namespaces were required by {build target}

    goog.asserts

In the following files:

    bazel-out/local_linux-fastbuild/genfiles/{soy template file}

I'll attach a reproduction scenario when I have time - unless it seems sufficient to just document this.

Runfiles can't be found when workspace() name is set

If I'm working on a separate project that uses Closure Rules as a dependency, and I put something like this in my WORKSPACE file:

workspace(name = "LOLCATATTACK")

Then I get errors like this:

bazel-out/host/bin/external/io_bazel_rules_closure/closure/templates/SoyToJsSrcCompiler: line 194: /usr/local/google/home/jart/.cache/bazel/_bazel_jart/e2f31d67319a8e487e516a36d39fd224/my-project/bazel-out/host/bin/external/io_bazel_rules_closure/closure/templates/SoyToJsSrcCompiler.runfiles/LOLCATATTACK/external/local_jdk/bin/java: No such file or directory

Maybe @kchodorow could clarify when this will be fixed?

Configurable source mapping

We do some cool stuff to configure the --source_map_location_mapping flag. The only configuring it does at the moment, is getting rid of the weird bazel-specific directory names.

However we should also allow the user to specify his own path mappings. For example, he might want java/com/google/foo/js/... to be represented as /assets/js/... in the sourcemap file.

Therefore an argument should be added to closure_js_binary and closure_js_deps that accepts a string map of bazel directories to web server paths.

No such package 'closure/templates'

Hi,

For simplest soy building, I met following error:

ERROR: /Users/jacob/projects/feedbacker/src/assets/test/BUILD:32:1: no such package 'closure/templates': BUILD file not found on package path and referenced by '//:hello_soy'.
ERROR: Loading failed; build aborted.

Following are my files, is there anything that I missed?

WORKSPACE:

git_repository(
    name = "io_bazel_rules_closure",
    remote = "https://github.com/bazelbuild/rules_closure.git",
    tag = "0.0.1",
)
load("@io_bazel_rules_closure//closure:defs.bzl", "closure_repositories")
closure_repositories()

BUILD:

load("@io_bazel_rules_closure//closure:defs.bzl", "closure_template_js_library")
closure_template_js_library(
    name = "hello_soy",
    srcs = ["hello.soy"]
)

hello.soy:

{namespace hello.templates autoescape="strict"}

/**
 * Renders an element containing the text "hello".
 */
{template .hello}
  <div class="{css hello-container}">Hello.</div>
{/template}

hello.js:

goog.provide('hello');

goog.require('goog.soy');
goog.require('hello.templates');

goog.soy.renderElement(document.body, hello.templates.hello);

hello.gss:

hello.gss

.hello-container {
  color: red;
  font-weight: bold;
}

contrib/externs/jquery-1.9.js not accepted

Hi, I'm just taking these rules for a spin. I know they say alpha, so if the issues aren't helpful, feel free to tell me to hold off for a bit.

This issue is about using jquery externs in the js build.

BUILD

closure_js_binary(
    name = "coffeerun_bin",
    main = "coffeerun",
    deps = [":coffeerun_lib"],
)

closure_js_library(
    name = "coffeerun_lib",
    srcs = glob(["scripts/*.js"]),
    deps = [
        "@io_bazel_rules_closure//closure/library",
        ":coffeerun_soy",
        ":jquery",
    ]
)

closure_js_library(
    name = "jquery",
    externs = ["externs/jquery-1.9.js"],
)

Referencing this file:
https://github.com/google/closure-compiler/blob/master/contrib/externs/jquery-1.9.js

Fails with this error:

externs/jquery-1.9.js:160: ERROR - All constants must be typed. The compiler could not infer the type of this constant. Please use an explicit type annotation.
var $ = jQuery;
    ^

1 error(s), 0 warning(s)

Additionally, I successfully use this externs file in my normal build. Is it intentional that it's more strict, or is there a way to disable that extra strictness?

Thanks!

Missing libfontconfig dependency

See http://ci.bazel.io/job/rules_closure/BAZEL_VERSION=HEAD,PLATFORM_NAME=linux-x86_64/4/console:

____[11 / 29] Testing //closure/testing/test:arithmetic_module_test
FAIL: //closure/testing/test:arithmetic_es6module_test (see /home/ci/.cache/bazel/_bazel_ci/f4ef80a8a473f3eedd2e46be717300bf/linux-x86_64/bazel-out/local_linux-fastbuild/testlogs/closure/testing/test/arithmetic_es6module_test/test.log)
____From Testing //closure/testing/test:arithmetic_es6module_test:
==================== Test output for //closure/testing/test:arithmetic_es6module_test:
third_party/phantomjs/phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory
================================================================================
FAIL: //closure/testing/test:arithmetic_es6typed_test (see /home/ci/.cache/bazel/_bazel_ci/f4ef80a8a473f3eedd2e46be717300bf/linux-x86_64/bazel-out/local_linux-fastbuild/testlogs/closure/testing/test/arithmetic_es6typed_test/test.log)
____From Testing //closure/testing/test:arithmetic_es6typed_test:
==================== Test output for //closure/testing/test:arithmetic_es6typed_test:
third_party/phantomjs/phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory
================================================================================
FAIL: //closure/testing/test:arithmetic_scope_test (see /home/ci/.cache/bazel/_bazel_ci/f4ef80a8a473f3eedd2e46be717300bf/linux-x86_64/bazel-out/local_linux-fastbuild/testlogs/closure/testing/test/arithmetic_scope_test/test.log)
____From Testing //closure/testing/test:arithmetic_scope_test:
==================== Test output for //closure/testing/test:arithmetic_scope_test:
third_party/phantomjs/phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory
================================================================================
FAIL: //closure/testing/test:arithmetic_module_test (see /home/ci/.cache/bazel/_bazel_ci/f4ef80a8a473f3eedd2e46be717300bf/linux-x86_64/bazel-out/local_linux-fastbuild/testlogs/closure/testing/test/arithmetic_module_test/test.log)
____From Testing //closure/testing/test:arithmetic_module_test:
==================== Test output for //closure/testing/test:arithmetic_module_test:
third_party/phantomjs/phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory
================================================================================
FAIL: //closure/testing/test:simple_test (see /home/ci/.cache/bazel/_bazel_ci/f4ef80a8a473f3eedd2e46be717300bf/linux-x86_64/bazel-out/local_linux-fastbuild/testlogs/closure/testing/test/simple_test/test.log)
____From Testing //closure/testing/test:simple_test:
==================== Test output for //closure/testing/test:simple_test:
third_party/phantomjs/phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory
================================================================================
FAIL: //closure/library/test:dom_test (see /home/ci/.cache/bazel/_bazel_ci/f4ef80a8a473f3eedd2e46be717300bf/linux-x86_64/bazel-out/local_linux-fastbuild/testlogs/closure/library/test/dom_test/test.log)
____From Testing //closure/library/test:dom_test:
==================== Test output for //closure/library/test:dom_test:
third_party/phantomjs/phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory
================================================================================

This is apparently a known issue with phantomjs: ariya/phantomjs#10904.

Looks like it could be downloaded from https://cgit.freedesktop.org/fontconfig/ with new_git_repository.

Repeat build binary output fails following a successful run

I've been able to successfully build an ADVANCED mode compiled binary output via this test repository. However, repeating the last command bazel build //:client_bin fails with the given error. One would assume that bazel would know nothing has changed and exit 0 immediately. However, there is some process that is removing the bazel-bin/client_bin.js file and causing a problem.

The workaround is trivial: make a change to any input *.js file and bazel will rebuild the output successfully again. Might be something I'm doing wrong.

pcj@carotid:~/github/rules_closure-getting-started$ ~/bin/bazel build //:client_bin
INFO: Found 1 target...
Target //:client_bin up-to-date:
  bazel-bin/client_bin.js
INFO: Elapsed time: 14.067s, Critical Path: 13.90s
pcj@carotid:~/github/rules_closure-getting-started$ ~/bin/bazel build //:client_bin
INFO: Found 1 target...
ERROR: /Users/pcj/github/rules_closure-getting-started/BUILD:24:1: Compiling 809 JavaScript files to client_bin.js failed: compiler failed: error executing command bazel-out/local-fastbuild/bin/external/io_bazel_rules_closure/closure/compiler/compiler '--js_output_file=bazel-out/local-fastbuild/bin/client_bin.js' ... (remaining 826 argument(s) skipped): com.google.devtools.build.lib.shell.BadExitStatusException: Process exited with status 1.
ERROR - Cannot read: bazel-bin/client_bin.js

ERROR - Cannot read: bazel-out/local-fastbuild/bin/client_bin.js

2 error(s), 0 warning(s)
Target //:client_bin failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 2.225s, Critical Path: 2.01s

suppress of diagnostic group triggers "contains superfluous suppress codes" error

Using a closure_js_library() suppress for a diagnostic group (eg: nonStandardJsDocs) triggers a contains superfluous suppress codes error message even when the suppression hides warnings. For example:

ahochhaus@ahochhaus-pc:~/ll$ cat test/BUILD 
load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_library")

closure_js_library(
  name = "example_lib",
  srcs = ["example.js"],
  deps = [
      "@io_bazel_rules_closure//closure/library",
  ],
  suppress = [
    "nonStandardJsDocs",
  ],
  visibility = ["//visibility:public"],
)
ahochhaus@ahochhaus-pc:~/ll$ cat test/example.js 
/**
 * @typedef {{
 *   timestamp: number,
 *   id: number,
 *   type: string,
 *   fromAdaptation: boolean
 * }}
 *
 * @property {number} timestamp
 *   The timestamp the choice was made, in seconds since 1970
 *   (i.e. Date.now() / 1000).
 * @property {number} id
 *   The id of the stream that was chosen.
 * @property {string} type
 *   The type of stream chosen ('audio', 'text', or 'video')
 * @property {boolean} fromAdaptation
 *   True if the choice was made by AbrManager for adaptation; false if it
 *   was made by the application through selectTrack.
 * @exportDoc
 */
shakaExtern.StreamChoice;
ahochhaus@ahochhaus-pc:~/ll$ bazel build test/...
INFO: Found 1 target...
ERROR: /home/ahochhaus/ll/test/BUILD:3:1: Checking 1 JS files in //test:example_lib failed: namespace-sandbox failed: error executing command /home/ahochhaus/.cache/bazel/_bazel_ahochhaus/9b0316414c69160d24362f2991b802bb/ll/_bin/namespace-sandbox ... (remaining 11 argument(s) skipped).
ERROR - Build rule (//test:example_lib) contains superfluous suppress codes: nonStandardJsDocs

1 error(s), 0 warning(s)

Target //test:example_lib failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 0.820s, Critical Path: 0.65s
ahochhaus@ahochhaus-pc:~/ll$ sed -i 's/"nonStandardJsDocs/#"nonStandardJsDocs/g' test/BUILD 
ahochhaus@ahochhaus-pc:~/ll$ bazel build test/...
INFO: Found 1 target...
INFO: From Checking 1 JS files in //test:example_lib:
test/example.js:19: WARNING - Parse error. illegal use of unknown JSDoc tag "exportDoc"; ignoring it
 * @exportDoc
   ^

0 error(s), 1 warning(s)

Target //test:example_lib up-to-date (nothing to build)
INFO: Elapsed time: 0.832s, Critical Path: 0.66s

The superfluous suppress error should only be triggered when no warnings or errors are suppressed.

P.S. Sorry for my absence. I intend to resume my clang format work soon...

Replace JSChecker with Java version that plugs into compiler

The current linter rule (closure_js_lint_test) uses the deprecated python closure-linter instead of the the new linter.jar (which is open sourced in the closure-compiler repository). The new linter has better support for ES6.

Can closure_js_lint_test be upgraded to use the new linter?

include uncompiled javascript files for closure_js_test

I need to write tests that have a runtime dependency on angular. I've tried including angular in deps and compiling it but the end result seems to be mangled code. Can we add a way for the test runner to load libraries that are non-compatible with closure before the test files?

How is this different/same as plovr?

I'm just looking at this project and trying to figure out if it replaces plovr. At first glance it seems like there is overlap with this project and what @bolinfest had intended many years ago with plovr.

One of things that I can't give up with plovr is build times. the plovr serve command is the only good way I know of keeping a JVM hot with the closure compiler. With a cold start JVM my build times are on the order of 30s, but with plovr serve after the first compile they're about 4-5s.

Does this project somehow replicate the plovr serve command? Again the crux issue is keeping the JVM running between compiles.

Support XMB L10N stuff

XMB = XML Message Bundle

I need to write support for all the translated text stuff supported by the Closure Compiler and Closure Templates.

phantomjs.sh not found

I've found the following in the error log when running bazel test for closure_js_test rules:

exec ${PAGER:-/usr/bin/less} "$0" || exit 1
-----------------------------------------------------------------------------
{test file}: 2: exec: third_party/phantomjs/phantomjs.sh: not found

JsChecker should check global symbols

If a closure_js_library has a strict language, then JsChecker's strict dependency checking should also apply to global symbols—not just goog / es6 namespaces. For example, if I say doodle = 6; then an error should be thrown if my library does not depend on a rule that defines var doodle = ...;. Either as source code or externs.

Furthermore, we should enforce a strict ordering. If I have multiple .js files in a single library rule, an error should be thrown if they share globals, if and only if they don't use namespaces (i.e. don't call goog.provides.) In other words, we enforce that the ordering within srcs be undefined for files without namespaces. This forces the user to either: a) adopt namespaces; or b) write really precise build rules that correctly model the relationships between files.

Implementation: For each defined symbol in both srcs and externs, add a global:foo line to the library-provided.txt file. Then validate referenced symbols against those, using the existing JsChecker infrastructure. Easy peasy.

pedantic mode option to make deprecated & unnecessaryCasts errors

This is more of a question than an issue but I couldn't find a mailing list. What is the best forum for end user discussion about the bazel rules_closure?

When setting pedantic mode, deprecated and unnecessaryCasts are only warnings (not errors).

JS_PEDANTIC_ARGS = [
    "--jscomp_error=*",
    "--jscomp_warning=deprecated",
    "--jscomp_warning=unnecessaryCasts",
]

This can be overcome by passing flags directly to the compiler in the BUILD file, for example:

defs = [
  "--jscomp_error=deprecated",
  "--jscomp_error=unnecessaryCasts",
],

I would expect pedantic mode to make all diagnostic groups errors. Is the best way to override the default pedantic behavior by using defs (as above)? Am I missing a better configuration hook?

Set --define=goog.json.USE_NATIVE_JSON by default

At this point I think most new code should set goog.json.USE_NATIVE_JSON by default. The few users who need IE7- support or have specific JSON parsing needs can disable explicitly.

The tricky part about enabling it automatically in closure_js_binary() is that the compiler define can only be set when goog.json is transitively required. The skylark rule does not currently know which closure library sources will be used. Rather all closure library sources are passed to the compiler and the compiler drops the unused ones.

One idea is that we could instrument JsChecker to return the list of transitively required sources during closure_js_library() and then maybe closure_js_binary() could conditionally set the define based on that list?

What is the idiomatic approach to conditionally set defines?

CSS Checker

We need a Java program that plugs into the CSS compiler (just like JsChecker) which will do two things:

  1. Strict dependency checking: Validate dependent rules form a transitive closure.
  2. Output a rule-provided.txt file containing a css:foo for each .foo { ... } which can be used by JsChecker to validate goog.getCssName('foo') statements.

CC: @iflan

rules_protobuf project?

Sorry for opening this issue on rules_closure but I don't know where else to put it.

When adding JSPB support #68, @jart asked:

@damienmg @kchodorow Should we start a new bazelbuild/rules_protobuf project?

What is the current thinking on a rules_protobuf project?

My reason for asking is that I'm working on a set of Go PB rules and I would like to be able to contribute them to the bazel community in a shared location. I could attempt to put them in rules_go, however it seems like moving all of the protobuf rules to a central repo may be cleaner.

closure_library.BUILD can't be referenced across repositories

When trying to build a closure_js_binary target, I'm now seeing this error:

ERROR: /home/wolfgang/.cache/bazel/_bazel_wolfgang/b53da5dfcf8e186eb6c4fd823f36a680/external/io_bazel_rules_closure/closure/compiler/jschecker/BUILD:17:1: no such package '@closure_library//': In new_http_archive rule //external:closure_library the 'build_file' attribute does not specify an existing file (/home/wolfgang/example-project/closure/library/closure_library.BUILD does not exist) and referenced by '@io_bazel_rules_closure//closure/compiler/jschecker:jschecker'.
ERROR: Loading failed; build aborted.
INFO: Elapsed time: 0.080s

Warnings about missing types from compiler

Types that are defined in extern files show up as undefined types in the compiler output. These are just warnings, and don't prevent the output of the closure_js_binary. I'll provide a reproduction scenario when I have time, logging this now before I forget.

Bump to 0.1.1

...or whatever your next release label is. The README.md is a little behind: I was struggling to figure out why closure_proto_js_library could not be found until I realized it does not exist in 0.1.0. Worked after I upgraded to:

git_repository(
    name = "io_bazel_rules_closure",
    remote = "https://github.com/bazelbuild/rules_closure.git",
    commit = "80d493d5ffc3099372929a8cd4a301da72e1b43f"
)

Create abstract closure_template_library rule

One of the nice things about Skylark is if you define multiple ctx.action statements inside a rule, it will only run each individual action if necessary. Therefore, it is possible for us to define a closure_template_library rule that generates the JS, Java jar, Python, etc. all at once, and the user only pays for what he needs.

But this is all dependent on whether or not we can export properties in the returned struct that Bazel will understand. I'm hoping that the correct properties will be as follows:

  • Java: compile_time_jars, runtime_jars
  • Python: transitive_py_files

These are the properties exported by their Skylark reference implementations, e.g. py_rules.bzl. The problem is I'm not sure yet if the native rules will understand them. More research is required.

Disable default externs

Closure Compiler by default is --env=BROWSER which causes 28,606 lines of @externs code to be added to each compilation. This has a four second impact on compilation time. It can't really be optimized away because externs aren't namespaced. So we'd be better off if we:

  1. Only load es{3,5,6}.js by default, depending on the input language.
  2. Define a closure_js_library for each browser externs file, e.g. //closure/externs/browser:html5
  3. Update //closure/library to have the minimum number of deps on these externs. Break hard edges if possible. For example, if only one .js file in Closure Library depends on the gigantic webgl.js externs, then maybe that part of Closure Library should be broken out into a separate build rule.
  4. Define a combined //closure/externs/browser rule for the lazy, that basically exports all the libraries in the package. Adding that as a dep will be equivalent to saying --env=BROWSER.
  5. Repeat for contrib externs, e.g. //closure/externs/contrib/angular:v1_5, as per #51.
  6. Write a file_test() that checks the directory listing of externs.zip so Closure Rules maintainers integrating a compiler new release can be informed when they need to update our externs rules.

This is a breaking change that deviates from the design chosen by the Closure Compiler team. I think this is a good idea for two reasons:

  1. It makes compiles go four seconds faster.
  2. It will teach new users about externs.

If the user gets an error saying, "hey! document is undefined. you probably want to depend on @io_bazel_rules_closure//closure/externs/browser:window!" Then he's going to wonder what externs are. He'll read the file. See how Closure rigorously defines type information for everything—even code that isn't in the compilation. And then he's going to begin to understand the Closure Compiler and why it is good.

Blocked by: #80

closure_js_deps specifies deps attribute instead of srcs

When using the deps attribute as specified in the readme for closure_js_deps rules, the following error occurs:
no such attribute 'deps' in 'closure_js_deps' rule
I notice there is a similar attribute in the definition called srcs - either the readme or the definition is using the wrong attribute name.

rules_closure job on ci.bazel.io is broken @HEAD

See http://ci.bazel.io/job/rules_closure/BAZEL_VERSION=HEAD,PLATFORM_NAME=linux-x86_64/26/console

Error:

____[84 / 162] Creating source manifest for //closure/testing/test:arithmetic_scope_test
ERROR: /home/ci/workspace/rules_closure/BAZEL_VERSION/HEAD/PLATFORM_NAME/linux-x86_64/closure/compiler/test/BUILD:106:1: Sanity checking 1 JS files in //closure/compiler/test:es6arrow_lib failed: namespace-sandbox failed: error executing command 
  (cd /home/ci/.cache/bazel/_bazel_ci/f4ef80a8a473f3eedd2e46be717300bf/linux-x86_64 && \
  exec env - \
  /home/ci/.cache/bazel/_bazel_ci/f4ef80a8a473f3eedd2e46be717300bf/linux-x86_64/_bin/namespace-sandbox @/home/ci/.cache/bazel/_bazel_ci/f4ef80a8a473f3eedd2e46be717300bf/linux-x86_64/bazel-sandbox/a8b6fde1-b159-417f-8260-9e552f6a4725-0.params -- bazel-out/local-fastbuild/bin/closure/compiler/jschecker/jschecker '--output_file=bazel-out/local-fastbuild/bin/closure/compiler/test/es6arrow_lib-provided.txt' '--label=//closure/compiler/test:es6arrow_lib' '--src=closure/compiler/test/es6arrow.js').
Traceback (most recent call last):
  File "/home/ci/.cache/bazel/_bazel_ci/f4ef80a8a473f3eedd2e46be717300bf/linux-x86_64/bazel-out/local-fastbuild/bin/closure/compiler/jschecker/jschecker.runfiles/io_bazel_rules_closure/closure/compiler/jschecker/jschecker.py", line 47, in <module>
    from external.closure_library.closure.bin.build import source
ImportError: No module named external.closure_library.closure.bin.build
____Building complete.
____Elapsed time: 7.129s, Critical Path: 2.67s

My opinion: the causing import statement should just be from closure.bin.build import source and it should work

Property quoting compiler pass

I was reading what @WebReflection wrote in 5 Reasons To Avoid Closure Compiler In Advanced Mode back in 2013 and I struck by an idea that might be interesting.

What if ADVANCED mode could be specified on a per-library basis?

That way you can link legacy code into your binary without having to turn off minification uber alles for the entire binary. Or using a separate script tag. This should be beneficial to open source users with heterogeneous codebases.

In order for this to work:

  1. The library rules would have to propagate the set of primitive source files to the binary rule.
  2. A compiler pass would have to be introduced that rewrites primitive source files to quote stuff.

For example, the following primitive file:

window.jeepers = 'creepers';
function madDogsAndEnglishmen() {
  function goOutInTheMiddaySun() {
    return 'there';
  }
  return {hi: goOutInTheMiddaySun()};
}
closure_js_library(
    name = "primitive_lib",
    srcs = ["primitive.js"],
    advanced = False,
)

Would be rewritten to the following mid-compilation when making the closure_js_binary:

goog.global['window']['jeepers'] = 'creepers';
goog.global['madDogsAndEnglishmen'] = function() {
  function goOutInTheMiddaySun() {
    return 'there';
  }
  return {'hi': goOutInTheMiddaySun()};
}

Has something like this been considered before @MatrixFrog? I poked through the jscomp codebase real quick and didn't see any passes that auto-quote properties.

CC: @hochhaus

Need concrete examples of usage

It would be helpful to add some concrete examples of how to use the closure rules in either the readme (which is already long, so maybe not) or an examples subdirectory that is linked to by the readme.

JsChecker may not honor function level suppressions

When updating to library/compiler version v20160517 JsChecker reports the following warnings:

INFO: From Checking 812 JS files in //closure/library:library:
external/closure_library/closure/goog/datasource/expr.js:276: WARNING lintChecks JSC_MISSING_REQUIRE_CALL_WARNING - missing require: 'goog.ds.DataManager'
                                  goog.ds.DataManager.getInstance();
                                  ^

external/closure_library/closure/goog/graphics/vmlelement.js:116: WARNING lintChecks JSC_MISSING_REQUIRE_CALL_WARNING - missing require: 'goog.graphics.VmlGraphics'
      goog.graphics.VmlGraphics.toSizeCoord(height);
      ^

external/closure_library/closure/goog/graphics/vmlelement.js:276: WARNING lintChecks JSC_MISSING_REQUIRE_CALL_WARNING - missing require: 'goog.graphics.VmlGraphics'
  style.height = goog.graphics.VmlGraphics.toSizePx(height);
                 ^

external/closure_library/closure/goog/graphics/vmlelement.js:421: WARNING lintChecks JSC_MISSING_REQUIRE_CALL_WARNING - missing require: 'goog.graphics.VmlGraphics'
  style.height = goog.graphics.VmlGraphics.toPosPx(height);
                 ^

external/closure_library/closure/goog/net/browsertestchannel.js:376: WARNING lintChecks JSC_MISSING_REQUIRE_CALL_WARNING - missing require: 'goog.net.BrowserChannel'
      goog.net.BrowserChannel.createChannelRequest(this, this.channelDebug_);
      ^

external/closure_library/closure/goog/net/channelrequest.js:1129: WARNING lintChecks JSC_MISSING_REQUIRE_CALL_WARNING - missing require: 'goog.net.BrowserChannel'
  this.watchDogTimerId_ = goog.net.BrowserChannel.setTimeout(
                          ^

0 error(s), 6 warning(s)

However, each of these functions already contains a function level suppression:

closure/goog/datasource/expr.js
closure/goog/graphics/vmlelement.js
closure/goog/net/browsertestchannel.js
closure/goog/net/channelrequest.js

More research should be done to understand what is going on here. It could be possible that JSChecker is not honoring suppressions on function bodies.

Implement JS <-> CSS checking / linking

The documentation in the README describes how JS library rules can depend on CSS library rules. This hasn't been implemented yet. Same goes for the flag on the JS binary rule that depends on the CSS binary. We need to code this stuff.

Brought up in: /issues/24

closure/templates not found

Error when using closure_template_js_library. I believe this is due to the same problem as #9 - when I have time, I can provide a way to reproduce.

no such package 'closure/templates': BUILD file not found on package path and referenced by '{build target}'.

should_generate_js_doc ignored by closure_template_js_library

Currently JS Docs are not generated by closure_template_js_library() even though should_generate_js_doc defaults to 1. The should_generate_js_doc argument appears unused in closure_template_js_library.bzl.

+  if should_generate_js_doc:
+    cmd += ["--shouldGenerateJsdoc"]

closure_template_java_library not building

Hi,

I was hoping to get advice on the recommended way to get my closure_template_java_library target to build. It looks like it hard codes in an expectation that Guava is in my source tree, but maybe I'm missing something.

I'm using the code in this repo:
https://github.com/robfig/undertow-bazel-closure-tools

WORKSPACE

load("@io_bazel_rules_closure//closure:defs.bzl", "closure_repositories")
closure_repositories()

maven_jar(
    name = "com_google_guava_guava",
    artifact = "com.google.guava:guava:19.0",
)

BUILD

load("@io_bazel_rules_closure//closure:defs.bzl", "closure_template_java_library")

closure_template_java_library(
    name = "coffeerun_soy_java",
    srcs = ["templates/index.soy"], 
    java_package = "com.robfig",
    deps = [
        ":com_google_guava_guava",
    ],
)

java_library(
    name = "com_google_guava_guava",
    visibility = ["//visibility:public"],
    exports = [
        "@com_google_guava_guava//jar",
    ],
)

ERROR

$ ~/bazel/output/bazel build :coffeerun_soy_java
.........
ERROR: /Users/robfig/closure-tools-server/BUILD:60:1: no such package 'java/com/google/common/collect': BUILD file not found on package path and referenced by '//:coffeerun_soy_java'.

Thanks!
Rob

closure_js_deps should only output foo-runfiles.js

The default output file contains the weird Bazel-specific directory names. It's only there because that's how it's done internally at Google. But I have no idea what people could possibly want to do with that file. So I think it should be changed to only output the -runfiles file.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.