blob: 0a05a6afa685217e550843c5f9ca4f81eab9abc7 [file]
<!DOCTYPE html>
<html itemscope itemtype="https://schema.org/WebPage" lang="en">
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/rules_nodejs/repositories.html" rel="canonical">
<link href="" rel="shortcut icon" type="image/png">
<title>rules_nodejs - Generated Repositories</title>
<!-- Webfont -->
<link href="//fonts.googleapis.com/css?family=Source+Code+Pro:400,500,700|Open+Sans:400,600,700,800" rel="stylesheet">
<!-- Bootstrap -->
<link crossorigin="anonymous" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" rel="stylesheet">
<!-- Font Awesome -->
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- Custom stylesheet -->
<link href="/rules_nodejs/css/main.css" rel="stylesheet">
<!-- metadata -->
<meta content="rules_nodejs" name="og:title"/>
<meta content="JavaScript and NodeJS rules for Bazel" name="og:description"/>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top" id="common-nav">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button class="navbar-toggle collapsed" data-target="#bs-example-navbar-collapse-1" data-toggle="collapse"
type="button">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/rules_nodejs/">
<img class="navbar-logo" src="/rules_nodejs/images/bazel-navbar.svg">
</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<form class="navbar-form navbar-right" action="/rules_nodejs/search.html" id="cse-search-box">
<div class="form-group">
<input type="hidden" name="cx" value="2735dc72dd157bd19">
<input type="search" name="q" id="q" class="form-control input-sm" placeholder="Search">
</div>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="https://github.com/bazelbuild/rules_nodejs">GitHub</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="container vpad">
<div class="row">
<div class="col-md-2">
<a aria-controls="sidebar-nav"
aria-expanded="false" class="btn btn-default btn-lg btn-block sidebar-toggle" data-toggle="collapse"
href="#sidebar-nav">
<i class="glyphicon glyphicon-menu-hamburger"></i> Navigation
</a>
<nav class="sidebar collapse" id="sidebar-nav">
<h3>rules_nodejs</h3>
<ul class="sidebar-nav">
<li><a href="/rules_nodejs/">Introduction</a></li>
<li><a href="install.html">Installation</a></li>
<li><a href="repositories.html">Repositories</a></li>
<li><a href="dependencies.html">Dependencies</a></li>
<li><a href="debugging.html">Debugging</a></li>
<li><a href="stamping.html">Stamping</a></li>
<li><a href="changing-rules.html">Making changes to rules_nodejs</a></li>
<li><a href="examples.html">Examples</a></li>
</ul>
<h3>Rules</h3>
<ul class="sidebar-nav">
<li><a href="/rules_nodejs/Built-ins.html">Built-ins</a></li>
<li><a href="/rules_nodejs/Concatjs.html">Concatjs</a></li>
<li><a href="/rules_nodejs/Cypress.html">Cypress</a></li>
<li><a href="/rules_nodejs/Jasmine.html">Jasmine</a></li>
<li><a href="/rules_nodejs/Labs.html">Labs</a></li>
<li><a href="/rules_nodejs/Protractor.html">Protractor</a></li>
<li><a href="/rules_nodejs/Rollup.html">Rollup</a></li>
<li><a href="/rules_nodejs/Terser.html">Terser</a></li>
<li><a href="/rules_nodejs/TypeScript.html">TypeScript</a></li>
</ul>
<h3>Community</h3>
<ul class="sidebar-nav">
<li><a href="https://github.com/bazelbuild/rules_nodejs/blob/master/CONTRIBUTING.md">Contribute to
rules_nodejs</a></li>
<li><a href="https://slack.bazel.build">Join #javascript on Slack</a></li>
<li><a href="https://github.com/bazelbuild/rules_nodejs/issues">Issue Tracker</a></li>
<li><a href="https://github.com/bazelbuild/rules_nodejs">Github</a></li>
</ul>
</nav>
</div>
<div class="col-md-8">
<div class="content">
<h1 id="generated-repositories">Generated Repositories</h1>
<p>rules_nodejs produces several repositories for you to reference.
Bazel represents your workspace as one repository, and code fetched or installed from outside your workspace lives in other repositories.
These are referenced with the <code class="language-plaintext highlighter-rouge">@repo//</code> syntax in your BUILD files.</p>
<h2 id="nodejs">@nodejs</h2>
<p>This repository is created by calling the <code class="language-plaintext highlighter-rouge">node_repositories</code> function in your <code class="language-plaintext highlighter-rouge">WORKSPACE</code> file.
It contains the node, npm, and yarn programs.</p>
<p>As always, <code class="language-plaintext highlighter-rouge">bazel query</code> is useful for learning about what targets are available.</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>bazel query @nodejs//...
@nodejs//:node
...
</code></pre></div></div>
<p>You don’t typically need to reference the <code class="language-plaintext highlighter-rouge">@nodejs</code> repository from your BUILD files because it’s used behind the scenes
to run node and fetch dependencies.</p>
<p>Some ways you can use this:</p>
<ul>
<li>Run the Bazel-managed version of node: <code class="language-plaintext highlighter-rouge">bazel run @nodejs//:node path/to/program.js</code></li>
<li>Run the Bazel-managed version of npm: <code class="language-plaintext highlighter-rouge">bazel run @nodejs//:npm</code></li>
<li>Run the Bazel-managed version of yarn: <code class="language-plaintext highlighter-rouge">bazel run @nodejs//:yarn</code></li>
<li>Install dependencies from nested package.json file(s) which were passed to <code class="language-plaintext highlighter-rouge">node_repositories#package.json</code>
<ul>
<li>using npm: <code class="language-plaintext highlighter-rouge">bazel run @nodejs//:npm_node_repositories install</code></li>
<li>using yarn: <code class="language-plaintext highlighter-rouge">bazel run @nodejs//:yarn_node_repositories</code></li>
</ul>
</li>
</ul>
<h2 id="npm">@npm</h2>
<p>This repository is created by calling the <code class="language-plaintext highlighter-rouge">npm_install</code> or <code class="language-plaintext highlighter-rouge">yarn_install</code> function in your <code class="language-plaintext highlighter-rouge">WORKSPACE</code> file.</p>
<p>The name <code class="language-plaintext highlighter-rouge">@npm</code> is recommended in the simple case that you install only a single <code class="language-plaintext highlighter-rouge">package.json</code> file.
If you have multiple, call the <code class="language-plaintext highlighter-rouge">npm_install</code> or <code class="language-plaintext highlighter-rouge">yarn_install</code> multiple times, and give each one a unique name.
This results in multiple repositories, named whatever you chose, rather than “npm”.
The following applies to any repository created by <code class="language-plaintext highlighter-rouge">npm_install</code> , or <code class="language-plaintext highlighter-rouge">yarn_install</code>, just replace <code class="language-plaintext highlighter-rouge">@npm</code> with the name you chose.</p>
<p>Again, use <code class="language-plaintext highlighter-rouge">bazel query @npm//...</code> to learn about all the targets declared in this repository.</p>
<p>Our philosophy is to mirror the installed npm dependencies in a way that’s idiomatic to reference them in Bazel.</p>
<p>Commonly used ones are:</p>
<ul>
<li>Every file that was installed from npm: <code class="language-plaintext highlighter-rouge">@npm//:node_modules</code>. This target can have a very large number of files and slow down your build, however it’s a simple way to skip having to declare more fine-grained inputs to your BUILD targets.</li>
<li>If you had a dependency on the <code class="language-plaintext highlighter-rouge">foo</code> package, you can reference <code class="language-plaintext highlighter-rouge">@npm//foo</code> to get all the files. We mirror the npm dependency graph, so if <code class="language-plaintext highlighter-rouge">foo</code> declares a dependency on another package <code class="language-plaintext highlighter-rouge">dep</code>, Bazel will include that dependency when <code class="language-plaintext highlighter-rouge">foo</code> is used.</li>
<li>If the <code class="language-plaintext highlighter-rouge">foo</code> package has an executable program <code class="language-plaintext highlighter-rouge">bar</code>, then <code class="language-plaintext highlighter-rouge">@npm//foo/bin:bar</code> is a <code class="language-plaintext highlighter-rouge">nodejs_binary</code> that you can call with <code class="language-plaintext highlighter-rouge">bazel run</code> or can pass as the <code class="language-plaintext highlighter-rouge">executable</code> to your own rules.</li>
<li>Sometimes you need a UMD bundle, but a package doesn’t ship one. For example, the <code class="language-plaintext highlighter-rouge">concatjs_devserver</code> rule depends on third-party libraries having a named UMD entry point. The <code class="language-plaintext highlighter-rouge">@npm//foo:foo__umd</code> target will automatically run Browserify to convert the package’s <code class="language-plaintext highlighter-rouge">main</code> entry into UMD.</li>
</ul>
<blockquote>
<p>One convenient (maybe also confusing) way to understand what BUILD files are generated is to look at our integration test at https://github.com/bazelbuild/rules_nodejs/tree/stable/internal/npm_install/test/golden - this directory looks similar to the content of an <code class="language-plaintext highlighter-rouge">@npm</code> repository.</p>
</blockquote>
<h2 id="generated-macros-for-npm-packages-with-bin-entries">Generated macros for npm packages with <code class="language-plaintext highlighter-rouge">bin</code> entries</h2>
<p>Any installed package that has one or more <code class="language-plaintext highlighter-rouge">bin</code> entries in the package.json get convenient macros generated.
These are the Bazel equivalent of the <code class="language-plaintext highlighter-rouge">./node_modules/.bin/*</code> files in your project which the package manager created.</p>
<p>For a package <code class="language-plaintext highlighter-rouge">foo</code> with some bin entries, we will create a <code class="language-plaintext highlighter-rouge">.bzl</code> file where you can load rules, at <code class="language-plaintext highlighter-rouge">@npm//foo:index.bzl</code></p>
<p>If the foo package contains a bin entry <code class="language-plaintext highlighter-rouge">bar</code>, the <code class="language-plaintext highlighter-rouge">index.bzl</code> file will contain <code class="language-plaintext highlighter-rouge">bar</code> and <code class="language-plaintext highlighter-rouge">bar_test</code> macros. You can load these two generated rules in your BUILD file:</p>
<p><code class="language-plaintext highlighter-rouge">load("@npm//foo:index.bzl", "bar", "bar_test")</code></p>
<p>The <code class="language-plaintext highlighter-rouge">bar</code> macro can be called in two ways. If you pass <code class="language-plaintext highlighter-rouge">outs</code> or <code class="language-plaintext highlighter-rouge">output_dir</code>, it produces an <code class="language-plaintext highlighter-rouge">npm_package_bin</code> rule that invokes the tool to transform some inputs to outputs, useful as a dependency of another rule, or with <code class="language-plaintext highlighter-rouge">bazel build</code>. If you don’t pass <code class="language-plaintext highlighter-rouge">outs</code> or <code class="language-plaintext highlighter-rouge">output_dir</code>, then it will produce a <code class="language-plaintext highlighter-rouge">nodejs_binary</code> rule intended for use with <code class="language-plaintext highlighter-rouge">bazel run</code>. (The latter is identical to the <code class="language-plaintext highlighter-rouge">@npm//foo/bin:bar</code> target, just giving you a convenient way to alias it with a different label and pass it arguments).</p>
<p>See examples in rules_nodejs. A typical tool to use with <code class="language-plaintext highlighter-rouge">outs</code> is Babel, while a typical rule with no outputs is <code class="language-plaintext highlighter-rouge">http_server</code>.</p>
<p>The <code class="language-plaintext highlighter-rouge">bar_test</code> macro produces a <code class="language-plaintext highlighter-rouge">nodejs_test</code> that assumes the tool is a test runner, and produces a zero or one exit code, useful as a target with <code class="language-plaintext highlighter-rouge">bazel test</code>. See the examples of <code class="language-plaintext highlighter-rouge">mocha_test</code> in rules_nodejs.</p>
<p>You can also read https://dev.to/bazel/layering-in-bazel-for-web-389h to see an end-to-end example of using the generated <code class="language-plaintext highlighter-rouge">bin</code> macros.</p>
</div>
</div>
<div class="col-md-2 sticky-sidebar">
<div class="right-sidebar">
<ul class="gh-links">
<li>
<i class="fa fa-github"></i>
<a href="https://github.com/bazelbuild/rules_nodejs/issues/new?title=Documentation issue: Generated Repositories&labels=question/docs">Create
issue</a>
</li>
<li>
<i class="fa fa-pencil"></i>
<a class="gh-edit" href="https://github.com/bazelbuild/rules_nodejs/tree/stable/docs/repositories.md">Edit
this page</a>
</li>
</ul>
<ul class="section-nav">
<li class="toc-entry toc-h2"><a href="#nodejs">@nodejs</a></li>
<li class="toc-entry toc-h2"><a href="#npm">@npm</a></li>
<li class="toc-entry toc-h2"><a href="#generated-macros-for-npm-packages-with-bin-entries">Generated macros for npm packages with bin entries</a></li>
</ul>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="container">
<div class="row">
<div class="col-lg-8">
<p class="text-muted">&copy; 2020 The rules_nodejs authors</p>
</div>
</div>
</div>
</footer>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script crossorigin="anonymous"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- Anchor JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/anchor-js/3.2.0/anchor.min.js" type="text/javascript"></script>
<script>
// Automatically add anchors and links to all header elements that don't already have them.
anchors.options = { placement: 'left' };
anchors.add();
</script>
<script>
var shiftWindow = function () {
if (location.hash.length !== 0) {
window.scrollBy(0, -50);
}
};
window.addEventListener("hashchange", shiftWindow);
var highlightCurrentSidebarNav = function () {
var href = location.pathname;
var item = $('#sidebar-nav [href$="' + href + '"]');
if (item) {
var li = item.parent();
li.addClass("active");
if (li.parent() && li.parent().is("ul")) {
do {
var ul = li.parent();
if (ul.hasClass("collapse")) {
ul.collapse("show");
}
li = ul.parent();
} while (li && li.is("li"));
}
}
};
$(document).ready(function () {
// Scroll to anchor of location hash, adjusted for fixed navbar.
window.setTimeout(function () {
shiftWindow();
}, 1);
// Flip the caret when submenu toggles are clicked.
$(".sidebar-submenu").on("show.bs.collapse", function () {
var toggle = $('[href$="#' + $(this).attr('id') + '"]');
if (toggle) {
toggle.addClass("dropup");
}
});
$(".sidebar-submenu").on("hide.bs.collapse", function () {
var toggle = $('[href$="#' + $(this).attr('id') + '"]');
if (toggle) {
toggle.removeClass("dropup");
}
});
// Highlight the current page on the sidebar nav.
highlightCurrentSidebarNav();
});
</script>
</body>
</html>