آموزش استفاده از Grunt برای مدیریت وظایف تکراری - Grunt (جلسه 29) - اضافه کردن Vendor Prefix به کدهای CSS

دسته بندی: آموزش
زمان مطالعه: 6 دقیقه
۰۵ شهریور ۱۳۹۵

در این مطلب با ادامه آموزش Grunt در خدمتتون هستیم.

grund

در این جلسه قصد داریم در مورد پلاگین grunt-autoprefixer صحبت کنیم و با استفاده از اون Vendor Prefix‌ها مختلف و متناسب رو به کدهای CSS خودمون اضافه کنیم. این پلاگین از AutoPrefixer استفاده میکنه و از قدرت اون بهره میبره و میتونید از هر ویژگی که در اونجا پشتیبانی میشه در اینجا هم استفاده کنید. این ابزار برای کسب اطلاعات در مورد مرورگرها و ویژگی‌های مختلف از اطلاعات و Database سایت Can I Use استفاده میکنه و خودش رو بروز میکنه. در ابتدا باید این پلاگین رو در پروژه خودمون نصب کنیم. برای اینکار عبارت زیر رو در cmd قرار میدیم:

npm install grunt-autoprefixer --save-dev

بعد از اینکار اینتر میزنیم:grunt install autoprefixer

میبینید که این پلاگین بدون ارور درون پروژه ما نصب شده و حالا اگر package.json رو ببینید، بصورت زیر بروز رسانی شده:grunt install autoprefixer 2

حالا باید این بسته رو درون gruntfile.js لود کنیم:grunt install autoprefixer 3

حالا باید یک وظیفه بنام autoprefixer بسازیم:

module.exports = function (grunt) {

	require('time-grunt')(grunt);

	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),

		concat: {
			options: {
				separator: '\n\n/*--------Next File-------*/\n\n',
				banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' + '<%= grunt.template.today("yyyy-mm-dd") %> */\n\n',
				footer: '\n\n/*------<%= pkg.author %>---------*/'
			},
			css: {
				src: ['development/css/css1.css', 'development/css/css2.css'],
				dest: 'final/css/final.css'
			},

			js: {
				src: ['development/js/js1.js', 'development/js/js2.js'],
				dest: 'final/js/final.js'
			}
		},

		uglify: {
			options: {
				mangle: false
			},
			js1: {
				files: {
					'final/js/js1.min.js': ['development/js/js1.js']
				}
			},
			js2: {
				files: {
					'final/js/js2.min.js': ['development/js/js2.js']
				}
			},
			all: {
				options: {
					sourceMap: true,
        			sourceMapName: 'final/js/all.min.js.map'
				},
				files: {
					'final/js/all.min.js': ['development/js/*.js']
				}
			}
		},

		cssmin: {
			options: {
				advanced: false,
				sourceMap: true,
        		sourceMapName: 'final/css/import.min.css.map'
			},
			all: {
				files: {
					'final/css/import.min.css': ['development/css/import.css']
				}
			}
		},

		coffee: {
			options: {
				bare: true,
				sourceMap: true,
				sourceMapDir: 'final/js/coffee.js.map'
			},
			compile: {
			    files: {
			      'final/js/coffee.js': ['development/coffee/coffee.coffee']
			    }
			}
		},

		less: {
			options: {
				compress: true,
				sourceMap: true,
				sourceMapFilename: 'final/css/less.css.map'
			},
			compile: {
				files: {
					'final/css/less.css': 'development/less/style.less'
				}
			}
		},

		sass: {
			dist: {
				options: {
	        sourcemap: 'none',
	        style: 'compressed'
	      },
	      files: {
	        'final/css/sass.css': 'development/sass/compile.sass',
	        'final/css/scss.css': 'development/sass/compile.scss'
	      }
	    }
		},

		pug: {
			compile: {
				options: {
					data: {
						debug: false
					}
				},
				files: {
					'final/html/template.html': ['development/pug/template.pug']
				}
			},
			debug: {
		    options: {
		      data: {
		        debug: true
		      }
		    },
		    files: {
		      'final/html/debug.html': 'development/pug/template.pug'
		    }
		  },
		  release: {
		    options: {
		      data: {
		        debug: false
		      }
		    },
		    files: {
		      'final/html/release.html': 'development/pug/template.pug'
		    }
		  }
		},

		csslint: {
			options: {
				csslintrc: '.csslintrc'
			},
		  lint: {
		    src: ['final/css/final.css']
		  }
		},

		jshint: {
			options: {
				reporter: require('jshint-stylish'),
				force: true,
				jshintrc: true
			},
			hint: {
		    src: ['final/js/final.js']
		  }
		},

		autoprefixer: {
			// ...
		}
	});

	grunt.loadNpmTasks('grunt-contrib-concat');
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-contrib-cssmin');
	grunt.loadNpmTasks('grunt-contrib-coffee');
	grunt.loadNpmTasks('grunt-contrib-less');
	grunt.loadNpmTasks('grunt-contrib-sass');
	grunt.loadNpmTasks('grunt-contrib-pug');
	grunt.loadNpmTasks('grunt-contrib-csslint');
	grunt.loadNpmTasks('grunt-contrib-jshint');
	grunt.loadNpmTasks('grunt-autoprefixer');

	grunt.registerTask('default', ['concat', 'uglify', 'cssmin', 'coffee', 'less', 'sass', 'pug', 'csslint']);
};

