ericclemmons / grunt-angular-templates

Grunt build task to concatenate & pre-load your AngularJS templates
MIT License
710 stars 107 forks source link

'dist' application requests partials despite their being in the JS file #116

Closed brandon-arnold closed 9 years ago

brandon-arnold commented 9 years ago

Hi there,

I've had this issue on the angular-fullstack github for a few weeks now to no avail, and I'm really not sure how to fix it. Any help would be greatly appreciated. I generated the application using their generator, but from what I can see, they've got ngTemplates configured right, and it does seem to work out of the box on the boilerplate application.

Anyway, for some reason my 'dist' application is trying to get angular partials from the server (resulting in 404's for each; see grunt serve:dist output below, in which the root Angular directive of my application has a 404, since it is correctly not copied to my dist output, expecting it instead to be stored in $templateCache). And I can see that the ngtemplates task must be working to some extent, since the partials are in my dist/public/app/...app.js (e.g. there is a line in the minified JS of the form a.put("app/components/pcyBody/pcyBody.html", '<!-- Output HTML -->') }]);).

Environment information (aside from grunt-angular-templates version 0.5.7):

1.3.3
C:\Program Files\ConEmuPack;C:\Program Files\ConEmuPack\ConEmu;C:\Program Files (x86)\CA\SC\CAWIN\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\TortoiseSVN\bin;c:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL Server\100\DTS\Binn\;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0\;C:\Program Files\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files (x86)\Common Files\Plantronics\;C:\Program Files (x86)\Plantronics\Spokes3G\;C:\Program Files (x86)\Plantronics\MyHeadsetUpdater\;C:\Program Files (x86)\Plantronics\VoyagerEdge\;C:\Program Files (x86)\CA\SC\Csam\SockAdapter\bin;C:\Program Files (x86)\CA\DSM\bin;C:\Program Files (x86)\CA\SC\CBB\;C:\PROGRA~2\CA\SC\CAM\bin;C:\Program Files\nodejs\;C:\Program Files\Microsoft\Web Platform Installer\;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Git\cmd;C:\Ruby193\bin;C:\ProgramData\chocolatey\bin;C:\Users\212438903\.ssh;C:\Program Files (x86)\PuTTY;C:\Program Files (x86)\GnuWin32\bin;C:\Program Files (x86)\pngquant;C:\Users\212438903\AppData\Roaming\npm;.bin;C:\Windows\system32\inetsrv\;C:\Program Files (x86)\SysinternalsSuite;C:\Program Files (x86)\gtk+\bin %NODE_PATH%
win32 { http_parser: '1.0',
  node: '0.10.33',
  v8: '3.14.5.9',
  ares: '1.9.0-DEV',
  uv: '0.10.29',
  zlib: '1.2.3',
  modules: '11',
  openssl: '1.0.1j' }

Relevant Gruntfile.js sections

//...
        // Package all the html partials into a single javascript payload
        ngtemplates: {
            options: {
                // This should be the name of your apps angular module
                module: 'policyApp',
                htmlmin: {
                    collapseBooleanAttributes: true,
                    collapseWhitespace: true,
                    removeAttributeQuotes: true,
                    removeEmptyAttributes: true,
                    removeRedundantAttributes: true,
                    removeScriptTypeAttributes: true,
                    removeStyleLinkTypeAttributes: true
                },
                usemin: 'app/app.js'
            },
            main: {
                cwd: '<%= yeoman.client %>',
                src: ['{app,components}/**/*.html'],
                dest: '.tmp/templates.js'
            },
            tmp: {
                cwd: '.tmp',
                src: ['{app,components}/**/*.html'],
                dest: '.tmp/tmp-templates.js'
            }
        },
//...
    grunt.registerTask('build', [
        'clean:dist',
        'injector:less',
        'copy:imagemin',
        'concurrent:dist',
        'injector',
        'wiredep',
        'useminPrepare',
        'autoprefixer',
        'ngtemplates',
        'concat',
        'ngAnnotate',
        'copy:dist',
        'cdnify',
        'cssmin',
        'uglify',
        'rev',
        'usemin'
    ]);

Output of grunt serve:dist

C:\Projects\policy5>grunt serve:dist
Running "serve:dist" (serve) task

Running "clean:dist" (clean) task
Cleaning .tmp...OK
Cleaning dist/package.json...OK
Cleaning dist/public...OK
Cleaning dist/server...OK

Running "injector:less" (injector) task
Missing option `template`, using `dest` as template instead
Injecting less files (26 files)
>> Nothing changed

Running "copy:imagemin" (copy) task
Copied 1 files

Running "concurrent:dist" (concurrent) task

Running "svgmin:dist" (svgmin) task
Total saved: 0 B

Done, without errors.

Running "less:server" (less) task
File .tmp/app/app.css created: 0 B → 10.96 kB

Done, without errors.

Running "imagemin:dist" (imagemin) task
Minified 0 images (saved 0 B)

Done, without errors.

Running "injector:scripts" (injector) task
Missing option `template`, using `dest` as template instead
Injecting js files (36 files)
>> Nothing changed

Running "injector:less" (injector) task
Missing option `template`, using `dest` as template instead
Injecting less files (26 files)
>> Nothing changed

Running "injector:css" (injector) task
Missing option `template`, using `dest` as template instead
>> Nothing changed

Running "wiredep:target" (wiredep) task

Running "useminPrepare:html" (useminPrepare) task
Going through client/index.html to update the config
Looking for build script HTML comment blocks

Configuration is now:

  concat:
  { generated:
   { files:
      [ { dest: '.tmp\\concat\\app\\vendor.css',
          src:
           [ 'client\\bower_components\\bootstrap-datepicker\\css\\datepicker.css',
             'client\\bower_components\\bootstrap-datepicker\\css\\datepicker3.css' ] },
        { dest: '.tmp\\concat\\app\\app.css',
          src: [ '{.tmp,client}\\app\\app.css' ] },
        { dest: '.tmp\\concat\\app\\vendor.js',
          src:
           [ '{client,node_modules}\\bower_components\\jquery\\dist\\jquery.js',
             '{client,node_modules}\\bower_components\\angular\\angular.js',
             '{client,node_modules}\\bower_components\\angular-resource\\angular-resource.js',
             '{client,node_modules}\\bower_components\\angular-cookies\\angular-cookies.js',
             '{client,node_modules}\\bower_components\\angular-sanitize\\angular-sanitize.js',
             '{client,node_modules}\\bower_components\\lodash\\dist\\lodash.compat.js',
             '{client,node_modules}\\bower_components\\angular-ui-router\\release\\angular-ui-router.js',
             '{client,node_modules}\\bower_components\\requirejs\\require.js',
             '{client,node_modules}\\bower_components\\bootstrap-datepicker\\js\\bootstrap-datepicker.js' ] },
        { dest: '.tmp\\concat\\app\\app.js',
          src:
           [ '{.tmp,client}\\app\\app.js',
             '{.tmp,client}\\app\\archived\\archived.controller.js',
             '{.tmp,client}\\app\\archived\\archived.js',
             '{.tmp,client}\\app\\components\\pcyBody\\pcyBody.directive.js',
             '{.tmp,client}\\app\\components\\pcyBody\\pcyFooter\\pcyFooter.directive.js',
             '{.tmp,client}\\app\\components\\pcyBody\\pcyHeader\\pcyHeader.controller.js',
             '{.tmp,client}\\app\\components\\pcyBody\\pcyHeader\\pcyHeader.directive.js',
             '{.tmp,client}\\app\\components\\pcyCallout\\pcyCallout.directive.js',
             '{.tmp,client}\\app\\components\\pcyCalloutSection\\pcyCalloutSection.directive.js',
             '{.tmp,client}\\app\\components\\pcyDocModalGroup\\pcyDocModal\\pcyDocModal.directive.js',
             '{.tmp,client}\\app\\components\\pcyDocModalGroup\\pcyDocModalGroup.directive.js',
             '{.tmp,client}\\app\\components\\pcyDocModalGroup\\pcyDocModalSrc\\pcyDocModalSrc.directive.js',
             '{.tmp,client}\\app\\components\\pcyDraftDelegationForm\\pcyCreateDelegationForm\\pcyCreateDelegationForm.directive.js',
             '{.tmp,client}\\app\\components\\pcyDraftDelegationForm\\pcyDraftDelegationForm.directive.js',
             '{.tmp,client}\\app\\components\\pcyDraftDelegationForm\\pcyEditDelegationForm\\pcyEditDelegationForm.directive.js',
             '{.tmp,client}\\app\\components\\pcyDraftPolicyForm\\pcyCreateDraftForm\\pcyCreateDraftForm.directive.js',
             '{.tmp,client}\\app\\components\\pcyDraftPolicyForm\\pcyDraftPolicyForm.directive.js',
             '{.tmp,client}\\app\\components\\pcyDraftPolicyForm\\pcyEditDraftForm\\pcyEditDraftForm.directive.js',
             '{.tmp,client}\\app\\components\\pcyFormToggleGroup\\pcyFormTarget\\pcyFormTarget.directive.js',
             '{.tmp,client}\\app\\components\\pcyFormToggleGroup\\pcyFormToggleGroup.directive.js',
             '{.tmp,client}\\app\\components\\pcyFormToggleGroup\\pcyLoadingForm\\pcyLoadingForm.directive.js',
             '{.tmp,client}\\app\\components\\pcyPolicyApiService\\pcyPolicyApiService.service.js',
             '{.tmp,client}\\app\\components\\pcyPolicyTable\\pcyPolicyFilter\\pcyPolicyFilter.directive.js',
             '{.tmp,client}\\app\\components\\pcyPolicyTable\\pcyPolicyPagination\\pcyPolicyPagination.directive.js',
             '{.tmp,client}\\app\\components\\pcyPolicyTable\\pcyPolicyTable.directive.js',
             '{.tmp,client}\\app\\components\\pcyViewDelegationForm\\pcyViewDelegationForm.directive.js',
             '{.tmp,client}\\app\\components\\pcyViewPolicyForm\\pcyViewPolicyForm.directive.js',
             '{.tmp,client}\\app\\create\\create.controller.js',
             '{.tmp,client}\\app\\create\\create.js',
             '{.tmp,client}\\app\\current\\current.controller.js',
             '{.tmp,client}\\app\\current\\current.js',
             '{.tmp,client}\\app\\delegations\\delegations.controller.js',
             '{.tmp,client}\\app\\delegations\\delegations.js',
             '{.tmp,client}\\app\\myPolicies\\myPolicies.controller.js',
             '{.tmp,client}\\app\\myPolicies\\myPolicies.js',
             '{.tmp,client}\\assets\\cdx\\components\\respond\\respond.min.js',
             '{.tmp,client}\\assets\\cdx\\js\\require.config.js' ] } ] } }

  uglify:
  { generated:
   { files:
      [ { dest: 'dist\\public\\app\\vendor.js',
          src: [ '.tmp\\concat\\app\\vendor.js' ] },
        { dest: 'dist\\public\\app\\app.js',
          src: [ '.tmp\\concat\\app\\app.js' ] } ] } }

  cssmin:
  { generated:
   { files:
      [ { dest: 'dist\\public\\app\\vendor.css',
          src: [ '.tmp\\concat\\app\\vendor.css' ] },
        { dest: 'dist\\public\\app\\app.css',
          src: [ '.tmp\\concat\\app\\app.css' ] } ] } }

Running "autoprefixer:dist" (autoprefixer) task
File .tmp/app/app.css created.

Running "ngtemplates:main" (ngtemplates) task
File .tmp/templates.js created.
Added .tmp/templates.js to <!-- build:js app\app.js -->

Running "ngtemplates:tmp" (ngtemplates) task
>> No templates found
File .tmp/tmp-templates.js created.
Added .tmp/tmp-templates.js to <!-- build:js app\app.js -->

Running "concat:generated" (concat) task
File .tmp\concat\app\vendor.css created.
File .tmp\concat\app\app.css created.
File .tmp\concat\app\vendor.js created.
File .tmp\concat\app\app.js created.

Running "ngAnnotate:dist" (ngAnnotate) task
>> 2 files successfully generated.

Running "copy:dist" (copy) task
Created 377 directories, copied 2202 files

Running "cdnify:dist" (cdnify) task
Going through dist/public/index.html to update script refs
✔ bower_components/jquery/dist/jquery.js changed to //ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js
✔ bower_components/angular/angular.js changed to //ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.min.js
✔ bower_components/angular-cookies/angular-cookies.js changed to //ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular-cookies.min.js
✔ bower_components/angular-resource/angular-resource.js changed to //ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular-resource.min.js
✔ bower_components/angular-sanitize/angular-sanitize.js changed to //ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular-sanitize.min.js

Running "cssmin:generated" (cssmin) task
File dist\public\app\vendor.css created: 51.52 kB → 35.81 kB
File dist\public\app\app.css created: 10.9 kB → 8.53 kB

Running "uglify:generated" (uglify) task
File dist\public\app\vendor.js created: 1.82 MB → 344.37 kB
File dist\public\app\app.js created: 92.77 kB → 69.07 kB

Running "rev:dist" (rev) task
dist/public/app/app.js >> 4eaf670e.app.js
dist/public/app/vendor.js >> 63bb9af2.vendor.js
dist/public/app/app.css >> 89a256e2.app.css
dist/public/app/vendor.css >> 259610cc.vendor.css
dist/public/assets/images/yeoman.png >> 66adba84.yeoman.png

Running "usemin:html" (usemin) task

Processing as HTML - dist/public/index.html
Update the HTML to reference our concat/min/revved script files
<script src="app/vendor.js" changed to <script src="app/63bb9af2.vendor.js"
<script src="app/app.js" changed to <script src="app/4eaf670e.app.js"
Update the HTML with the new css filenames
<link rel="stylesheet" href="app/vendor.css" changed to <link rel="stylesheet" href="app/259610cc.vendor.css"
<link rel="stylesheet" href="app/app.css" changed to <link rel="stylesheet" href="app/89a256e2.app.css"
Update the HTML with the new img filenames
Update the HTML with data-main tags
Update the HTML with data-* tags
Update the HTML with background imgs, case there is some inline style
Update the HTML with anchors images
Update the HTML with reference in input

Running "usemin:css" (usemin) task

Processing as CSS - dist/public/app/259610cc.vendor.css
Update the CSS to reference our revved images

Processing as CSS - dist/public/app/89a256e2.app.css
Update the CSS to reference our revved images

Running "usemin:js" (usemin) task

Processing as JS - dist/public/app/4eaf670e.app.js
Update the JS to reference our revved images

Processing as JS - dist/public/app/63bb9af2.vendor.js
Update the JS to reference our revved images

Running "env:all" (env) task

Running "env:prod" (env) task

Running "express:prod" (express) task
Starting background Express server
Express server listening on 9000, in production mode

Running "wait" task
>> Waiting for server reload...
Done waiting!

Running "open:server" (open) task

Running "express-keepalive" task
GET /app/components/pcyBody/pcyBody.html 404 99ms
brandon-arnold commented 9 years ago

I think I have resolved it. It is a discrepancy between generator-angular-fullstack and grunt-angular-templates. In generator-angular-fullstack, the boilerplate codefiles for a directive have the templateUrl's with a preceding '/'. But grunt-angular-templates is generating URLs in the $templateCache .put(...) statements without the preceding '/'. This difference results in the directive making an HTTP get, resulting in a 404.

I think angular's template engine should support the different URLs, personally. Is there a right way to do this?

ericclemmons commented 9 years ago

I'd use a prefix:

https://github.com/ericclemmons/grunt-angular-templates#prefix

Let me know if that works!

brandon-arnold commented 9 years ago

Good to know. I see that the generator does it both ways! So the generator needs to be consistent. I will bring this information in the referenced article and do a pull request on theirs. Thanks a bunch!

brandon-arnold commented 9 years ago

And yes, a 'prefix' works.