Pregunta

I have code that makes it easy and fast to write/test code, that code does not belong in my production code (mostly it mocks out the server so I only need the grunt server).

Two parts to this, one is how to I remove parts of a script

angular.module('nglaborcallApp', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute',
'server_mocks',  // Don't want this line in the production build
'dialogs'

]

and then a section of index.html that needs to go away

<!-- build:js({.tmp,app}) scripts/mocks/mocks.js -->
<script type='text/javascript'>var Mocks = {};</script>
<script src='scripts/mocks/jobs.js'></script>
<script src='scripts/mock.js'></script>
<!-- endbuild -->

So this might be 2 questions. I don't see anything in the usemin documentation about this so I'm guessing there is some other tool, but I don't know what the name of that tool is.

The other possibility is I'm doing it wrong and rather than inject this mocking object, I should be doing it with the grunt server. What is everyone else doing?

¿Fue útil?

Solución

Ok, so stumbled on the answer while looking for something else and since no one had yet responded. Here is how I solved it:

You get a copy of Grunt Preprocess with

npm install --save-dev grunt-preprocess

Then you modify your GruntFile.js like so (this is for an angular project, YMMV)

module.exports = function (grunt) {
    grunt.loadNpmTasks('grunt-preprocess');      <-- Add this line near the top of the file

add this in your list of subtasks

    preprocess : {
        options: {
            inline: true,
            context : {
                DEBUG: false
            }
        },
        html : {
            src : [
                '<%= yeoman.dist %>/index.html', 
                '<%= yeoman.dist %>/views/*.html'
            ]
        },
        js : {
            src: '.tmp/concat/scripts/*.js'
        }
    },

Modify your registered tasks (at the bottom of the file) like thils:

grunt.registerTask('build', [
    'clean:dist',
    'useminPrepare',
    'concurrent:dist',
    'autoprefixer',
    'concat',
    'preprocess:js',  // Remove DEBUG code from production builds
    'preprocess:html',  // Remove DEBUG code from production builds
    'ngmin',
    'copy:dist',
    'cdnify',
    'cssmin',
    'uglify',
    'rev',
    'usemin'
]);

Then modify your existing javascript code something like this:

// @if DEBUG
'server_mocks',  // Won't be included in production builds
// @endif

and your existing html code something like this:

<!-- @if DEBUG -->
<script src='scripts/mock.js'></script>  <!-- Won't be included in production builds -->
<!-- @endif -->

Otros consejos

Take a look at dom munger (https://github.com/cgross/grunt-dom-munger) you can give the elements that you want removed a specific attribute or IDs and have it remove them from the html file. But, what I like better is to have it inject, via append or prepend, the unwanted element when I specify a target of dev. It keeps the original HTML cleaner. I haven't delt with removing portions of javascript though. Depending on what else is in your js file that you want changed, you could have it inject a different version of the file for your dev and release build.

Remove Examples:

  • 'script[data-remove="true"]' - all script elements with the attribute data-remove and a value of true.
  • '#removeMe' - the element with the ID removeMe

Append Examples:

  • { selector:'html',html:'<script src=\'scripts/mock.js\'></script> ' } - append the specified html to the html element

here is a solution where you don't need extra tools:

as stated in the documentation you could use a type which is not css/js and this will be removed during build

<!-- build:<type>(alternate search path) <path> -->
... HTML Markup, list of script / link tags.
<!-- endbuild -->
  • type: can be js, css or a custom type with a block replacement function defined
  • If another type, the block will be ignored. Useful for "development only" blocks that won't appear in your build

so you can just do something like this:

<!-- build:mockJs -->
<script type='text/javascript'>var Mocks = {};</script>
<script src='scripts/mocks/jobs.js'></script>
<script src='scripts/mock.js'></script>
<!-- endbuild -->

EDIT: for javascript you could use uglifies global definition

http://github.com/gruntjs/grunt-contrib-uglify/blob/master/docs/uglify-examples.md#conditional-compilation

just do an uglify config in you gruntfile:

grunt.initConfig({
   ...
   uglify: { 
      options: { 
         compress: {
            global_defs: {
               "PROD": true
             }
         }
      }
   }
   ...
});

and in js do something like:

var modules = ['ngCookies', 'ngResource',
   'ngSanitize',
   'ngRoute',
   'dialogs'
]

if(!PROD) {
  modules.push('server_mocks');
}

angular.module('nglaborcallApp', modules);

you could also add this global JS in your debug block

<!-- build:mockJs -->
<script type='text/javascript'>var Mocks = {};</script>
<script src='scripts/mocks/jobs.js'></script>
<script src='scripts/mock.js'></script>
<script type='text/javascript'>
   PROD = false;
</script>
<!-- endbuild -->
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top