What is the difference? I realise that they get put into different object properties in bower.json but I can't seem to figure out why you need two separate properties for this, why not just use one.
From the documentation:
-S, --save: Save installed packages into the project’s bower.json dependencies
-D, --save-dev: Save installed packages into the project’s bower.json devDependencies
But there is no explanation of the difference between the two. When should I be saving in dependencies vs devDependencies?
Same case than in npm. Packages that you use in production should go inside dependencies and those that do not inside devDependencies.
The idea is that you are able to install only --production or --development variables, depending on the environment you are deploying your code.
From another answer in this community: What's the difference between dependencies, devDependencies and peerDependencies in npm package.json file?
Related
I want to setup the bazel build system to build a monorepo with multiple JavaScript packages with the new rules_js rule set. The documentation of rules_js says that it supports "nested npm packages in a monorepo" via "workspaces", but I don't understand how to wire everything up so that:
each package in the monorepo can have different external dependencies
packages in the monorepo can also depend on each other
I tried using #npm//$DEPENDENCY in the deps of rules like js_library to refer to my npm dependencies (like with the older rules_nodejs ruleset), but I just get errors about non-existing targets.
TL;DR
Set up a pnpm workspace and use npm_link_all_packages multiple times to set up separate node_modules folders in your bin tree. Then refer to the dependencies in these node_modules folders by :node_modules/$DEPENDENCY in your deps.
How does rules_js create node_modules folders?
rules_js uses the npm_link_all_packages rule to set up node_modules folders based on a pnpm-lock.yaml lockfile. This is similar to the pnpm install command of the pnpm package manager. The difference is that pnpm install creates the node_modules folders in the source tree and npm_link_all_packages creates them in the bin tree.
Since you want that each package can have different external dependencies, they each need to have their own node_modules. pnpm supports a single lock file for multiple packages if you set up a pnpm workspace. The resulting lock file can be used by rules_js to set up a Bazel workspace with multiple packages that each get their own node_modules folder in the bin tree. The npm_link_all_packages rule will automatically set up the correct node_modules folder based on the Bazel package name and the pnpm-lock.yaml.
So you have to set up a pnpm workspace and use npm_link_all_packages multiple times to set up separate node_modules folders in your bin tree.
How exactly do I set this up?
To achieve this, you can put the following pieces in your workspace root:
pnpm-workspace.yaml to configure the list of pnpm workspace packages
pnpm-lock.yaml to record how all all direct and indirect npm dependencies are resolved
WORKSPACE.bazel to setup rules_js
package.json to avoid confusing pnpm, and in case you want global scripts or settings for your IDE or similar
BUILD.bazel to create the virtual store with npm_link_all_packages
And in each pnpm workspace package $PACKAGE you put:
$PACKAGE/package.json to configure the direct npm dependencies of $PACKAGE
$PACKAGE/BUILD.bazel to create the node_modules folder in the bin tree with npm_link_all_packages, and for your js_library or similar
So every pnpm workspace package is also a bazel package (since it has a BUILD.bazel).
How can I refer to my npm dependencies in deps?
In the deps of js_library and similar, you can point to the dependencies in the node_modules folders generated by npm_link_all_packages. Typically, the js_library is in the same Bazel package as the npm_link_all_package, so you can just use :node_modules/$DEPENDENCY. If the js_library is in a sub-package of $PACKAGE, you can use //$PACKAGE:node_modules/$DEPENDENCY instead. Then in your JavaScript files, you can import from "$DEPENDENCY" or require("$DEPENDENCY"). This will work out at runtime because the node_modules folder will be at an appropriate place in the runfiles for node to find it.
How can the packages in my workspace refer to each other?
If you want one of your packages $PACKAGE to depend on another one of your packages $OTHER, you put a "$OTHER": "workspace:*" into the $PACKAGE/package.json as usual with pnpm. You also have to make sure that the default target of $OTHER (for example, //some/path/to/other:other) is an npm_package rule. Then you can use :node_modules/$OTHER or //$PACKAGE:node_modules/$OTHER in the deps of a js_library or similar to refer to $OTHER just like you would refer to an npm dependency.
How can I create the pnpm-lock.yaml?
Note that this is a working pnpm setup with some additional BUILD.bazel files, so you can:
use pnpm install --lockfile-only to create the pnpm-lock.yaml
use pnpm install to create the pnpm-lock.yaml and also create node_modules folders in the source tree. These folders are not needed for rules_js but can be helpful for your IDE.
According to the documentation:
pipenv install foo==0.x
will install foo with the specified version and update both Pipfile and Pipfile.lock.
If the foo has been written into both files, then what is the need for pipenv lock command?
The document said it:
Regenarate Pipfile.lock and updates the dependencies inside it.
Under what situation do we need to call the pipenv lock command?
Thanks if you could clarify my confusion.
As I understand, it can be used to update all your dependencies before entering production.
pipenv lock is used to create a Pipfile.lock, which declares all dependencies (and sub-dependencies) of your project, their latest available versions, and the current hashes for the downloaded files. This ensures repeatable, and most importantly deterministic, builds.
You can use pipenv lock to compile your dependencies on your development environment and deploy the compiled Pipfile.lock to all of your production environments for reproducible builds.
I've been trying to get a bazel monorepo with typescript to work. I have a couple of requirements in mind.
I should be able to import local packages using #myworkspace/ instead of ../../../ and so on, without needing Bazel. This is mostly so I get autocomplete while I'm writing.
The #myworkspace/ package should be the same during development and build time but only Bazel-managed dependencies should be resolved on imports when running sandboxed. Just so I know if I've messed up the name of the package in the js_library rule.
There should only be one lock file for the whole project. All dependencies should be located at root/node_modules.
It should be possible to individually deploy node packages i.e. #myworkspace/myCloudFunction.
It should be possible to include local dependencies in packages that will deployed.
I'm new to Bazel and it seems like it requires some mentality changes when coming from the NPM ecosystem. After googling, I've managed to find something that works for points 1 and 2 (But I might be wrong). I've published the playground repo at https://github.com/vitorelourenco/bazelmono-ts (pretty much a copy from https://github.com/lokshunhung/bazel-ts-monorepo with some ideas I took from https://github.com/angular/angular)
My questions about points 3 and 4:
Say I want the lib Lodash available on package #myworkspace/cloudFunction that will be deployed to Google Cloud Functions. If I install Lodash in the #myworkspace/cloudFunction folder, then Lodash will be added to package.json but I'll have a second node_modules folder and a second yarn.lock file, I don't want that. But if I install it in root/, then Lodash will not be added to the dependencies listed on package.json located at #myworkspace/cloudFunction, and when I deploy it, it won't install. Is there a smart way to handle this issue?
Point 5 is very similar. Ideally, the final Bazel output would have the local dependencies bundled in and ready to use but I can't seem to figure out a way to do it yet. I've tried adding a pkg_npm rule to //packages/app in the playgroup repo but couldn't get it to include //packages/common in it.
I am trying to clean my application of unused bower dependencies.
Is there a possibility or a tool to find unused bower dependencies in an application?
Bower downloads the packages and store them in the bower downloads directory. It is up to you to refer to these scripts in your application. You can search your application for the specific directory to find out if a script from that directory is ever referred to.
If you are worried about the scripts you are loading and not using any functions from them, there are tools available depending on the technology/framework you use.
If you are worried about the injected dependencies which are hardly ever used in the modules, then you should search for tools specified by the technology/framework.
I'm trying to get Bower to install this javascript:
https://github.com/markmalek/Fixed-Header-Table
I use: bower install git#github.com:markmalek/Fixed-Header-Table.git --save
It installs the package into bower-components, and even adds it to my project's bower.json, but it doesn't add the to my html. I'm guessing it's because that particular git repo doesn't contain a bower.json telling my project which js file is the main one. So how do I install this package?
Thanks!
This answer takes your assumption that your HTML is picking up scripts loaded via Bower using the bower.json file as correct.
There are two options. The quickest is to fork the repo yourself, and in the main directory use the command bower init to create your own bower.json file in your forked version of the repo. Then, change the github url to the repo to your forked version rather than the original you have above.
The second option is to submit a pull request to the package owner adding a bower.json file so that you can continue to pull directly from his repo.
There are probably more options like manually loading the script outside of pulling from a bower.json file but the two above seem simplest.