-->

How to configure Grunt to replace Bower dependenci

2019-01-21 05:35发布

问题:

I am new to Yeoman/Grunt/Bower. I have a bower.json file that defines the following dependencies:

bower.json

{
    "dependencies": {
        "angular": "~1.0.7",
        "jquery": "~1.8.0",
        "bootstrap": "~2.3.2",
        "angular-grid": "~2.0.5"
    }
}

In my html file I am using the non-minified versions of those libraries, which I installed via the command bower install

index.html

<script src="components/jquery/jquery.js"></script>
<script src="components/bootstrap/docs/assets/js/bootstrap.js"></script>
<script src="components/angular/angular.js"></script>
<script src="components/angular-grid/build/ng-grid.js"></script>

How can I configure grunt, so it will:

  1. Copy only the minified versions of the those js files to the build directory
  2. Replace the HTML so it will change e.g. jquery.js to jquery.min.js
  3. When not using CDNs - is it recommend to combine all the files together with the custom application script?

What is the right approach here? Do I have to define each lib in a grunt copy task? Like:

Gruntfile.js:

copy: {
  dist: {
    files: [{
      src: [
        'components/jquery/jquery.min.js',
        'components/bootstrap/docs/assets/js/bootstrap.min.js',
        'components/angular/angular.min.js',
        'components/angular-grid/build/ng-grid.min.js'
      ]
    }]
  }
}

回答1:

Minified versions of the JavaScript libraries you're using will eventually not be shipped with Bower modules. Minifying and concatenating is not something the package manager is responsible for, but your build pipeline.

With Yeoman, the recommended way is to use grunt-usemin, which will take care of all the necessary steps. You can see an example of this when scaffolding out a new app with yo webapp and taking a look at the generated Gruntfile.js and index.html.

In your case, you would need to add a comment around your script includes:

<!-- build:js scripts/main.js -->
<script src="components/jquery/jquery.js"></script>
<script src="components/bootstrap/docs/assets/js/bootstrap.js"></script>
<script src="components/angular/angular.js"></script>
<script src="components/angular-grid/build/ng-grid.js"></script>
<!-- endbuild -->

And make sure to have the corresponding usemin tasks in your Grunt pipeline:

useminPrepare: {
    options: {
        dest: 'dist'
    },
    html: 'app/index.html'
},
usemin: {
    options: {
        dirs: ['dist']
    },
    html: ['dist/{,*/}*.html'],
    css: ['dist/styles/{,*/}*.css']
},


回答2:

don't need to change the html, try grunt-contrib-uglify

uglify: {
  libs: {
    files: [
      {
        expand: true,
        cwd: 'components',
        src: '**/*.js',
        dest: 'build/components'
      }
    ]
  }
}

and if the file are requested more the one page, it will be cached by the browser, it will be load faster than the combined larger file.



回答3:

Another option if you are interested in using minified javascript and also having the package version in the include path is to use grunt-version-copy-bower-components. This grunt plugin handles copying the bower component to a destination directory, includes the component version in the component path, and modifies referencing files (html and css) to use the versioned minified path.

Including the version in the components path can be helpful if the site is hosted with a cache (behind a CDN). It allows you to specify long cache times for the bower components. When switching to a new bower component version the URL will be new and the cache will fetch the new one instead of serving a stale component.

An example configuration:

versionCopyBowerComponents: {
  options: {
    exclude: ['underscore'],
    dest: 'dist/libs',
    filesReferencingComponents: {
      files: ['dist/test.html', 'dist/test.css'],
      useComponentMin: true
    }
  }
}

The plugin will determine the bower components that your project is using and automatically install them to the path specified in dest. The files listed in filesReferencingComponents->files are files that include/source the bower component. Specifying useComponentMin will cause it to choose the minified version of the component.



回答4:

It would be a bad practice to minify yourself a library that already exists in a minified version. Fortunately, at least for angularJS, the bower package includes angular.min.js.map file. With this source map, I think it makes no sense to include at any point the non-minified file in the source. Just include the min file, leave it outside Grunt minifier, and let the browser map to the non minified source.