JavaScript & TypeScript

Stay organized with collections Save and categorize content based on your preferences.

This describes JavaScript-specific guidance for checking code into //piper/third_party.

IMPORTANT: Read go/thirdparty first.

NOTE: This file applies to TypeScript as well as JavaScript.

General policies

NOTE: You should apply these changes on the initial checkin, even though it may mean your code is not "pristine."

IMPORTANT: Using third-party JavaScript code that contains license text or copyright notices requires special treatment in the JavaScript source.

Since the Google JavaScript compiler strips out most comments in .js source files, JavaScript files with license and copyright comments require special treatment. Even 'notice' licenses, which are usually considered not very strict in most respects, require the special @license JsDoc tag so that the notice is preserved. This is because JavaScript is distributed in its source form when it is used by browsers. Similarly, the same requirement applies to .css, .html, .ts and other files with content that may be served to users.

JavaScript source code should go into //third_party/javascript/packagename directories.

New third-party JavaScript package code reviews should be cc'ed to both emailremoved@ and emailremoved@ to ensure prompt, assigned reviews.

If the file already has licensing information, you need to make sure it will be preserved by the compiler. (If it does not already have licensing information, skip to the next section.)

To prevent license text in a JavaScript source file from being removed, wrap the desired text in a JsDoc comment and add the special @license tag. If the source already includes a JsDoc comment with a @preserve tag, that is sufficient as well.

/**
 * @license
 * Copyright 2008 SomeThirdParty.
 * Here is the full license text and copyright
 * notice for this file. Note that the notice can span several
 * lines and is only terminated by the closing star and slash:
 */
var foo = /...
function someThirdPartyFunc() {
  /...
}

If you include a license/preserve block, the JS Compiler will output the contents of the block in the compiled output of any js_binary rule. You should examine the compiled output and make sure the license block is present and legible.

Add a @license block for JavaScript released under a license with a notice requirement

If the original source code's license terms include a notice requirement but the source files lack license and copyright info, you should add an @license block containing, at a minimum, a copyright statement and the full license text or SPDX-License-Identifier to each source file.

NOTE: If the source files have license and copyright info, but it doesn't meet the minimum requirements, you should add the missing information.

JavaScript @externs and TypeScript .d.ts files are an exception: since they are never served to the user, they do not need a @license block. For clarity, .tsx files are subject to the @license block requirement.

For the Apache License, it is sufficient to include the shorter provided notice. For all other licenses, the full license must be included.

It is not necessary to add the @license block to files which will not be packaged with an application, but where we are acting like a CDN. This only applies to non-Google libraries hosted in //third_party/hosted_libraries/ (https://developers.google.com/speed/libraries). (If you have another location to add to this list, email emailremoved@ first.)

Using SPDX-License-Identifier

To reduce payload size, while still complying with our notice obligations, you can use SPDX identifiers to identify the license the code is released under:

/**
 * @license
 * Copyright 2000 Example, Inc
 * SPDX-License-Identifier: Apache-2.0
 */

Source which contains an existing @license block with license or copyright information should be preserved. Existing license text or copyright information should never be removed from the upstream third-party source.

If it does not include an SPDX license identifier line or the full text of the license, the relevant SPDX line should be added, or the full license text if no SPDX identifier exists.

For example, the (upstream) block:

/**
 * @license
 * Copyright 2000 Example, Inc
 * This code is released under the MIT license.
 */

would be expanded (in third_party) to:

/**
 * @license
 * Copyright 2000 Example, Inc
 * This code is released under the MIT license.
 * SPDX-License-Identifier: MIT
 */

We only support a simple SPDX-License-Identifier values. We do not support SPDX License Expressions.

For dual licensed code (i.e. MIT or GPL), you only need to include the identifier for one Google will be using, which will be least restrictive one. See go/thirdpartylicenses#same.

See go/simpler-js-notices for more information on our SPDX-License-Identifier policy.

NOTE: This currently only applies to code in third_party. Code being released to the outside world must still use the full license header.

Legacy third_party/javascript packages created before the @license tag

