taptapship / wiredep

Wire Bower dependencies to your source code.
MIT License
1.15k stars 142 forks source link

Question: relative path option from bower.json location #176

Closed JaKXz closed 8 years ago

JaKXz commented 9 years ago

I've got a .bowerrc file which specifies my bower_components directory as public/lib, and I'm using the node API to get my files as normal.

However, the array of filepaths I'm getting back from wiredep().js and wiredep().css uses absolute paths from the root of my machine, e.g. /Users/Jason/git/my-project/public/lib/package-name/etc.

Is there a way to specify a relative path that wiredep should use?

JaKXz commented 9 years ago

To support my question, I tried the following (from just the node command line):

require('wiredep')({ cwd: './' }).js

which produces the same thing as above. Then I tried:

require('wiredep')({ cwd: 'public/' }).js

which gives me an error because my bower.json file is not in public/. Would it be easier/better to move bower.json there?

CWSpear commented 9 years ago

Try:

var jsFiles = require('wiredep')({
  ignorePath: __dirname + '/public'
}).js;

That turn /Users/Jason/git/my-project/public/lib/package-name/etc into /lib/package-name/etc, which, if I understood your issue correctly, is what you're wanting?

(By the way, even if you hadn't found that option, you could always map out those files and exclude that path (which is more or less what ignorePath does)):

// es6, cuz we should all start learning it! =)
var jsFiles = require('wiredep')().js.map(path => path.replace(__dirname + '/public', ''));

// or es5, cuz io.js is still young
var jsFiles = require('wiredep')().js.map(function (path) {
  return path.replace(__dirname + '/public', '');
});
stephenplusplus commented 9 years ago

I'm surprised it's giving back absolute paths at all. Doesn't it just give a relative path from source file (index.html) to injected file (some file in a bower package)?

JaKXz commented 9 years ago

@CWSpear thanks for the suggestion, but unfortunately the ignorePath option is not doing what I would like. Even with it set to ignorePath: /Users/Jason/git/my-project/ explicitly, I'm still getting the absolute path (/Users/Jason/git/my-project/public/lib/some-bower-package/files.js).

I need the paths to come back like this: public/lib/some-bower-package/files.js, which is the relative path from where the bower.json is located.

The .map solution is what I've ended up leaving as a //HACK for now.

CWSpear commented 9 years ago

Like @stephenplusplus said, it is odd that it's the full path. Something else weird is maybe going on? Anyway, that .map solution should be perfectly suitable.

sabrehagen commented 9 years ago

I'm encountering the same issue on Windows. I could use the map function, but it is really not optimal.

CWSpear commented 9 years ago

Sorry, my last comment (which I have now deleted) was dumb; I thought this was a different issue.

Anyway, @sabrehagen, are you also using .bowerrc? There may be an issue with the way it creates the paths if you are using a path from .bowerrc...

CWSpear commented 9 years ago

Ok, after digging in the code: it looks like this method has always functioned this way.

And the more I think about it and look at how I use it, and how I've heard other people use it, it's meant to give you the full paths. That way, you can do whatever you want outside of the default wiredep toolchain, and it's usually better to have the full path, and it's easier remove part of a path than add part of one.

So I would argue that using .map is the solution here.

@sabrehagen, @JaKXz If I may ask, what is it you're trying to do that you're using wiredep().js, exactly? (It's perfectly legit to do so, I'm just curious as to why and maybe we can find a better overall solution...?)

JaKXz commented 9 years ago

@CWSpear I would honestly love it if there was a relativePath option. I'm using wiredep to specify my "lib" files and then using grunt-injector get my app files together. The build process is based on relative paths from the Gruntfile, so it would be awesome if wiredep was consistent with that, rather than having to do the map manually.

Of course, I think it's only worth implementing in wiredep if you guys are not just doing the map behind the scenes. I haven't explored the source enough to know how you're building paths, but I think building paths from the location of the .bowerrc or bower.json is a reasonable solution for the relativePath option.

JaKXz commented 9 years ago

I also tried using process.cwd() in the ignorePath option with no luck.

CWSpear commented 9 years ago

Right, so what happens is that wiredep more or less gets a list of files from the same thing wiredep().js does, and then when it injects them, it looks at all the things like cwd and ignorePath. Those transformations aren't applied in what is exposed with the wiredep().js.

We could change it to be add those transformations, but it would be a breaking change as others could (and do) rely on the current functionality.

I do something similar in my build, but I use gulp, so using a map would be trivial since gulp is just working with files and not massive configs. In my case, gulp.src "relative-izes" the file path for me, so I don't actually have to do that.

Have you tried grunt-injector's ignorePath option?

JaKXz commented 9 years ago

One thing I've noticed is that bower's api lists files w/ relative paths by default from bower.json. Perhaps for the relativePath option wiredep could walk through the object that command returns and filter based on the overrides?

sabrehagen commented 9 years ago

@CWSpear We're using wiredep().js to build a list of our bower packages that we then inject into our grunt watcher and subsequently index.html. grunt-wiredep wasn't able to solve our needs, we we're using wiredep directly.

JaKXz commented 9 years ago

But to answer your question, @CWSpear, I haven't tried grunt-injector's ignorePath option.

sabrehagen commented 9 years ago

Furthermore, I need to normalise my paths for use in the map function as node reports __dirname as c:\repositories\stemn\ but wiredep reports C:\\repositories\\stemn\\etc... resulting in

var jsFiles = wiredep.js.map(function (path) {
  return upath.normalize(path).replace(upath.normalize(__dirname + '/app/'), '');
});
eddiemonge commented 8 years ago

Is this still an issue? If so, I'll reopen

AndrewAllison commented 8 years ago

I Found this to still be an issue. My fixes included.

Changing the .bowerrc file as follow

{
  "directory": "./app/bower_components"
}

This results in the bower components living in the app dir with the rest of the index.html and files. The local server can now see the files.

I also had to change the $.useref.assets().restore() as discussed.

The bower method in the gulpfile.js now looks like:

// inject bower components
gulp.task('bower', function () {
  return gulp.src(paths.views.main)
    .pipe(wiredep({
      directory: yeoman.app + '/bower_components',
      ignorePath: '..'
    }))
  .pipe(gulp.dest(yeoman.app));
});

This all seems to now work fine in the browser. I've not tested prod environments etc.. though..

one more note I had issues with the server and ports on windows so that was changed to...

gulp.task('start:client', ['start:server', 'styles'], function () {
  openURL('http://localhost:9002');
});
gulp.task('start:server', function() {
  $.connect.server({
    root: [yeoman.app, '.tmp'],
    livereload: true,
    // Change this to '0.0.0.0' to access the server from outside.
    port: 9002,
    hostname: 'localhost',
  });
});`

Just in case anybody else gets the Error: listen EACCES 0.0.0.0:9000

simongcc commented 7 years ago

@JaKXz I would like also to do the mapping of the file path, may I know how to accomplish the same thing of the hack map in pipe?

I have tried the following but seems not working:

.pipe(wiredep({
      ignorePath: /^(\.\.\/)+/
    }).js.map(path){
      return path.replace("from something", "to something")
   })
...

Edited: I think it is due the the pipe is a stream instead of the original wiredep() so it does not support js.map because it is a stream at the point. In this case, is there any way to do it in a stream? or is there any way to tweak it before pipe?