Bower execution can be configured in two ways:
- With bower.json for project configuration (like
package.json
orGemfile
) - With configuration variables for execution in general (like command-line flags)
bower.json and .bowerrc specification
Bower execution can be configured in two ways:
package.json
or Gemfile
)I would like to have the possibility to add custom fields in the bower.json. Maybe there could be a 'custom' key within the specification?
for example: styles
, scripts
, fonts
, images
. without these, it makes life difficult for tools to have any useful information that defines the component contents
Sparked by: #8 (comment)
This spec is for bower though and for bower index.js is the default entry point of a package if no main is supplied, a build tool creator would still find some use in having that specified in the spec I think.
I see no benefit in supporting index.js as a fallback for not specifying main
. The less indirection the better.
We should strive to be explicit and learn from history:
https://groups.google.com/d/msg/nodejs/kxw_rSqu3AY/iDxNWFplRhIJ
Node programs run on filesystems. Every step of indirection away from
"the file on the filesystem" to "the string in the require()
statement" is a cost. Some of those costs provide some benefit, like
how require("foo") can be either locally in node_modules, or up a
level, so that modules can share dependencies (but don't have to, if
they would conflict). Other costs, like how require("foo/bar") can be
either foo/bar, or foo/bar.js, or foo/bar/index.js, are simply
historical mistakes that seemed like a good idea at the time, but
provide no value, and are now too costly to remove.
Now that GitHub restored their downloads feature (somewhat). It would have been very useful if in addition to:
"repository": {
"type": "git",
"url": "git://github.com/foo/bar.git"
}
bower.json could also support the following format:
"repository": {
"type": "zip",
"url": "https://github.com/foo/bar/releases/download/tag/bar_tag.zip"
}
Some repos (like ours for example) tend to not include binaries. We prefer to put them separately into a downloadable zip.
I'd like to get some opinions about how to handle developing multiple components in the same repository that all depend on each other. I'd like to use bower.json
to manage both my internal and external components so I can keep all dependency ordering information in the same place (for both build order and script order in my html).
For my usage:
Local paths are already supported in the spec, but their handling is less than ideal.
Dependencies are specified with a simple hash of package name to a semver compatible identifier or URL.
- Local paths may be used as values for local development, but they will be disallowed when registering.
The current behavior of bower is that all components, both internal and external, are copied into the bower_components
directory. If you are actively developing on both components, you need to keep re-running bower install
in order to get the latest code into the dependent components.
Alternative approaches are to:
bower link
bower_components/comp-1
-> local/path/to/comp-1
and commit them to the repo
One way to support this would be to add localDependencies
and localDevDependencies
properties to bower.json
.
internal-example
{
"name": "internal-example",
"dependencies": {
"angular-ui-router": "~0.2.13"
},
"devDependencies": {
"mocha": "~2.2.1",
"chai": "~2.2.0"
},
"localDependencies": {
"example-lib": "../example-lib"
},
"localDevDependencies": {
"example-core": "../example-core"
}
}
example-lib
{
"name": "example-lib",
"dependencies": {
"moment": "~2.10.3"
},
"devDependencies": {
"mocha": "~2.2.1",
"chai": "~2.2.0"
},
"localDependencies": {
"example-core": "../example-core"
}
}
example-core
{
"name": "example-core",
"dependencies": {
"lodash": "~3.6.0"
},
"devDependencies": {
"chai": "~2.2.0",
"mocha": "~2.2.1",
"angular-mocks": "~1.3.15"
}
}
When running bower install
in internal-example
(assume bower install
has already been run for the other components), the following would be the output into internal-example/bower_components
:
localDependencies
are included hereNone of the localDependencies
or localDevDependencies
(or their dependencies
like moment) were copied into bower_components
. However, the version numbers were checked by bower to make sure there were no conflicts.
If example-lib
and example-core
have dependencies on incompatible versions of jquery
, bower should probably just report an error and fail the installation - since these are internal components the author should fix incompatibilities in the dependencies rather than in the parent.
Alternatively, bower should continue to operate as usual by copying in all dependencies
except localDependencies
. My rationale is that if you update your dependencies in a local dependency (e.g. moment from v1.1 to v2.0) you need to make sure to run bower install
everywhere that local dependency is referenced. The behavior of not copying may introduce too much weirdness or unexpected behavior.
Tools like wiredep would need to be updated to follow the paths of localDependencies
and respect any .bowerrc
files found there in order to find the correct bower_components
folder.
The output from wiredep for the above project might look like:
console.log(JSON.stringify(require('wiredep')({
dependencies: true,
devDependencies: false,
localDependencies: true,
localDevDependencies: true
}), null, 2));
{
"packages": {
"angular": {
"main": [
"/Users/nmalaguti/git/my-example/internal-example/bower_components/angular/angular.js"
],
"type": [
".js"
],
"name": "angular",
"dependencies": {}
},
"angular-ui-router": {
"main": [
"/Users/nmalaguti/git/my-example/internal-example/bower_components/angular-ui-router/release/angular-ui-router.js"
],
"type": [
".js"
],
"name": "angular-ui-router",
"dependencies": {
"angular": ">= 1.0.8"
}
},
"moment": {
"main": [
"/Users/nmalaguti/git/my-example/example-lib/bower_components/moment/moment.js"
],
"type": [
".js"
],
"name": "moment",
"dependencies": {}
},
"lodash": {
"main": [
"/Users/nmalaguti/git/my-example/example-core/bower_components/lodash/lodash.js"
],
"type": [
".js"
],
"name": "lodash",
"dependencies": {}
},
"exp-core": {
"main": [
"/Users/nmalaguti/git/my-example/example-core/build/src/foo.js"
],
"type": [
".js"
],
"name": "example-core",
"dependencies": {
"lodash": "~3.6.0"
}
},
"example-lib": {
"main": [
"/Users/nmalaguti/git/my-example/example-lib/build/src/styles/inner/deer.css",
"/Users/nmalaguti/git/my-example/example-lib/build/src/styles/rabbit.css",
"/Users/nmalaguti/git/my-example/example-lib/build/src/image.css",
"/Users/nmalaguti/git/my-example/example-lib/build/src/bar.js"
],
"type": [
".css",
".js"
],
"name": "example-lib",
"dependencies": {
"moment": "~2.10.3",
"example-core": "../example-core"
}
}
},
"js": [
"/Users/nmalaguti/git/my-example/internal-example/bower_components/angular/angular.js",
"/Users/nmalaguti/git/my-example/internal-example/bower_components/angular-ui-router/release/angular-ui-router.js",
"/Users/nmalaguti/git/my-example/example-lib/bower_components/moment/moment.js",
"/Users/nmalaguti/git/my-example/example-core/bower_components/lodash/lodash.js",
"/Users/nmalaguti/git/my-example/example-core/build/src/foo.js",
"/Users/nmalaguti/git/my-example/example-lib/build/src/bar.js"
],
"css": [
"/Users/nmalaguti/git/my-example/example-lib/build/src/styles/inner/deer.css",
"/Users/nmalaguti/git/my-example/example-lib/build/src/styles/rabbit.css",
"/Users/nmalaguti/git/my-example/example-lib/build/src/image.css"
]
}
I'm not sure if this is the right way to use bower.json
or if this is a goal of bower.json
. I'm interested in this because it simplifies the dependency ordering story for the build order of components and for including them in html.
We have a Jenkins server running a multibranch job. When a release is finished in the repo (gitflow), develop and master branches are updated. The multibranch job is triggered, starting building develop and master branches at same time.
The build job execute grunt that call "bower install". One branch runs ok, the other stops with an error.
Running "shell:bowerInstall" (shell) task
C:\Users\jenkinssvc\AppData\Roaming\npm\node_modules\bower\lib\node_modules\configstore\index.js:70
throw err;
^
Error: EPERM: operation not permitted, rename 'C:\Users\jenkinssvc\.config\configstore\bower-github.json.716917364' -> 'C:\Users\jenkinssvc\.config\configstore\bower-github.json'
at Object.fs.renameSync (fs.js:741:18)
at Function.writeFileSync [as sync] (C:\Users\jenkinssvc\AppData\Roaming\npm\node_modules\bower\lib\node_modules\write-file-atomic\index.js:81:8)
at Configstore.set (C:\Users\jenkinssvc\AppData\Roaming\npm\node_modules\bower\lib\node_modules\configstore\index.js:63:21)
at Configstore (C:\Users\jenkinssvc\AppData\Roaming\npm\node_modules\bower\lib\node_modules\configstore\index.js:28:11)
at readCachedConfig (C:\Users\jenkinssvc\AppData\Roaming\npm\node_modules\bower\lib\config.js:19:23)
at defaultConfig (C:\Users\jenkinssvc\AppData\Roaming\npm\node_modules\bower\lib\config.js:11:12)
at Object.<anonymous> (C:\Users\jenkinssvc\AppData\Roaming\npm\node_modules\bower\lib\index.js:16:32)
at Module._compile (module.js:571:32)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:488:32)
Warning: Command failed: bower install
OS: Windows Server 2016
Jenkins version: 2.59
Nodejs: v7.2.1
Bower: 1.8.0
I know the problem is not with bower directly. The problem is in configstore (2.0.0) which uses write-file-atomic
Since resolving main
in #43, we've thrown a wrench in the gears for build tools, most prevelantly Wiredep. Wiredep needs a list of all the files to be included when you install the package. Previously, main
was being widely used for this purpose. Now main
should no longer lists all the files (The entry-point files necessary to use your package. One per filetype). We need another field.
These two proposals are my first shot at it. Your thoughts appreciated 🍉
files
flat list
files
is an array of all the files required to use the package. Filepaths may include globs.
files
differs frommain
in thatmain
only lists single files per filetype, whereasfiles
should include every file.We recommend listing source files in
files
, rather than compiled distribution files.
"files": [
"js/motion.js",
"js/run.js",
"js/walk.js",
"sass/motion.scss",
"sass/run.scss",
"sass/walk.scss",
"img/motion.png",
"img/walk.png",
"img/run.png",
"fonts/icons.woff2",
"fonts/icons.woff"
]
Most likely you would list globs for multiple files of the same type.
"files": [
"js/*.js",
"sass/*.scss",
"img/*.*",
"fonts/*.*"
]
Pros: Simple specification, easier for developers to adopt. Don't have to worry on Bower spec side about asset-type specification. Cons: Aside from file extension, it's not clear what files do what. For example, a package make require icon.svg
— is this file a font or should be it used as an image?
We leave it up to build tools on how they make use of the array. Some might only be concerned about .js
and .css
files. For globs, they'd have to expand the glob and do the logic on their side.
Taking from #21
files
is an object listing all the files required to use the package.files
are listed as arrays for each type of asset.
scripts
: Script files like JavaScript.js
or CoffeeScript.coffee
styles
: Style files like CSS.css
, Sass.scss
, or LESS.less
images
: ...fonts
: ...data
templates
- (Others — we'd have to determine this spec)
Filepaths may include globs. yada yada yada ....
"files": {
"scripts": [
"js/motion.js",
"js/run.js",
"js/walk.js",
],
"styles": [
"sass/motion.scss",
"sass/run.scss",
"sass/walk.scss",
],
"images": [
"img/motion.png",
"img/walk.png",
"img/run.png",
],
"fonts": [
"fonts/icons.woff2",
"fonts/icons.woff"
]
}
Pro: Clear about what files do what. Cons: More complex. We'd have to figure out the list of types. Might be confusing files that do not have an explicit type, like if there's a video file and we don't have a videos
field.
Fun fact: recommended way back in 2013 bower/bower#935 (comment)
files
would live along side main
, not overwrite it. I'm not sure if it should be required or part of the bower init
flow at this point.
Currently, I prefer Proposal 1. Easier for authors and for Bower spec.
bower hooks are configured in .bowerrc, and should be present in the spec.
The spec says "Note: README (all variants of case, .md, .text) and bower.json will never be ignored.", but it seems that bower.json
can be ignored. Should this be a .bower.json
instead?
See bower/bower#1174
https://github.com/bower/bower.json-spec#main says main
shouldn't contain minified files but y'all also say it should be a single entrypoint, per #20.
So, should we put a single concatenated (but not minified) JS file in main
, or should we put all the individual basically-independent JS files in main
?
Context: twbs/bootstrap#14534
After coming across quite a few bower packages without main
files specified, I was thinking it would be quite useful to have an overrides
property defined in the bower.json spec. overrides
would allow package consumers to specify main files of their choosing, overriding the main
s specified by the packages they're using.
This is already being used in a few build tools / plugins like main-bower-files and wiredep, but it would be better if it were actually part of the official spec.
Some package authors specify multiple redundant main
files (ie. one minified, one un-minified), and if you're using any kind of build automation that involves bower, having the ability to choose the one that best fits your project in your bower config itself would be a godsend. Everything else I've tried / seen just feels hacky.
This is even more important for bower packages that don't define a main
file at all - at that point you have to manually specify which file you want in your code.
My thought is that it would work something like it does here: https://github.com/ck86/main-bower-files#overrides-options
{
"name": "your-package-name",
"dependencies": {
"<bower-package>": "*"
},
"overrides": {
"<bower-package>": {
"main": "some-file.js"
}
}
}
Or, NODE_ENV
specific overrides:
{
"overrides": {
"<bower-package>": {
"main": {
"development": "file.js",
"production": "file.min.js",
}
}
}
}
"main"
here would also be able to accept a glob.
What do you think?
Although the bower spec supports authors
, it does not officially support contributors
which I think is an important distinction.
There are a plethora of ways repo/project owners use to give credit to contributors
contributors
arrayI'd love to see spec writers encourage a common way to give credit where credit is due. I also do not feel that authors
should serve to address both groups. Unless of cause if the authors
key were to be renamed to contributors
.
FWIW this is a distinction the bower website itself appears to make.
With the current implementation, passing username and password for a non GIT dependency (e.g. artifacts from nexus) is only possible by adding basic authentication to the dependency url itself. Which then would be eventually committed to a repository. Is there any hidden feature which would allow the url resolver to add a user specific authentication? A shorthand resolver using global username and password is also only available for git.
Am I doing it wrong or is there a chance of including a basic authentication into bower for zips and tarballs?
Thanks,
Peer
@unscriptable just mentioned this (#7 (comment))
Related to this I believe bower/bower#934
moduleType
would allow the developer to specify if their package is AMD, global, CJS, etc.
It’s difficult to get a straight answer on what platforms a given app can support. Consider the following bower.json:
{
"name": "example",
"version": "0.0.1",
"dependencies": {
"jquery": "1.9",
"codemirror": "~4.2.0",
"seedrandom": "~2.3.10"
}
}
To know what platforms this package can support, I’ll need to read a table at http://jquery.com/browser-support/, look towards the bottom of http://codemirror.net/2/, and read between the lines of https://github.com/davidbau/seedrandom/blob/master/README.md.
I propose an optional “supportedPlatforms” property. Packages could use this as the set of platforms for which they are willing to accept bugs. For example, jQuery 1.9’s could look like this:
“supportedPlatforms”: [
“Chrome 38+”,
“Firefox 32+”,
“Internet Explorer 6+”,
…
]
This would allow tools to calculate the intersection of the dependency set. For instance, the example above cannot support mobile well (because CodeMirror doesn’t yet).
I don’t have a good proposal for the exact values of the array.
User-Agent string seems too hard to read.
Arbitrary text doesn’t provide enough standardization to be useful (though it is still much more organized than the current state of the world).
As I understand it, semver isn't used by browsers and doesn't define ranges in a standard way.
Some type of object could be used:
“supportedPlatforms”: [
{browser: “chrome”, versions: “38-39”}
…
]
This proposal takes inspiration from npm’s “engines”, “engineStrict”, “os”, and “cpu” properties. These use an extension of semver.
This may be too simple. “Supported” is not necessarily a binary state: for instance, a package might support only some features in IE. However, as I see it, “supportedPlatforms” isn’t a replacement for reading documentation, it’s only meant to clarify which platforms are completely out-of-scope.
Does this seem useful?
I think it's important to document both in one place. What do you think @desandro ?
For example in bower.json
for devDependency or dependency one could have a following entry:
{
...
"xyzlib": "git+https://example.com/path/to/xyzlib.git#<SHA-1>"
....
}
upon bower update
or bower install
, bower.json
pulls the xyzlib specified by as expected.
If the xyzlib
has additional commits, to refer to the latest commit, the bower.json pointing to xyzlib
requires to be updated everytime.
Instead if a tag like #latest
is available (as shown below), then irrespective of number of commits xyzlib moves ahead, the #latest
will always refer to the most recent commit.
{
...
"xyzlib": "git+https://example.com/path/to/xyzlib.git#latest"
....
}
main
is currently kind of useless. i'd suggest using it as the main entry point into a component's JS.
The spec itself ought to be versioned, and a field should be added to bower.json
indicating at least the major (and perhaps also the minor) version of the bower.json
spec that it claims to conform to.
This would allow for an easier migration/upgrade path when backward-incompatible changes need to be made to the spec. If a bower.json
lacks a bower.json
-spec-version-number, it should default to version "0" of the spec, for backward compatibility with old packages. Version 0 should be tagged retroactively as some commit circa the current version of the spec as of when this issue was filed. A bower.json
using an outdated major version of the spec should at least emit a warning, and at most fail with an error if it's so old that supporting it is too burdensome for Bower or is bad public policy for Bower.
i find it quite annoying to duplicate information from package.json, how about for projects which use package.json add just bower specific configuration in nested object with key "bower" ?
They're listed on https://bower.io/docs/config/ but not doc'd in this spec.
In npm, you can have both main and esnext:main property in package.json. This is handy when your module have different build output for es5 and es6. Does bower.json plan to support esnext:main or similar?
In the config spec, it states:
Example of valid environment variables:
bower_https_proxy is evaluated as https-proxy
bower_storage__cache is evaluated as storage.cache
But in the description of storage
, the only valid keys are packages
, registry
, and link
with no mention of cache
. This confusion example also appears on the docs for config.
Am I right in thinking these examples should be updated to match the valid keys? Am I also right in thinking that one needs to override all three if ~/.bower is not available?
I think that it could be interesting to add a suggest
attribute to invite users to install other packages.
For instance, I'm developing an AngularJS module that could rely on different other modules if they're in the $injector
. Suggesting user to install other modules in addition of the documentation could be great !
There're some inconsistencies in the spec and bower's (1.5) behavior:
version
in package.json is "Deprecated. Use git or svn tags instead.". Ok, how will bower determine version in case of pluggable resolvers? For an example when a resolver returns tar.gz archive. There're no "tags" in that case.main
and ignore
attributes:bower xxx#0.22 invalid-meta xxx is missing "main" entry in bower.json
bower xxx#0.22 invalid-meta xxx is missing "ignore" entry in bower.json
But in the spec these attributes are marked as "Recommended" not "required".
Basically, an alternative and more extensible format to the "moduleType" property proposed in #10.
{ "name": "jquery",
"main": "jquery.js",
"amd": {
"main": "jquery-amd.js"
},
"es6-module": {
"main": "jquery-es6.js"
},
"imports": {
"main": ["jquery.html", "jquery.js", "jquery.css"]
}
}
Instead of simply just declaring a moduleType, packages can declare a nested set of overrides. If the build tool is intended for AMD, it will prefer an amd.main
value, otherwise fallback to the top level main.
Right now main
is the only interesting property to build tools. Others could be introduced in the future and this format would support them.
I feel like the spec should list out a set of suggested "extension types" based on the use cases we've already seen.
amd
cjs
or commonjs
(probably the latter)es6-modules
imports
HTML import / web component style/cc @robdodson @rpflorence @joliss @briandipalma @wibblymat @paulirish @benschwarz
I've been reading the showdown and other commentary as to what 'main' means, and in addition to the actual nature of main (single entry, array, etc.) is it possible there is an additional "dimension" to consider?
Ember specifies ember.js
as their main. But this is the debug version: It's slower, has asserts, logging statements, etc. but they also have ember.prod.js
.
(neither are minified - the production one is simply faster)
Should Bower attempt to specify how components might express these configurations? So, in the Ember case, they might have
main: 'ember.prod.js',
debug: 'ember.js'
If Bower did not want to get in to treating debug
as a first-class concept, then it could require namespacing them - e.g. alternatives: ...
I use Brunch, and it has a configuration override mechanism. I could foresee my development configuration specifying bower: { configuration: 'debug' }
or something to that effect, and the build process would use a simple "if the configuration exists, use that, otherwise fallback to main" resolution policy as it processes each component.
This means that during development I can get the benefits of debug related things, but when I brunch build --production
the configuration system would omit the main override (and just use default for everything).
What I'm describing would involve changes on the way Brunch works, of course, but they would only be possible if Bower was tolerant of - or even encouraged -alternative configurations.
The alternative is that I have to mess around with bower overrides, which doesn't really feel appropriate for "build release" vs. "build debug", and I've seen some people wanting to have a shadow bower.json
(e.g. bower-debug.json
) which doesn't feel right either.
Since bower/bower#694 has been fixed, bower warns the user when installing modules whose bower.json does not include main
and ignore
.
But the spec still specifies them as optional. I think these attributes should be marked as required
in the spec.
Just making absolutely sure. See twbs/bootstrap#12805
(And yes, I know it should really be only 1 file (bower/bower#946), but it's been 3 months and files
still has yet to been added to your spec.)
I know that main
shouldn't be a directory, but can it be a glob to files?
Say instead of
"main": [
"dist/template1.html",
"dist/template2.html",
"dist/app.js"
]
a shorter
"main": [
"dist/*.html",
"dist/app.js"
]
?
The question would be what $ bower list --path
would return? The glob or the expanded paths? (Maybe it could be configured like $ bower list --path --expand-glob
.)
I would like to see the Bower spec be more specific about what should go in the author field.
I agree in the demarcation outlined in #15, but if you aren't willing to add a separate attribute, which frankly I do not think you should either, it would be nice to see a description that states that authors are considered the on-going maintainers and primary contacts for the repo.
This has caused me grief after someone PR'd four words and added themselves to author list in bower and then got offended when another maintainer suggested it wasn't an appropriate thing to do.
Please. No open source project needs the grief of irrational conflicts over egos.
If you can either spell out a more specific definition or even better save people some grief and get rid of authors and change it to maintainers I would be grateful.
Thank you for your time.
Maybe the document could be put in json schema so it could be used for a bower validate
command?
What is the default value of private
field?
What happens if I omit it?
If you aren't familiar, github has a great team mention feature. Under the bower organization, I'd like to organize a @bower/build-tools-maintainers team the consists of maintainers interested in implementing spec changes like main
, paths
, etc. Anytime a PR is opened to change one of these properties that could affect tooling, we should be sure to @mention that team.
Also, it be nice to maintain a list somewhere of tool repositories implementing bower spec features. Just for use case reference.
Who has admin permissions to the bower org that could create this team?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.