Prior to 2008-4-10, the @license JsDoc tag did not exist and the ThirdParty team recommended that that JavaScript files containing notices remain uncompiled. This restriction has been lifted. If you maintain or depend on a js_library file with do_not_compile in the name, see if you can work with the authors to embed copyright and license information in an @license tag. This will allow your users to benefit from the faster download times of compiled JavaScript.

JavaScript packages and embedded dependencies

Many JavaScript packages are distributed as bundles where the code dependencies have been compiled, inlined, or otherwise included in a single file with the source.

Ideally, these embedded dependencies should be removed, checked in as separate packages, and referenced via BUILD files. However, in the cases where this is not possible, the guidelines about packages that contains code with portions under different licenses apply. In particular:

  • The file-scope licenses() in the BUILD file needs to reflect the MOST restrictive license.

  • The full license texts of each included transitive dependency need to be concatenated in the package LICENSE file, separating the different licenses with dashed line dividers.

  • The copyright statements and full license texts of each included transitive dependency need to be placed in a @license block in the bundled source file being checked in.

IMPORTANT: Before attempting to check in compiled/inlined/bundled JavaScript, you should have a conversation with emailremoved@ and pending the outcome of that discussion, request a go/oneversion exception. Compiled/inlined/bundled JavaScript can violate several go/thirdparty policies and potentially expose the company to security or legal risks. Be prepared to learn that the software you wish to use may not be possible without significant extra work.

Caveat for JavaScript code for use in borgmon consoles

The //piper/.../third_party tree exists to contain third-party JavaScript code for use in borgmon consoles. It has a separate location in Piper so that it will be pushed out to production along with the rest of the borgmon configs. Packages in //piper/.../third_party still need to follow the general guidelines above, with the exception that the BUILD file need not contain any real build rules, just the comment sections from the latest BUILD file templates and a file-scope licenses() directive.

Importing (L)GPL JS libraries

You may add (L)GPL JS libraries to //piper/third_party/javascript, but if you do so they MUST NOT be compiled as part of a build rule. In order to meet the requirements of the (L)GPL, the correct way to include your script is via a SCRIPT tag. Your BUILD file will therefore simply export the files. E.g.:

filegroup(
   name = "my_amazing_library",
   srcs = glob(["*.js"]),
)

You may then include this as a data dependency of another target.

Note that including an (L)GPL library will have legal impact on your product. In particular:

  1. You will be required to make sure the unobfuscated source to the LGPL portion is available (pointing to someone else's copy is not enough), and the license is available as well.

  2. Users will be allowed to modify your product, and reverse engineer it for the purpose of debugging those modifications.

You cannot prevent this (and go/uTos does not), and you must make sure if you are not on go/uTos that any TOS you have does not violate this by banning reverse engineering without an open source license override.

Multiple versions

go/oneversion applies to javascript libraries. The exception process is documented at go/oneversion#exceptions. Reviewers: any time you see a multiple_versions section in the METADATA file, that approval field MUST contain a link to a bug link or emailremoved@ thread where the exception was granted. go/oneversion is the source for truth for the current policy. See the section on node.js modules for special versioning rules for those imports.

TypeScript

For the purposes of this policy, TypeScript code is treated exactly as JavaScript code would be. TypeScript is checked in underneath //piper/third_party/javascript as .ts files and transpiled to JavaScript using ts_library BUILD rules (or ng_module, or ts_declaraton, as appropriate). .d.ts files are exempt from the @license tag requirement since they only contain type definitions and are never distributed to users, similar to @externs files for JavaScript.

See also go/typescript/third_party#typescript for more documentation.

Note that TypeScript code, in addition to an @license tag, requires an empty line after the initial file comment.

/**
 * @license The license of the code.
 */

// Note the empty line above.
class X { }

DefinitelyTyped type definitions, i.e. type definitions that are developed separately from the actual implementation code. Please see //piper/third_party/javascript/typings/README.md for specific instructions on how to use and sync those.

In addition to emailremoved@, please contact emailremoved@ with any issues.

NodeJS / npm modules

NodeJS modules live in //piper/third_party/javascript/node_modules. See go/nodemodulesingoogle3 for details, including relevant tooling. See here for a deeper dive discussing npm packages.

NOTE: Using npm in a package outside of google3? There's a tool for making license checking easier!