دیدید که بعد از task هایی که قبلا ساخته بودیم، وظیفه autoprefixer رو هم ساختیم.

قبل از اینکه تنظیمات درون autoprefixer رو قرار بدیم، یک فایل بنام prefix.css رو درون پوشه css موجود در پوشه development بسازید. درون فایل prefix.css کدهای زیر رو قرار بدین:

:fullscreen a {
    display: flex
}

a {
    display: flex;
}

a {
    -webkit-border-radius: 5px;
            border-radius: 5px;
}

دیدید که درون این فایل مورد نظر مقداری کد css قرار داده شده. حالا میخایم کاری کنیم که به این کدها vendor prefix بصورت اتوماتیک اضافه بشه و دستی اونا رو اضافه نکنیم.

حالا میتونیم تنظیمات مورد نظرمون رو درون اون قرار بدیم، برای اینکار بصورت زیر عمل میکنیم:grunt config prefix

میبینید که یک وظیفه بنام prefix ساختیم و درون اون ویژگی files رو قرار دادیم. درون files فایل و مسیر ورودی و خروجی رو مشخص کردیم. حالا برای اینکه اون رو بصورت پیش فرض با زدن grunt اجرا کنیم، autoprefixer رو به آرایه آخر اضافه میکنیم:grunt config prefix 2

حالا اگر grunt autoprefixer رو اجرا کنیم، کارهایی که مشخص کردیم تو یه چشم به هم زدن انجام میشن و فایل مورد نظر ساخته میشه.grunt config prefix 3

میبینید که با موفقیت عملیات مورد نظر انجام شده و حالا اگر به فایل prefix.css ساخته شده در پوشه final نگاه کنید، کدهای زیر وجود دارن:

:-webkit-full-screen a {
    display: -webkit-box;
    display: flex
}

:-moz-full-screen a {
    display: flex
}

:-ms-fullscreen a {
    display: -ms-flexbox;
    display: flex
}

:fullscreen a {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex
}

a {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
}

a {
    border-radius: 5px;
}

میبینید که همه prefix‌ها بصورت زیبا و حرفه ای اضافه شدن و کار شما رو راحت کردن. اگر دقت کنید برای rule آخر که مربوط به a هست یکی از vendor prefix‌ها که -webkit-border-radius بود، پاک شده است و به دلیل این هست که برای مرورگرهای انتخابی فعلی این مورد نیاز نیس و در مرورگر مورد نظر بهمین صورت پشتیبانی میشه. اساس این ابزار بر پایه browserlist هست. این ابزار اطلاعات مورد نظر خودش رو از سایت Caniuse دریافت میکنه و بعد از اون ما میتونیم با استفاده از Query نوشتن، اطلاعات خاصی رو از اون بیرون بکشیم و استفاده کنیم. مثلا فرض کنید من به browserslist میگم که فقط مرورگرهای ie 6 و 7 رو نیاز دارم. این ابزار این کار رو برام انجام میده و اطلاعات مورد نظر رو از can i use میگیره و کدهای css شما رو متناسب با اون تغییر میده و prefix‌های مورد نظر رو بهش اضافه میکنه. مثالهایی از Query هایی که میتونین استفاده کنید در اینجا قرار داده شده. اگر این ویژگی رو مشخص نکنید، یک Query پیش فرض در نظر گرفته میشه و اون کوئری > 1%, last 2 versions, Firefox ESR هست. این ابزار یک سایت هم داره که میتونین کوئری‌های مورد نظر خودتون رو در اون قرار بدین و بعد از اون اینتر بزنید تا مرورگرهای متناسب با اون کوئری به شما نمایش داده بشن. حالا شما میتونین با استفاده از ویژگی browsers این کوئری رو تغییر بدین. بصورت زیر:grunt config prefix 4

حالا اگر مجددا grunt autoprefixer رو اجرا کنید، کدهای خروجی بصورت زیر خواهند بود:

:-webkit-full-screen a {
    display: flex
}

:-moz-full-screen a {
    display: -moz-box;
    display: flex
}

:fullscreen a {
    display: -moz-box;
    display: flex
}

a {
    display: -moz-box;
    display: flex;
}

a {
    border-radius: 5px;
}

دیدید که با قبل فرق کرده. پس نتیجه میگیریم که ما مرورگرهای مورد نظرمون رو مشخص میکنیم و این ابزار متناسب با اونا، Vendor Prefix‌های مورد نیاز رو اضافه میکنه و کدهامون رو بهینه نگه میداره. برای بروزرسانی پایگاه داده caniuse در سیستم خودتون عبارت زیر رو در cmd قرار بدین و اینتر بزنید:

npm update caniuse-db

برای مطالعه بیشتر در مورد این پلاگین به این لینک مراجعه کنید.

در جلسات بعدی بیشتر در مورد Grunt صحبت میکنیم.

امیدوارم از این جلسه خوشتون اومده باشه.

موفق باشید

یا علی

چه امتیازی به این مقاله می دید؟
نویسنده محمد اسفندیاری
بسیار به طراحی وب علاقمندم و به سرعت در حال یادگیری تمام مباحث پیشرفته هستم و دوست دارم که به دیگران هم یاد بدهم.

جلسات دوره

نظرات کاربران

اولین دیدگاه این پست رو تو بنویس !

نیاز به لاگین

برای ارسال دیدگاه و یا پرسیدن سوال خود در این قسمت، باید در سایت لاگین شوید.