Absolute path using grunt-wiredep for Grunt + Bower

7.2k Views Asked by At

The grunt-wiedep task outputs relative paths for assets. I instead need absolute paths. So, I reconfigured the replace block as suggested here: https://github.com/stephenplusplus/grunt-wiredep/issues/46

But, after specifying the replace block as suggested, I get the following added as my script reference. As you can see, it is wrong.

<script src="/../../../public/vendors/jquery/dist/jquery.js"></script>
<script src="/../../../public/vendors/angular/angular.js"></script>
<script src="/../../../public/vendors/angular-resource/angular-resource.js"></script>
<script src="/../../../public/vendors/angular-route/angular-route.js"></script>

What I want is this instead:

<script src="/vendors/jquery/dist/jquery.js"></script>
<script src="/vendors/angular/angular.js"></script>
<script src="/vendors/angular-resource/angular-resource.js"></script>
<script src="/vendors/angular-route/angular-route.js"></script>

So, I tried this for my replace block. Notice the RegEx:

replace: {
    js: '<script src="/{{filePath}}"></script>'.replace(/\.\.\/public/gi, ''),
    css: '<link rel="stylesheet" href="/{{filePath}}" />'.replace(/\.\.\/public/gi, '')
}

But it appears that {{filePath}} is being replaced at a later time and hence the RegEx does not yield the expected results.

What would be an ideal way to handle such situation?

2

There are 2 best solutions below

1
On BEST ANSWER

In the gruntfile.js configuration for wiredep add the following: ignorePath: '/../../../public'

This will remove that part from the start of the path created by wiredep.

For example something like this, plus whatever adjustments for your config:

wiredep: {
    target: {
        src: [
            '/Views/**/*.html',
        ],          
        ignorePath: '/../../../public',
        dependencies: true,
        devDependencies: false, 
    }
},
0
On

To build on Robert Noack's answer, you can use RegEx instead as your ignorePath value. Personally I use this following pattern to remove the relative paths but keep's the last forward-slash from the match so that the final output will be an absolute path:

/^(\/|\.+(?!\/[^\.]))+\.+/

Here is how this works:

^                  // Start matching at first character in string
(
    \/             // [1] Look for "/"
  |                //  OR
    \.+            // [2] Look for "." repeated one or more times, followed by
    (?!            //   [3] Don't match
        \/[^\.]    //     "/" followed by a character that is not "."
    )              
)+
\.+                // [4] Look for remaining "." not including the next "/"

So if for example our outputed filepath is /../../../path/to/file.js, we first remove the first / [1], then we remove ../../ [2], but skipping the last ../ [3]. We are now left with ../path/to/file.js but then we remove .. [4] resulting in /path/to/file.js

In the end, my configuration looks like this:

wiredep: {
    app: {
        src: [
            "<%= config.app %>/templates/**/*.html"
        ],
        exclude: [
            "modernizr"
        ],
        ignorePath: /^(\/|\.+(?!\/[^\.]))+\.+/,
        devDependencies: true
    }
}

And my HTML output looks like:

## BEFORE ##
<!-- build:js(.) assets/vendor/vendor.js -->
<!-- bower:js -->
<script src="../../../bower_components/jquery/dist/jquery.js"></script>
<script src="../../../bower_components/jquery-waypoints/waypoints.js"></script>
<script src="../../../bower_components/holderjs/holder.js"></script>
<!-- endbower -->
<!-- endbuild -->

## AFTER ##
<!-- build:js(.) assets/vendor/vendor.js -->
<!-- bower:js -->
<script src="/bower_components/jquery/dist/jquery.js"></script>
<script src="/bower_components/jquery-waypoints/waypoints.js"></script>
<script src="/bower_components/holderjs/holder.js"></script>
<!-- endbower -->
<!-- endbuild -->