Related
I want to deploy my VueJS app to GitHub, but after I run "npm run build" I don't have in dist folder the index.html file: https://gyazo.com/94b69e4e9ef07d6334dc8b11d7cd7024
This file is already existing outside the dist folder.
Can you please help me find a solution to deploy this project?
My webpack.config.js looks like this:
var path = require('path')
var webpack = require('webpack')
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
module: {
rules: [
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
],
}, {
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
},
extensions: ['*', '.js', '.vue', '.json']
},
devServer: {
historyApiFallback: true,
noInfo: true,
overlay: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}
Thank you!
Try changing:
path: path.resolve(__dirname, './dist'),
to
path: path.resolve('./dist'),
After fixing my css/scss compiling I'm now try to run the css on my html file, but I keep getting:
GET http://localhost:8080/dist/css/screen.css 404 (Not Found)localhost/:26
GET http://localhost:8080/source/js/modernizr.js 404 (Not Found)localhost/:28
Now, my paths on my html files is the follow:
<link href="dist/css/screen.css" media="screen, projection" rel="stylesheet" type="text/css" />
<script type"text/javascript" src="source/js/modernizr.js"></script>
What am I doing wrong? is it an html path issue? or is it a gruntfile.js issue?
something must missing from either the html or gruntFile.js
hope it makes sense
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
config: {
source: 'source/',
dest: 'dist/',
dist: './dist/'
},
connect: {
options: {
port: 8080,
livereload: 35729,
hostname: 'localhost'
},
livereload: {
options: {
open: true,
base: '<%= config.source %>html',
port: 8080
}
},
dist: {
options: {
open: true,
base: '<%= config.dest %>',
livereload: false
}
}
},
watch:{
compass:{
options: {livereload: true },
files:['<%= config.source %>**/*.scss'],
tasks:['compass']
},
css: {
options: {livereload: true },
files: ['<%= config.dest %>*.css'],
tasks: []
},
js: {
options: { livereload: true },
files: ['<%= config.source %>js/*.js'],
tasks: ['jshint']
},
images: {
options: { livereload: true },
files: ['<%= config.source %>images/*.*']
},
fontsicons: {
options: { livereload: true },
files: ['<%= config.source %>images/icons/**/*.{svg,eot,woff,ttf,woff2,otf}']
},
livereload: {
// Here we watch the files the sass task will compile to
// These files are sent to the live reload server after sass compiles to them
options: { livereload: true },
files: ['<%= config.source %>html/*']
}
},
compass: {
dist: {
files: [{
expand: true,
cwd: 'sass',
src: ['source/sass/*.scss', '*.sass'],
dest: 'css/',
ext: '.css'
}]
}
}
});
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['connect:livereload', 'watch', 'compass', ]);
grunt.registerTask('icons', ['webfont']);
};
To get HTTP response from http://localhost:8080 you'll need a http server running on your computer listening on port 8080. If you have no such server running, you will get always 404 error.
E.g. on Node.js the most used is Express: http://www.tutorialspoint.com/nodejs/nodejs_express_framework.htm.
With this piece of code you'll get "Hello World" response on http://localhost:8080 and handle the routes /dist and /source:
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World');
})
app.use(express.static(path.join(__dirname, 'dist')));
app.use(express.static(path.join(__dirname, 'source')));
var server = app.listen(8080, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
I scaffolded a project using the YEOMAN generator-webapp (I'm running Nodejs v4.0.0, NPM 3.5.3, Bower 1.7.5, Yeoman 1.6.0). When i ran the grunt serve command everything fired up just fine. All scripts and styles got loaded without errors.
The Issue
For some reason i just can't get my head around the following issue. All browsers i have tested (chrome 47, safari 9.0.3 and mozilla 43.0.2) are showing the value of the<title></title> and <script></script> nodes as text inside the window.
The strange part is, the scripts do got executed, as seen in te console.
At first i thought it may be a LiveReload or BrowserSync problem. But even after running grunt build and serving /dist/ using http-server the error remains.
I also reinstalled the complete project after updating NPM and Bower. After running grunt serve again the problem seemed to be gone. However, after a couple of changes in the index.html file the problem reoccured. Even after returning the index.html in it's original state.
Unfortunately i couldn't find any good reading material that even talks about this issue. (this is the closest i got; https://github.com/BrowserSync/browser-sync/issues/791. I'm not sure which steps to take from here. I includes the gruntfile.js, package.json and index.html. A little help or a pointer in the right direction would be greatly appreciated.
gruntfile.js
// Generated on 2016-01-27 using
// generator-webapp 1.1.2
'use strict';
// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// If you want to recursively match all subfolders, use:
// 'test/spec/**/*.js'
module.exports = function (grunt) {
// Time how long tasks take. Can help when optimizing build times
require('time-grunt')(grunt);
// Automatically load required grunt tasks
require('jit-grunt')(grunt, {
useminPrepare: 'grunt-usemin'
});
// Configurable paths
var config = {
app: 'app',
dist: 'dist'
};
// Define the configuration for all the tasks
grunt.initConfig({
// Project settings
config: config,
// Watches files for changes and runs tasks based on the changed files
watch: {
bower: {
files: ['bower.json'],
tasks: ['wiredep']
},
babel: {
files: ['<%= config.app %>/scripts/{,*/}*.js'],
tasks: ['babel:dist']
},
babelTest: {
files: ['test/spec/{,*/}*.js'],
tasks: ['babel:test', 'test:watch']
},
gruntfile: {
files: ['Gruntfile.js']
},
sass: {
files: ['<%= config.app %>/styles/{,*/}*.{scss,sass}'],
tasks: ['sass', 'postcss']
},
styles: {
files: ['<%= config.app %>/styles/{,*/}*.css'],
tasks: ['newer:copy:styles', 'postcss']
}
},
browserSync: {
options: {
notify: true,
background: true,
watchOptions: {
ignored: ''
}
},
livereload: {
options: {
files: [
'<%= config.app %>/{,*/}*.html',
'.tmp/styles/{,*/}*.css',
'<%= config.app %>/images/{,*/}*',
'.tmp/scripts/{,*/}*.js'
],
port: 9000,
server: {
baseDir: ['.tmp', config.app],
routes: {
'/bower_components': './bower_components'
}
}
}
},
test: {
options: {
port: 9001,
open: false,
logLevel: 'silent',
host: 'localhost',
server: {
baseDir: ['.tmp', './test', config.app],
routes: {
'/bower_components': './bower_components'
}
}
}
},
dist: {
options: {
background: false,
server: '<%= config.dist %>'
}
}
},
// Empties folders to start fresh
clean: {
dist: {
files: [{
dot: true,
src: [
'.tmp',
'<%= config.dist %>/*',
'!<%= config.dist %>/.git*'
]
}]
},
server: '.tmp'
},
// Make sure code styles are up to par and there are no obvious mistakes
eslint: {
target: [
'Gruntfile.js',
'<%= config.app %>/scripts/{,*/}*.js',
'!<%= config.app %>/scripts/vendor/*',
'test/spec/{,*/}*.js'
]
},
// Mocha testing framework configuration options
mocha: {
all: {
options: {
run: true,
urls: ['http://<%= browserSync.test.options.host %>:<%= browserSync.test.options.port %>/index.html']
}
}
},
// Compiles ES6 with Babel
babel: {
options: {
sourceMap: true,
presets: ['es2015']
},
dist: {
files: [{
expand: true,
cwd: '<%= config.app %>/scripts',
src: '{,*/}*.js',
dest: '.tmp/scripts',
ext: '.js'
}]
},
test: {
files: [{
expand: true,
cwd: 'test/spec',
src: '{,*/}*.js',
dest: '.tmp/spec',
ext: '.js'
}]
}
},
// Compiles Sass to CSS and generates necessary files if requested
sass: {
options: {
sourceMap: true,
sourceMapEmbed: true,
sourceMapContents: true,
includePaths: ['.']
},
dist: {
files: [{
expand: true,
cwd: '<%= config.app %>/styles',
src: ['*.{scss,sass}'],
dest: '.tmp/styles',
ext: '.css'
}]
}
},
postcss: {
options: {
map: true,
processors: [
// Add vendor prefixed styles
require('autoprefixer')({
browsers: ['> 1%', 'last 2 versions', 'Firefox ESR']
})
]
},
dist: {
files: [{
expand: true,
cwd: '.tmp/styles/',
src: '{,*/}*.css',
dest: '.tmp/styles/'
}]
}
},
// Automatically inject Bower components into the HTML file
wiredep: {
app: {
src: ['<%= config.app %>/index.html'],
ignorePath: /^(\.\.\/)*\.\./
},
sass: {
src: ['<%= config.app %>/styles/{,*/}*.{scss,sass}'],
ignorePath: /^(\.\.\/)+/
}
},
// Renames files for browser caching purposes
filerev: {
dist: {
src: [
'<%= config.dist %>/scripts/{,*/}*.js',
'<%= config.dist %>/styles/{,*/}*.css',
'<%= config.dist %>/images/{,*/}*.*',
'<%= config.dist %>/fonts/{,*/}*.*',
'<%= config.dist %>/*.{ico,png}'
]
}
},
// Reads HTML for usemin blocks to enable smart builds that automatically
// concat, minify and revision files. Creates configurations in memory so
// additional tasks can operate on them
useminPrepare: {
options: {
dest: '<%= config.dist %>'
},
html: '<%= config.app %>/index.html'
},
// Performs rewrites based on rev and the useminPrepare configuration
usemin: {
options: {
assetsDirs: [
'<%= config.dist %>',
'<%= config.dist %>/images',
'<%= config.dist %>/styles'
]
},
html: ['<%= config.dist %>/{,*/}*.html'],
css: ['<%= config.dist %>/styles/{,*/}*.css']
},
// The following *-min tasks produce minified files in the dist folder
imagemin: {
dist: {
files: [{
expand: true,
cwd: '<%= config.app %>/images',
src: '{,*/}*.{gif,jpeg,jpg,png}',
dest: '<%= config.dist %>/images'
},{
expand: true,
cwd: '<%= config.app %>',
src: '*.{ico,png}',
dest: '<%= config.dist %>'
}]
}
},
svgmin: {
dist: {
files: [{
expand: true,
cwd: '<%= config.app %>/images',
src: '{,*/}*.svg',
dest: '<%= config.dist %>/images'
}]
}
},
htmlmin: {
dist: {
options: {
collapseBooleanAttributes: true,
collapseWhitespace: true,
conservativeCollapse: true,
removeAttributeQuotes: true,
removeCommentsFromCDATA: true,
removeEmptyAttributes: true,
removeOptionalTags: true,
// true would impact styles with attribute selectors
removeRedundantAttributes: false,
useShortDoctype: true
},
files: [{
expand: true,
cwd: '<%= config.dist %>',
src: '{,*/}*.html',
dest: '<%= config.dist %>'
}]
}
},
// By default, your `index.html`'s <!-- Usemin block --> will take care
// of minification. These next options are pre-configured if you do not
// wish to use the Usemin blocks.
// cssmin: {
// dist: {
// files: {
// '<%= config.dist %>/styles/main.css': [
// '.tmp/styles/{,*/}*.css',
// '<%= config.app %>/styles/{,*/}*.css'
// ]
// }
// }
// },
// uglify: {
// dist: {
// files: {
// '<%= config.dist %>/scripts/scripts.js': [
// '<%= config.dist %>/scripts/scripts.js'
// ]
// }
// }
// },
// concat: {
// dist: {}
// },
// Copies remaining files to places other tasks can use
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= config.app %>',
dest: '<%= config.dist %>',
src: [
'*.txt',
'images/{,*/}*.webp',
'{,*/}*.html',
'fonts/{,*/}*.*'
]
}]
}
},
// Run some tasks in parallel to speed up build process
concurrent: {
server: [
'babel:dist',
'sass'
],
test: [
'babel'
],
dist: [
'babel',
'sass',
'imagemin',
'svgmin'
]
}
});
grunt.registerTask('serve', 'start the server and preview your app', function (target) {
if (target === 'dist') {
return grunt.task.run(['build', 'browserSync:dist']);
}
grunt.task.run([
'clean:server',
'wiredep',
'concurrent:server',
'postcss',
'browserSync:livereload',
'watch'
]);
});
grunt.registerTask('server', function (target) {
grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
grunt.task.run([target ? ('serve:' + target) : 'serve']);
});
grunt.registerTask('test', function (target) {
if (target !== 'watch') {
grunt.task.run([
'clean:server',
'concurrent:test',
'postcss'
]);
}
grunt.task.run([
'browserSync:test',
'mocha'
]);
});
grunt.registerTask('build', [
'clean:dist',
'wiredep',
'useminPrepare',
'concurrent:dist',
'postcss',
'concat',
'cssmin',
'uglify',
'copy:dist',
'filerev',
'usemin',
'htmlmin'
]);
grunt.registerTask('default', [
'newer:eslint',
'test',
'build'
]);
};
package.json
{
"private": true,
"devDependencies": {
"autoprefixer": "^6.0.2",
"babel-preset-es2015": "^6.1.18",
"grunt": "^0.4.5",
"grunt-babel": "^6.0.0",
"grunt-browser-sync": "^2.1.2",
"grunt-concurrent": "^1.0.0",
"grunt-contrib-clean": "^0.6.0",
"grunt-contrib-concat": "^0.5.1",
"grunt-contrib-copy": "^0.8.0",
"grunt-contrib-cssmin": "^0.12.2",
"grunt-contrib-htmlmin": "^0.4.0",
"grunt-contrib-imagemin": "^1.0.0",
"grunt-contrib-uglify": "^0.8.0",
"grunt-contrib-watch": "^0.6.1",
"grunt-eslint": "^17.0.0",
"grunt-filerev": "^2.2.0",
"grunt-mocha": "^0.4.12",
"grunt-newer": "^1.1.0",
"grunt-postcss": "^0.6.0",
"grunt-sass": "^1.0.0",
"grunt-svgmin": "^2.0.1",
"grunt-usemin": "^3.0.0",
"grunt-wiredep": "^2.0.0",
"jit-grunt": "^0.9.1",
"time-grunt": "^1.1.0"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "grunt test"
},
"eslintConfig": {
"extends": [
"eslint:recommended"
],
"env": {
"node": true,
"browser": true,
"es6": true,
"jquery": true,
"mocha": true
},
"rules": {
"quotes": [
2,
"single"
],
"indent": [
2,
2
]
}
},
"name": "Test_application",
"version": "1.0.0",
"main": "Gruntfile.js",
"directories": {
"test": "test"
},
"dependencies": {},
"author": "",
"license": "ISC",
"description": ""
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- build:css(.) styles/vendor.css -->
<!-- bower:css -->
<!-- endbower -->
<!-- endbuild -->
<!-- build:css(.tmp) styles/main.css -->
<link rel="stylesheet" href="styles/main.css">
<!-- endbuild -->
</head>
<body>
<h1>Hello world!</h1>
<!-- Test script -->
<script>//<![CDATA[
var test = 'Well, this is not helping.';
console.log(test);
//]]></script>
<script>
var test = 'Wow, i have been executed! Why am i visible as text in the window?';
console.log(test);
</script>
<!-- build:js(.) scripts/vendor.js -->
<!-- bower:js -->
<script src="/bower_components/jquery/dist/jquery.js"></script>
<!-- endbower -->
<!-- endbuild -->
<!-- build:js(.tmp) scripts/main.js -->
<script src="scripts/main.js"></script>
<!-- endbuild -->
</body>
</html>
Unfortunately i still don't know which problem exactly causes the effects like described above. However, i did found a solution. It seem's the Yeomean generator-webapp module hasn't been maintained for a while and lost some stability. (The Yeomen crew is currently looking for maintainers)
They did released a Gulp edition of the webapp generator, which could be found here. I simply build a new project with the gulp generator and replaced the new app directory with the old one. Worked like a charm. Don't forget to install Gulp global first if you didn't already.
I'm using grunt to build and deploy a simple angular web app that uses bootstrap and font-awesome. The project was initially created using yeoman generator-angular and built using grunt serve:dist
I noticed the URLS in some of my css files are not being revved or minified properly.
Edit: I've been reading about grunt tasks and I think I've narrowed it down to the rebase in cssmin/clean.
Adding noRebase: true to the cssmin options seems to fix some of the issues but cause others.
Without noRebase:true, this is in the minified css:
body{background-image:url(c:/dev/myapp/.tmp/images/ricepaper_v3.png);
#font-face{font-family:FontAwesome;src:url(/bower_components/components-font-awesome/fonts/fontawesome-webfont.eot?v=4.0.3);
Obviously I don't want it to reference bower_components or my local path.
With noRebase: true:
body{background-image:url(../images/ricepaper_v3.png);
#font-face{font-family:FontAwesome;src:url(../fonts/fontawesome-webfont.eot?v=4.0.3);
This fixes the fonts (which were never revved so the name is correct) but breaks the background image since the image is now named something like "a120f004.ricepaper_v3.png"
My gruntfilejs:
'use strict';
// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'
module.exports = function (grunt) {
// Load grunt tasks automatically
require('load-grunt-tasks')(grunt);
// Time how long tasks take. Can help when optimizing build times
require('time-grunt')(grunt);
// Define the configuration for all the tasks
grunt.initConfig({
// Project settings
yeoman: {
// configurable paths
app: require('./bower.json').appPath || 'app',
dist: 'dist'
},
// Watches files for changes and runs tasks based on the changed files
watch: {
bower: {
files: ['bower.json'],
tasks: ['bowerInstall']
},
js: {
files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
tasks: ['newer:jshint:all'],
options: {
livereload: true
}
},
jsTest: {
files: ['test/spec/{,*/}*.js'],
tasks: ['newer:jshint:test', 'karma']
},
styles: {
files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
tasks: ['newer:copy:styles', 'autoprefixer']
},
gruntfile: {
files: ['Gruntfile.js']
},
livereload: {
options: {
livereload: '<%= connect.options.livereload %>'
},
files: [
'<%= yeoman.app %>/{,*/}*.html',
'.tmp/styles/{,*/}*.css',
'<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
]
}
},
// The actual grunt server settings
connect: {
options: {
port: 9000,
// Change this to '0.0.0.0' to access the server from outside.
hostname: 'localhost',
livereload: 35729
},
livereload: {
options: {
open: true,
base: [
'.tmp',
'<%= yeoman.app %>'
]
}
},
test: {
options: {
port: 9001,
base: [
'.tmp',
'test',
'<%= yeoman.app %>'
]
}
},
dist: {
options: {
base: '<%= yeoman.dist %>'
}
}
},
// Make sure code styles are up to par and there are no obvious mistakes
jshint: {
options: {
jshintrc: '.jshintrc',
reporter: require('jshint-stylish')
},
all: [
'Gruntfile.js',
'<%= yeoman.app %>/scripts/{,*/}*.js'
],
test: {
options: {
jshintrc: 'test/.jshintrc'
},
src: ['test/spec/{,*/}*.js']
}
},
// Empties folders to start fresh
clean: {
dist: {
files: [{
dot: true,
src: [
'.tmp',
'<%= yeoman.dist %>/*',
'!<%= yeoman.dist %>/.git*'
]
}]
},
server: '.tmp'
},
// Add vendor prefixed styles
autoprefixer: {
options: {
browsers: ['last 1 version']
},
dist: {
files: [{
expand: true,
cwd: '.tmp/styles/',
src: '{,*/}*.css',
dest: '.tmp/styles/'
}]
}
},
// Automatically inject Bower components into the app
bowerInstall: {
app: {
src: ['<%= yeoman.app %>/index.html'],
ignorePath: '<%= yeoman.app %>/'
}
},
// Renames files for browser caching purposes
rev: {
dist: {
files: {
src: [
'<%= yeoman.dist %>/scripts/{,*/}*.js',
'<%= yeoman.dist %>/styles/{,*/}*.css',
'<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
'<%= yeoman.dist %>/styles/fonts/*'
]
}
}
},
// Reads HTML for usemin blocks to enable smart builds that automatically
// concat, minify and revision files. Creates configurations in memory so
// additional tasks can operate on them
useminPrepare: {
html: '<%= yeoman.app %>/index.html',
options: {
dest: '<%= yeoman.dist %>',
flow: {
html: {
steps: {
js: ['concat', 'uglifyjs'],
css: ['cssmin']
},
post: {}
}
}
}
},
// Performs rewrites based on rev and the useminPrepare configuration
usemin: {
html: ['<%= yeoman.dist %>/{,*/}*.html'],
css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
options: {
assetsDirs: ['<%= yeoman.dist %>']
}
},
// The following *-min tasks produce minified files in the dist folder
cssmin: {
options: {
root: '<%= yeoman.app %>',
noRebase: true
}
},
imagemin: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/images',
src: '{,*/}*.{png,jpg,jpeg,gif}',
dest: '<%= yeoman.dist %>/images'
}]
}
},
svgmin: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/images',
src: '{,*/}*.svg',
dest: '<%= yeoman.dist %>/images'
}]
}
},
htmlmin: {
dist: {
options: {
collapseWhitespace: false,
collapseBooleanAttributes: true,
removeCommentsFromCDATA: true,
removeOptionalTags: true
},
files: [{
expand: true,
cwd: '<%= yeoman.dist %>',
src: ['*.html', 'views/{,*/}*.html'],
dest: '<%= yeoman.dist %>'
}]
}
},
// ngmin tries to make the code safe for minification automatically by
// using the Angular long form for dependency injection. It doesn't work on
// things like resolve or inject so those have to be done manually.
ngmin: {
dist: {
files: [{
expand: true,
cwd: '.tmp/concat/scripts',
src: '*.js',
dest: '.tmp/concat/scripts'
}]
}
},
// Replace Google CDN references
cdnify: {
dist: {
html: ['<%= yeoman.dist %>/*.html']
}
},
// Copies remaining files to places other tasks can use
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= yeoman.app %>',
dest: '<%= yeoman.dist %>',
src: [
'*.{ico,png,txt}',
'.htaccess',
'*.html',
'views/{,*/}*.html',
'images/{,*/}*.{webp}',
'fonts/*'
]
}]
},
styles: {
expand: true,
cwd: '<%= yeoman.app %>/styles',
dest: '.tmp/styles/',
src: '{,*/}*.css'
}
},
// Run some tasks in parallel to speed up the build process
concurrent: {
server: [
'copy:styles'
],
test: [
'copy:styles'
],
dist: [
'copy:styles',
'imagemin',
'svgmin'
]
},
// By default, your `index.html`'s <!-- Usemin block --> will take care of
// minification. These next options are pre-configured if you do not wish
// to use the Usemin blocks.
// cssmin: {
// dist: {
// files: {
// '<%= yeoman.dist %>/styles/main.css': [
// '.tmp/styles/{,*/}*.css',
// '<%= yeoman.app %>/styles/{,*/}*.css'
// ]
// }
// }
// },
// uglify: {
// dist: {
// files: {
// '<%= yeoman.dist %>/scripts/scripts.js': [
// '<%= yeoman.dist %>/scripts/scripts.js'
// ]
// }
// }
// },
// concat: {
// dist: {}
// },
// Test settings
karma: {
unit: {
configFile: 'karma.conf.js',
singleRun: true
}
}
});
grunt.registerTask('serve', function (target) {
if (target === 'dist') {
return grunt.task.run(['build', 'connect:dist:keepalive']);
}
grunt.task.run([
'clean:server',
'bowerInstall',
'concurrent:server',
'autoprefixer',
'connect:livereload', //deploys the dist folder tot he server. otherwise use connect:livereload
'watch'
]);
});
grunt.registerTask('server', function (target) {
grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
grunt.task.run(['serve:' + target]);
});
grunt.registerTask('test', [
'clean:server',
'concurrent:test',
'autoprefixer',
'connect:test',
'karma'
]);
grunt.registerTask('build', [
'clean:dist',
'bowerInstall',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'ngmin',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'rev',
'usemin',
'htmlmin'
]);
grunt.registerTask('default', [
'newer:jshint',
'test',
'build'
]);
};
I noticed in the logs that it was only fontawesome that was not being revved. the background image is being revved, but for some reason it duplicates the css and doesnt delete the first local path.
Anyways, long story short I solved the issue by writing a grunt copy task and calling it in the grunt build. It just copies the bower component fonts to the expected dist folder. This seems like a fine solution as it will always use the bower updated fonts.
copy: {
...
, fontawesome: {
expand:true,
cwd: '<%= yeoman.app %>/bower_components/components-font-awesome/fonts',
dest: '<%= yeoman.dist %>/bower_components/components-font-awesome/fonts',
src: [ '**' ]
}
}
So I'm in love with grunt and live-reload. The one thing I don't understand is how to get my html to reload when the css or js reloaded. Using my code below, the HTML is watched and updated in real time using live-reload chrome extension. But when the sass is complied into css, I need the html to live-reload.
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
compass: {
dist: {
options: {
cssDir: 'styles',
sassDir: 'sass',
imagesDir: 'images',
javascriptsDir: 'scripts',
force: true
}
}
},
cssmin: {
minify: {
expand: true,
cwd: 'styles',
src: ['*.css', '!*.min.css'],
dest: 'styles',
ext: '.min.css'
}
},
watch: {
sass: {
files: '**/*.scss',
tasks: ['compass']
},
css: {
files: '**/*.css',
tasks: ['cssmin'],
},
html: {
files: ['index.html','**/*.css'],
options: {
livereload: true
}
}
}
});
grunt.loadNpmTasks('grunt-contrib');
grunt.registerTask('default',['watch','compass']);
}
The purpose of live reload is to only reload those assets that have changed, so if the CSS is compiled then that asset needs to reload, not the HTML. The live reload extension will do the rest depending on what changed. Therefore, add the livereload option to your CSS target as well.
watch: {
sass: {
files: '**/*.scss',
tasks: ['compass']
},
css: {
files: '**/*.css',
tasks: ['cssmin'],
options: {
livereload: true
}
},
html: {
files: ['index.html','**/*.css'],
options: {
livereload: true
}
}
}