While I was developing some client javascript today, I came across a situation where I wanted server-side directory information in my client javascript. Specifically, I needed to refer to a static html template from some Angular directive code.

Directory structure

root
    - ng
        - dist
            - js
                - my_app
                      my_app_bundle.js
                    - partials
                          directive_template.html
        - src
            - js
                - my_app
                      my_app_controllers.js
                      my_app_services.js
                      my_app_directives.js
                      my_app.js
                    - partials
                          directive_template.html

I do all my development on files in the src directory, and have a gulp watch process using Browserify to compile the source files into the dist/my_app_bundle.js file, as well as copying any html files with from the src/ directory into dist/ with the same exact directory structure.

Directive code

angular.module('myapp.directives', [])
        .directive('myDirective', function() {
            return {
                templateUrl: "/ng/dist/js/my_app/partials/directive_template.html",
                link: function(scope, ele) {
                    // link fn code
                }
            }
        })

Here you can see the templateUrl hardcoded. This is an easy solution in the moment. But it sucks in the long run - it's not resistant to directory structure changes and prone to bugs.

The solution

angular.module('myapp.directives', [])
        .directive('myDirective', function() {
            return {
                templateUrl: __dirname + "/partials/directive_template.html",
                link: function(scope, ele) {
                    // directive code
                }
            }
        })

During browserify compilation,
__dirname + '/partials/directive_template.html'
is compiled to
'/ng/dist/js/my_app' + '/partials/directive_template.html'

Browserify re-uses the Node.js module system. I knew this, and wondered whether Browserify would also know about Node.js-like globals. Turns out it does! I thought that was cool enough to write a blog post on.