24

Is there a way to make bower run a package grunt after it was cloned from GitHub?

I'm trying to use Bower but one of the packages I'm using is the Bootstrap extension, x-editable. The problem is that while other packages push a fully built version to github so when installed by Bower you have a built version x-editable expect you to run a grunt file to build the package.

That is a common practice in other package managers like npm but I could find how to make Bower build it on install. Which means I need another mechanism to complete the installation of the package.

Guy Korland
  • 9,139
  • 14
  • 59
  • 106

3 Answers3

23

Building on install is an anti-pattern and is strongly recommended against in Node. Like Node, Bower packages should be pre-built. This is because the end-user shouldn't have to care what preprocessor or build-system a package requires.

Your best options are to either convince the author to pre-build, fork and do it yourself, or build manually after you've installed the component.

The Bower team is planning to add the ability to publish packages to a server similar to how it works in npm. This will make it much better for packages needing a build-step.

Sindre Sorhus
  • 62,972
  • 39
  • 168
  • 232
  • 5
    Most of the "heavy" packages in npm I'm using have some build phase after install. Committing a pre-built cross platform (usually native) code to seems like even worse option. Never the less, even if as best practice Bower doesn't encourage it, I think the option should be available for special cases. – Guy Korland Jun 18 '13 at 20:55
  • 2
    Native extensions are the exception in Node as they don't have the infrastructure to pre-compile, but it's being considered. An option is already available. Bower has an API. So you are free to hack your own solution, but for the common user this is not a good choice and will never be recommended or supported in Bower. – Sindre Sorhus Jun 18 '13 at 21:39
  • 1
    @Sinder My question is whether I can force a build phase on a package that wasn't published by me? e.g. x-editable which is on Bower repository but in order to use it you need to run its grunt file. – Guy Korland Jun 19 '13 at 22:12
  • As said in the answer you can build it manually after installing, by `cd`ing into the component folder and running `grunt`. Bower doesn't have any pre/post-install hooks. – Sindre Sorhus Jun 19 '13 at 23:06
  • 21
    I don't really understand how it can be said to be an "anti-pattern". AFAICT Bower works over git, and it's usually considered bad practice to keep compiled files in your git repo. – starwed Jul 16 '13 at 20:42
  • 1
    @starwed see my updated answer. You're generally right when it comes to reusable modules, but everything deployable should be compiled. The problem as you point out is that Bower works over git, but user convenience trumps dev convenience. – Sindre Sorhus Jul 16 '13 at 21:50
  • @SindreSorhus I disagree. 1) Building quality packages is impossible without having adequate source control; putting compiled code in repo compromises it, so in the end it negatively affects users. 2) Many users are developers too and they contribute to these packages, so its their convenience too. Maybe, the possible automatic option is to publish to bower from some fork/branch that is being pushed to from the build process. I think that bower should either provide storage for packages like npm does, or allow building packages on install as it did previously. – esp Feb 27 '16 at 13:31
4

There are 3 hooks in bower, postinstall may solve your problem if for whatever reason you can not pre-built like @Sindre Sorhus points out.

In .bowerrc do:

{
    "scripts": {
        "preinstall": "<your command here>",
        "postinstall": "<your command here>",
        "preuninstall": "<your command here>"
    }
}

source https://github.com/bower/bower/blob/master/HOOKS.md

schurpf
  • 609
  • 7
  • 7
-2

You could use composer for handling post install:

bower.json:

{
    "dependencies": {
        "bootstrap": "*"
    }
}

composer.json:

{
    "scripts" : {
        "post-install-cmd" : [
            "bower install --no-color",
            "lessc bower_components/bootstrap/less/bootstrap.less public/script/bootstrap.css"
        ]
    }
}

Then I run composer install:

Loading composer repositories with package information
Installing dependencies (including require-dev)
Nothing to install or update
Generating autoload files
bower warn Package bootstrap is still using the deprecated "component.json" file
bower cloning git://github.com/twitter/bootstrap.git
bower cached git://github.com/twitter/bootstrap.git
bower fetching bootstrap
bower checking out bootstrap#v2.3.2
bower warn Package jquery is still using the deprecated "component.json" file
bower copying C:\Users\renadm\AppData\Roaming\bower\cache\bootstrap\9d49e0aedf207bebd028e26cc86a9e58
bower cloning git://github.com/components/jquery.git
bower cached git://github.com/components/jquery.git
bower fetching jquery
bower checking out jquery#1.8.3
bower copying C:\Users\renadm\AppData\Roaming\bower\cache\jquery\29cb4373d29144ca260ac7c3997f4381
bower installing bootstrap#2.3.2
bower installing jquery#1.8.3

After Bower finishes installing, the LESS compiler processes the .less files and puts a nice bootstrap.css in my public folder. something similar could be done for JavaScript files with Closure Compiler.

Renaat De Muynck
  • 3,267
  • 1
  • 22
  • 18