Wiredep, and bower_components

I’m trying to automatically inject my bower components into www/index.html. I got the index.html file populated but I’m getting 404’s for all of the files. When I run ionic serve - is it creating a webserver from the www folder (thus preventing access to the bower_components folder at the root? Do I have to copy all of the bower components into the www folder? I remember the initial setup having a www/lib folder with the libs copied and pasted in there. This isn’t easily maintainable though so I’m trying to use wiredep instead.

Just to recap, here’s my structure:

– root
---- app (src files)
---- bower_components
---- www (target/build directory)
------- index.html

Any thoughts?

Is the path correct in the gulp config? Could you show your gulp code and index file (where it posted wrong sources)?

Trying to reinvent the wheel? Just check how generator-m is built…

That has an entirely different folder structure.

<!-- bower:js-->    
<script src="../bower_components/ionic/js/ionic.bundle.js"></script>
...
<!-- endbower-->

Here’s the generated index.html. So theoretically the path is correct - it’s trying to reach outside the www folder and into the bower_components folder - but I’m assuming it can’t because it’s a web server.

You want to see the gulp config - what is this? Here’s my gulp code for wiredep:

return gulp.src(paths.app + 'index.jade')
    .pipe(jade({
        pretty: true
    }))
    .pipe(wiredep({
        exclude: [
            'bower_components/angular/angular.js',
            'angular-animate.js',
            'angular-sanitize.js',
            'angular-router.js'
        ]
    }))
    .pipe(gulp.dest(paths.dist))

So you’ll probably need to add something like this to your config:

bower: {
	json: require('./bower.json'),
	directory: './bower_components/',
	ignorePath: '../bower_components/',
        fileTypes: {
            html: {
        	replace: {
        		js: '<script src="/lib/{{filePath}}"></script>',
        		css: '<link rel="stylesheet" href="/lib/{{filePath}}" />'
        	}
        }
       }
},

Then create these options to pass to wiredep:

var options = {
	bowerJson: config.bower.json,
	directory: config.bower.directory,
	ignorePath: config.bower.ignorePath,
	fileTypes: config.bower.fileTypes
};

Then .pipe(wiredep(options)). Hopefully that works for you. You may have to tweak some paths around.

Thanks @swade for your help so far. I really appreciate it. Got some questions:

  1. What is my “config”? ionic.project in the root?

  2. Are you suggesting that I do have to manually copy over the bower components into www/lib so that index.html can pick them up and not just reference them from outside of the www folder?

I have the config as a gulp.config.js file and require it in my gulp file. You could just as easily put it in your gulpfile. You don’t have to manually do it, wiredep has options to ignore path names and replace them. So that file type is actually used when wiredep injects it into your html. So essentially with this '<script src="/lib/{{filePath}}"></script>', it should ignore ../bower_compenents in your filepath name then you can add your own filepath prefix, in this case /lib/.

I get that it can modify the name but the actual files themselves would have to be copied over from bower_components into www/lib correct?

Oh, I get what you’re asking. Mine automatically add to the www/lib folder when I do a bower install, but I don’t think it really matters if they are in the www filepath, but cordova might have something to say about that. But you can choose your directory in the .bowerrc file.

{
  "directory": "www/lib"
}

The problem here is that I’m trying to treat the www as a target folder where only compiled and built files go. I’ve extracted my application out of the www folder into an app folder at the root so I can more easily manage the src files and built files. The problem is getting the bower_components into the target (www) directory.

In the www folder you should just put your build, with the assets compiled, concatenated and obfuscated in a vendor.js/vendor.css (the bower stuff) along with your app.js/app.css (your app files).

Check this structure. If you follow best practices you’ll end up with a very similar structure to that one. It’s based on Swiip’s gulp-angular. Give the generator-m a go, check the build tasks, and study how it’s built.

0.02

Hi @dwilt4rville I wrote a blog post about how to correctly setup wiredep with Ionic here: https://jasonbrown.io/using-wiredep-and-gulp-to-manage-your-ionic-app-dependencies/

Not sure why you are re-structuring your project, understand you are wishing to use www as your compiled directory, however when you build your ionic application it gets copied into platforms/ios/www (for example) you’ll have issues with the default ionic config due to restructuring your project.

You should treat this directory as your compiled/distributed directory, app_root/www is your working development directory.

1 Like

@Loyx Yep, I saw that generator before but that generator doesn’t follow the best practices that you linked to (or I’m doing in my app). They’re doing the typical directives.js and services.js - not organizing by module/component. I did figure out how though to get the bower files injecting and solved that issue and have effectively turned the www folder into a build directory. Exactly what I wanted.

@delta98 The reason I’m restructuring my project is that I don’t want my build files sitting next to my src files. This separation makes it much easier for maintaining in a variety of ways. I have pulled this off without any problems and it seems to be working great. Did some builds and all is working on the devices.

They’re doing the typical directives.js and services.js - not organizing by module/component.

I think it’s pretty clear they are using modules… GitHub - mwaylabs/generator-m-ionic: Advanced workflows and setup for building rock-solid Ionic apps

Anyways, glad you found a solution!

Look at their file structure:

File structure

└── app/ - your application folder
│ └── bower_components/ - local installation of bower packages
│ └── main/ - —main module—
│ │ ├── assets/ - assets: fonts, images, translation, etc… goes here
│ │ ├── constants/ - angular constants
│ │ ├── controllers/ - angular controllers
│ │ ├── directives/ - angular directives
│ │ ├── filters/ - angular filters
│ │ ├── services/ - angular services
│ │ ├── styles/ - scss styles
│ │ ├── templates/ - angular templates
│ │ └── main.js - angular module definition, routing etc…
│ └── anotherModule/ - —another module—
│ │ ├── …
│ ├── app.js - application module, includes main module, ionic, ui-router etc …
│ └── index.html - angular entry point, injects: app files, bower files, fonts, …
├── gulp_tasks/ - gulp tasks
├── hooks/ - cordova hooks
├── nodes_modules/ - local installation of node modules
├── platforms/ - cordova platforms
├── plugins/ - corodova plugins
├── www/ - your gulp build goes here, cordova starts building from here
├── .bowerrc - bower configuration
├── .editorconfig - editor configuration
├── .gitattributes - git’s attribute configuration
├── .gitignore - git’s ignore configuration
├── .jscsrc - jscs configuration
├── .jshintignore - jshint ignore
├── .jshintrc - jshint configuration
├── .travis.yml - travis continuous integration configuration
├── .yo-rc.json - yeoman’s .yo-rc.json
├── bower.json - bower dependencies
├── config.xml - cordova’s config.xml
├── gulpfile.js - entry point to all gulp tasks
├── jenkins.sh - shell script for jenkins continuous integration
├── package.json - node dependencies configuration
├── README.md - the generator’s README.md

In a module structure, controllers and directives shouldn’t be in a controllers/directives folder but in the module folder. Right? Am I reading this right?

In a module structure, controllers and directives shouldn’t be in a controllers/directives folder but in the module folder.

If you notice the files in the folder “main” belong to a module named “main”.

└── main/ - ---main module---
│ │ ├── assets/ - assets: fonts, images, translation, etc... goes here
│ │ ├── constants/ - angular constants
│ │ ├── controllers/ - angular controllers
│ │ ├── directives/ - angular directives
│ │ ├── filters/ - angular filters
│ │ ├── services/ - angular services
│ │ ├── styles/ - scss styles
│ │ ├── templates/ - angular templates
│ │ └── main.js - angular module definition, routing etc...

Then in app.js you have:

'use strict';
angular.module('MyCoolApp', [
  // load your modules here
  'main' // starting with the main module
]);

And if you need more modules, then you generate them with yeoman and they’re wired automatically. That’s what the following line says:

└── anotherModule/ - ---another module---
│ │ ├── ...

and you get something like this:


Look at the chat module, it has the same structure as the “main” module…

Right, but you still have the “controllers” folder. Scroll down in that best practices doc to the “A More Complex App Example”. You’ll notice the controllers are inside of the module, not a controllers folder. That’s more of the approach I meant and the m-generator doesn’t seem to be talking about that pattern.

use bindep has more features …
npm install -g bindep

with simple bower/wiredep there are many cases in which you must pass to manual :slight_smile: