I'm trying to use environment variables in my AngularJS to do environment-specific configuration. I'm using the Yeoman workflow which uses Grunt, and the grunt-ng-constant plugin is purported to help with environment-specific configuration. In following this tutorial, I set up my Gruntfile accordingly, but when I run grunt serve in the console, config.js is not written into /app/scripts/. Without config.js, I cannot inject the environment variable into the angular application.
Here's a snippet of my Gruntfile:
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',
ngtemplates: 'grunt-angular-templates',
cdnify: 'grunt-google-cdn'
});
// Configurable paths for the application
var appConfig = {
app: require('./bower.json').appPath || 'app',
dist: '../server/dist'
};
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-ng-constant');
// Define the configuration for all the tasks
grunt.initConfig({
// Project settings
yeoman: appConfig,
ngconstant: {
// options for all environments
options: {
space: ' ',
wrap: '"use strict";\n\n {%= __ngModule %}',
name: 'config'
},
// Development/Testing environment
development: {
options: {
dest: '<%= yeoman.app %>/scripts/config.js'
},
constants: {
ENV: {
name: 'development',
apiEndpoint: 'http://localhost:3000'
}
}
},
// Production environment
production: {
options: {
dest: '<%= yeoman.dist %>/scripts/config.js'
},
constants: {
ENV: {
name: 'production',
apiEndpoint: 'http://productionUrl'
}
}
}
},
...
grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
if (target === 'dist') {
return grunt.task.run(['build', 'connect:dist:keepalive']);
}
grunt.task.run([
'clean:server',
'wiredep',
'concurrent:server',
'autoprefixer:server',
'connect:livereload',
'watch',
'ngconstant:development'
]);
});
...
What is generated is /.sass-cache and /.tmp in the same directory (client) as the Gruntfile.
My app file structure:
The ngconstant task is not being called because it is after the watch task. Modify the run block so the line 'ngconstant:development' is next to 'autoprefixer:server', so it is before connect & watch tasks. Don't forget to add a comma!
grunt.task.run([
'clean:server',
'wiredep',
'concurrent:server',
'autoprefixer:server',
'ngconstant:development',
'connect:livereload',
'watch'
]);
Also, the app path might be wrong in the bower.json file. To be sure, modify the path to your app by changing appConfig so it looks like this:
var appConfig = {
app: 'app',
dist: '../server/dist'
}
Related
I am trying to use javascript Const with Grunt Uglify but receive the error:
Unexpected token: keyword «const».
I have done a little googling and tried
npm install terser-webpack-plugin --save-dev
However that did not work.
It was stated I needed to add the following to my Plugins array...
const TerserPlugin = require('terser-webpack-plugin')
new TerserPlugin({
parallel: true,
terserOptions: {
ecma: 6,
},
}),
I wasn't sure exactly where to add this though? Does it go in my grunt file.js?
Additionally I also saw that a fix might be to use the harmony branch of grunt-contrib-uglify. But I fear this method is out of date?
Ultimately I am attempting to code a cookie consent pop up. Does anyone know how to get Const to work with grunt uglify?
Or does anyone have a better recommendation for coding cookie consent pop ups?
Many thanks.
Edit: Adding grunt file as requested
// Load Grunt
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// Tasks
sass: { // Begin Sass Plugin (this takes all your scss files and compiles them into style.css)
dist: {
files: [{
expand: true,
cwd: 'assets/scss/my-theme',
src: ['**/*.scss'],
dest: 'dist/css',
ext: '.css'
}]
}
},
postcss: { // Begin Post CSS Plugin (this applies browser prefixes to your compiled style.css in 'dist' folder)
options: {
map: false,
processors: [
require('autoprefixer')({
overrideBrowserslist: ['last 2 versions']
})
]
},
dist: {
src: 'dist/css/style.css'
}
},
cssmin: { // Begin CSS Minify Plugin (this takes your style.css file from 'dist', minifies it and creates style.min.css)
target: {
files: [{
expand: true,
cwd: 'dist/css',
src: ['style.css', '!*.min.css'],
dest: 'dist/css',
ext: '.min.css'
}]
}
},
uglify: { // Begin JS Uglify Plugin (this takes your my-theme js files in 'assets', minifies them and creates script.min.js in 'dist' folder)
build: {
src: ['assets/js/my-theme/*.js'],
dest: 'dist/js/script.min.js'
}
},
watch: { // Compile everything into one task with Watch Plugin (this watches for any changes to scss and js files, so make sure it is pointing to your 'my-theme' CSS and JS folders in 'assets')
css: {
files: 'assets/scss/my-theme/**/*.scss',
tasks: ['sass', 'postcss', 'cssmin']
},
js: {
files: 'assets/js/my-theme/**/*.js',
tasks: ['uglify']
}
}
});
// Load Grunt plugins
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-postcss');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-terser');
// Register Grunt tasks
grunt.registerTask('default', ['watch']);
};
This is my first day with grunt and I'm trying to make it work using these tutorials
https://24ways.org/2013/grunt-is-not-weird-and-hard/
https://css-tricks.com/autoprefixer/
And my Gruntfile.js is this:
module.exports = function(grunt) {
// 1. All configuration goes here
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
scripts: {
files: ['scripts/app.js'],
tasks: ['uglify'],
options: {
spawn: false,
}//For some reason I had a come here. Don't know if it matters
},
css: {
files: ['content/app.scss'],
tasks: ['sass'],
options: {
spawn: false,
}
},
styles: {
files: ['content/app.css'],
tasks: ['autoprefixer']
}
},
uglify: {
build: {
src: "scripts/app.js",
dest: "scripts/app-final.js"
}
},
sass: {
dist: {
options: {
style: 'compressed'
},
files: {
'content/app.css': 'content/app.scss'
}
}
},
autoprefixer: {
dist: {
files: {
'content/app-prefixed.css': 'content/app.css'
}
}
},
imagemin: {
dynamic: {
files: [{
expand: true,
cwd: 'assets/img/',
src: ['**/*.{png,jpg,gif}'],
dest: 'assets/img/'
}]
}
}
});
// 3. Where we tell Grunt we plan to use this plug-in.
grunt.loadNpmTasks(
'grunt-contrib-uglify',
'grunt-contrib-sass',
'grunt-autoprefixer',
'grunt-contrib-watch',
'grunt-contrib-imagemin'
);
// 4. Where we tell Grunt what to do when we type "grunt" into the terminal.
grunt.registerTask(
'default', [
'watch',
'uglify',
'sass',
'autoprefixer',
'imagemin'
]);
};
But when I try grunt watch watch I get this:
# grunt watch
Warning: Task "watch" not found. Use --force to continue.
Aborted due to warnings.
To make things weirder grunt uglify is seen
# grunt uglify
Running "uglify:build" (uglify) task
>> Destination scripts/app-final.js not written because src files were empty.
>> No files created.
Done, without errors.
Running grunt --help gives me an interesting thing
Available tasks
uglify Minify files with UglifyJS. *
default Alias for "watch", "uglify", "sass", "autoprefixer", "imagemin" tasks.
I really cannot find a difference between uglify and the other functions. VS Code doesn't give me any errors. I installed all of the used tasks. I have node installed.
Restarting VS Code doesn't help. I don't think this matters but just in case, I'm using Linux.
Reinstalling the dependencies didn't help either
You did the following:
grunt.loadNpmTasks(
'grunt-contrib-uglify',
'grunt-contrib-sass',
'grunt-autoprefixer',
'grunt-contrib-watch',
'grunt-contrib-imagemin'
);
Replace it with this:
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-imagemin');
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-uglify');
Grunt does not take multiple Arguments in grunt.loadNpmTasks for some reason. You can see the proper usage of the loadNpmTasks - function in the documentation: https://gruntjs.com/sample-gruntfile
My Gruntfile checks which Git branch I'm on (dev, test or prod) and if "prod" I want to minify/compress the CSS with compass (grunt-contrib-compass).
But I'm unable to change the outputStyle property in compass options.
However I'm able to change my custom meta.build.outputStyle to "compressed" in the deploy function, but unable to change compass.site_x.options.outputStyle by reading that meta variable. Any ideas?
Gruntfile summary (parts excluded):
module.exports = function(grunt) {
grunt.initConfig({
meta:{
build: {
outputStyle: 'expanded'
}
},
compass: {
site_x: {
options: { // Target options
sassDir: 'sass',
specify: 'sass/legacy/main.scss',
cssDir: 'dist/styles',
imagesDir: "images",
outputStyle: "<%= meta.build.outputStyle %>",
config: "./config.rb"
}
}
},
.... //misc
});
.... //misc
function deploy(environment) {
if(environment === "prod") {
grunt.log.oklns("Starting deploy to PROD");
grunt.config.set("meta.build.outputStyle", "compressed");
grunt.log.oklns("outputStyle: "+grunt.config.get('meta').build.outputStyle); // prints "compressed"
}
}
....
I have a folder with differents design project, on each one I may have scss files to compile. So I did a Gruntfile to watch on all this folders for the scss files and I want to compile them in their directory. But it' actually not working because of this error :
Running "sassAll" task
Running "sass:animating-rocket" (sass) task
Verifying property sass.animating-rocket exists in config...ERROR
>> Unable to process task.
Warning: Required config property "sass.animating-rocket" missing. Use --force to continue.
Aborted due to warnings.
It seems that a variable is not define on the config scope...
My Gruntfile looks like this :
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dist: {
options: {
style: 'compressed'
},
files: [{
src: ['<%= grunt.task.current.args[0] %>/*.scss'],
dest: '<%= grunt.task.current.args[0] %>',
ext: '.css'
}]
}
},
watch: {
options: {
livereload: true
},
css: {
files: ['**/*.scss'],
tasks: ['sassAll'],
options: {
spawn: false
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('sassAll', function () {
gruntUtils.sassTasks.forEach(function (param) {
grunt.task.run('sass:' + param);
});
});
var gruntUtils = {
sassTasks: ['animating-rocket', 'hamburger-animation']
};
grunt.registerTask('default', ['sassAll', 'watch']);
};
I'm new to setting up my own grunt, and this is what I have come up with. I was just wondering if someone could look it over and give me some hints/advice.
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
coffee: {
compile: {
expand: true,
flatten: true,
cwd: 'src/coffee',
src: ['*.coffee'],
dest: 'src/js/',
ext: '.js'
}
},
concat: {
css: {
src: [
'src/css/*'
],
dest: 'css/.css'
},
js: {
src: [
'src/js/*'
],
dest: 'js/package.js'
}
},
cssmin: {
css: {
src: 'css/package.css',
dest: 'css/package.min.css'
}
},
uglify: {
js: {
files: {
'js/package.min.js': ['js/package.js']
}
}
},
watch: {
aspx: {
files: ['*.aspx', '*.master']
},
css: {
files: ['src/css/*'],
tasks: ['concat:css', 'cssmin']
},
coffee: {
files: ['src/coffee/*'],
tasks: ['coffee:compile']
},
js: {
files: ['src/js/*'],
tasks: ['concat:js', 'uglify']
},
livereload: {
files: ['*.aspx', '*.master', 'css/*.css', 'js/*.js'],
options: { nospawn: true, livereload: true }
}
}
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-coffee');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.registerTask('default', ['coffee:compile','concat:css', 'cssmin:css', 'concat:js', 'uglify:js', 'watch']);
};
It does work, and reloads and compiles perfectly. I was just wondering if there may be a more effiecent way to handle this. Being my first gruntfile I know it is very far from perfect.
I would recommend load-grunt-tasks in order to cut down on the complexity of the main Gruntfile.js. It's incredibly simple to use. It allows you to split up the Gruntfile.js into a number of smaller JS files stored in a separate Grunt folder, for example:
/root
/Grunt
cssmin.js
coffee.js
watch.js
...
And then your main Gruntfile.js to load in your tasks is simply, again for example:
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
}
It's all held together with YAML file called aliases.yaml that sits in the Grunt folder that details the Grunt commands and their associated processes. So with this in the YAML file:
lint:
- clear
- jshint
- jscs
You could run grunt lint and it would run those tasks.
I've found it a) a complete lifesaver, and b) helped me understand Grunt at a whole different level.
I've made an example repo for you to help explain what I'm talking about. I hope it's of some help.