使用構(gòu)建工具之前我覺得前端好蠢,css沒有變量,不能寫循環(huán),為了兼容要寫好多前綴,hmtl寫多頁面中有同一個(gè)header,我就粘貼復(fù)制,然后修改的時(shí)候每個(gè)都要改。 我還不會(huì)壓縮和合并,每次都要按F5刷新。其實(shí)這些問題也是網(wǎng)頁優(yōu)化的問題。 構(gòu)建工具正是解決這些問題的集合。雖然網(wǎng)上gulp和webpack的教程很多,我還是根據(jù)自己的需求整理了一下。 gulp安裝: https:///2014/01/getting-started-with-gulp/ webpack安裝: http://webpack./docs/installation.html
基本的需求: css:要能編譯sass,要壓縮,要能自己補(bǔ)前綴 js:要壓縮,要丑化(就是把變量名換成簡(jiǎn)單的字母,即省空間又不容易被看懂),要合并 img: 要壓縮 html:可以引入文件(就解決一開始說的問題,多頁面下共同的組件)
gulp中的watch功能可以監(jiān)聽文件,通過livereload和gulp的監(jiān)聽來實(shí)現(xiàn)保存后自動(dòng)構(gòu)建并刷新頁面十分帶感。
在給gulpfile之前,先看一下我的目錄結(jié)構(gòu): src是生產(chǎn)目錄,就是代碼都是在這了面編寫的 dist是發(fā)布目錄,里面裝的就是經(jīng)過壓縮合并等,構(gòu)建好的文件目錄 我把html也放在src目錄里了(可能有些人寫在dist中),然后構(gòu)建的時(shí)候在移到dist目錄中,這樣生產(chǎn)和發(fā)布的目錄就分離的比較好,你上傳到git上的時(shí)候可以只上傳src中的東西 .jshintrc是一個(gè)叫g(shù)ulp-jshint插件對(duì)應(yīng)的配置文件,這個(gè)插件是用來檢查你的js的書寫規(guī)范和錯(cuò)誤的,配置是配置它的規(guī)則 .babelrc是配置es6的,這個(gè)后面再說。
gulpfile // 載入外掛 var gulp = require('gulp'), sass = require('gulp-ruby-sass'), autoprefixer = require('gulp-autoprefixer'), minifycss = require('gulp-minify-css'), jshint = require('gulp-jshint'), uglify = require('gulp-uglify'), imagemin = require('gulp-imagemin'), rename = require('gulp-rename'), clean = require('gulp-clean'), order = require("gulp-order"), concat = require('gulp-concat'), notify = require('gulp-notify'), cache = require('gulp-cache'), livereload = require('gulp-livereload'), fileinclude = require('gulp-file-include') ; // 樣式 gulp.task('styles', function() { return sass('src/css/*.scss') .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4')) .pipe(gulp.dest('dist/css')) .pipe(rename({ suffix: '.min' })) .pipe(minifycss()) .pipe(gulp.dest('dist/css')) .pipe(notify({ message: 'Styles task complete' })); }); // 腳本 gulp.task('scripts', function() { return gulp.src(['src/**/*.js']) .pipe(order([ "lib/jquery-2.0.3.min.js", "lib/*.js", "js/*.js" ])) .pipe(jshint('.jshintrc')) .pipe(jshint.reporter('default')) .pipe(concat('main.js')) .pipe(gulp.dest('dist/js')) .pipe(rename({ suffix: '.min' })) .pipe(uglify()) .pipe(gulp.dest('dist/js')) .pipe(notify({ message: 'Scripts task complete' })); }); // 圖片 gulp.task('images', function() { return gulp.src('src/images/**/*') .pipe(cache(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true }))) .pipe(gulp.dest('dist/images')) .pipe(notify({ message: 'Images task complete' })); }); //html gulp.task('html', function() { return gulp.src('src/**/*.html') .pipe(fileinclude({ prefix: '@@', basepath: '@file' })) .pipe(gulp.dest('dist/')) .pipe(notify({ message: 'html task complete' })); }); // 清理 gulp.task('clean', function() { return gulp.src(['dist/css', 'dist/js', 'dist/images'], {read: false}) .pipe(clean()); }); // 預(yù)設(shè)任務(wù) gulp.task('default', ['clean'], function() { gulp.start('styles', 'scripts', 'images', 'html'); }); gulp.task('watch', function() { // 看守所有.scss檔 gulp.watch('src/css/**/*.scss', ['styles']); // 看守所有.js檔 gulp.watch('src/js/**/*.js', ['scripts']); // 看守所有圖片檔 gulp.watch('src/images/**/*', ['images']); //看守html gulp.watch('src/**/*.html', ['html']) ; livereload.listen(); gulp.watch(['dist/**']).on('change', livereload.changed); }); 有幾個(gè)插件說明一下: 1.gulp-notify這個(gè)插件是用來完成任務(wù)后給你一個(gè)提示音的,因?yàn)槿绻?xiàng)目大第一次構(gòu)建會(huì)很慢。 2.gulp-concat插件合并js的時(shí)候是沒有順序的,所以我用了gulp-order來解決依賴的問題,比如好多文件依賴jquery 3.gulp-cache插件是緩存img,因?yàn)閕mg壓縮很費(fèi)時(shí)間,所以這個(gè)插件就是指構(gòu)建有變更的img 4.gulp-livereload這個(gè)插件需要chrome中的插件支持,在chrome瀏覽器中右上角,設(shè)置->擴(kuò)展程序->獲取更多擴(kuò)展程序 在這里搜索livereload,并下載安裝 安裝完成后會(huì)有這樣的圖標(biāo)
編譯sass遇到的坑: 編譯sass使用的是插件是gulp-ruby-sass,之前經(jīng)常報(bào)錯(cuò)是編碼的問題,后面將項(xiàng)目路徑的中文名改成英文名就解決了問題。 網(wǎng)上還有最終方案是在SASS 項(xiàng)目中 encoding = “utf-8” 出處: http://wuyixiang.sinaapp.com/sass-compass-compile-error/
感覺gulp這些功能都蠻不錯(cuò),但我其實(shí)還有一些需求沒說,是關(guān)于js的 1.模塊化(避免命名沖突) 2.要用es6(跟上潮流嘛) 3.js能不能按需加載?比如說我有頁面A和頁面B,他們都依賴一個(gè)base.js,然后又分別各自依賴a.js和b.js,這種情況我用剛才的gulpfile打包以后合并出來的一個(gè)公共的js是將三個(gè)js都包括了,但顯然頁面B不需要a.js,所以當(dāng)用戶單獨(dú)訪問頁面B的時(shí)候加載的js就顯得多余了,就多費(fèi)了流量啊,速度也會(huì)慢。 上述的前兩個(gè)gulp還是能解決,但是第三個(gè)問題好像并不好解決。。。在查找各方資料后我決定用webpack,所以就是其他css,html的部分還是gulp來處理,但是把js交給webpack來處理
webpack登場(chǎng)??! 其實(shí)使用了es6后就可以用新特性export和import寫模塊化的東西了,所以前兩個(gè)需求算是合并了。 import和export舉例: export class animal{ constructor(name){ this.name = name; } sayhi(){ //console.log(`hi ${this.name} !`); alert(this.name); } } export var myname = "mtjs " ; import {animal,myname} from './animal' ; 第三個(gè)需求使用webpack中的CommonsChunkPlugin這個(gè)插件實(shí)現(xiàn)的 這個(gè)插件可以把多個(gè)html中公共依賴的部分打包成一個(gè)和多個(gè)公共依賴包(chunk),這樣每個(gè)頁面只需要引入這個(gè)公共chunk和自己?jiǎn)为?dú)的js就可以了。 webpack和gulp一樣,都是用配置文件的: const webpack = require('webpack'); var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); module.exports = { entry: { index:'./src/js/index.js', main:'./src/js/main.js' }, output: { filename: '[name].js' }, module: { loaders: [{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', }] }, plugins: [ new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, }, output: { comments: false, }, }),//壓縮和丑化 new webpack.ProvidePlugin({ $: 'jquery' }),//直接定義第三方庫 new CommonsChunkPlugin({ name: "commons", // (the commons chunk name) filename: "commons.js", // (the filename of the commons chunk) minChunks: 2, // (Modules must be shared between 2 entries) chunks: ["index", "main"] // (Only use these entries) })//定義公共chunk ] }; 在webpack中每個(gè)頁面都要有一個(gè)entry,這里index和main就是兩個(gè)頁面的entry,在這個(gè)entry中定義依賴就好了,output中本來還可以指定生成文件的路徑,但我們將路徑放在gulpfile中統(tǒng)一處理 配置中我們用了babel的loader來編譯用es6標(biāo)準(zhǔn)寫的js文件,這個(gè)loader需要前面說到的.babelrc文件來配置 CommonsChunkPlugin的參數(shù): name:chunk名 filename:生成的文件名 minChunks:最小引用次數(shù),一個(gè)依賴最少被引入這個(gè)次數(shù)才會(huì)被加到公共的chunk中 chunks:指定這個(gè)chunk是由哪些頁面構(gòu)成的
好了js處理完了,現(xiàn)在將gulp和webpack結(jié)合起來就好了 在gulpfile中把原來的處理js的task刪掉,添加下面的代碼 var webpack = require('gulp-webpack'); gulp.task('scripts', function(callback) { return gulp.src('src/entry.js') .pipe(webpack( require('./webpack.config.js') )) .pipe(gulp.dest('dist/js')); }); 這樣就大功告成了,鍵入gulp和gulp watch來感受一下吧
項(xiàng)目github地址:https://github.com/jokermask/gulp_webpack_demo
|
|