gulp+webpack構建配置


使用構建工具之前我覺得前端好蠢,css沒有變量,不能寫循環,為了兼容要寫好多前綴,hmtl寫多頁面中有同一個header,我就粘貼復制,然后修改的時候每個都要改。

我還不會壓縮和合並,每次都要按F5刷新。其實這些問題也是網頁優化的問題。

構建工具正是解決這些問題的集合。雖然網上gulp和webpack的教程很多,我還是根據自己的需求整理了一下。

gulp安裝: https://markgoodyear.com/2014/01/getting-started-with-gulp/

webpack安裝: http://webpack.github.io/docs/installation.html

 

基本的需求:

css:要能編譯sass,要壓縮,要能自己補前綴

js:要壓縮,要丑化(就是把變量名換成簡單的字母,即省空間又不容易被看懂),要合並

img: 要壓縮

html:可以引入文件(就解決一開始說的問題,多頁面下共同的組件)

 

gulp中的watch功能可以監聽文件,通過livereload和gulp的監聽來實現保存后自動構建並刷新頁面十分帶感。

 

在給gulpfile之前,先看一下我的目錄結構:

src是生產目錄,就是代碼都是在這了面編寫的

dist是發布目錄,里面裝的就是經過壓縮合並等,構建好的文件目錄

我把html也放在src目錄里了(可能有些人寫在dist中),然后構建的時候在移到dist目錄中,這樣生產和發布的目錄就分離的比較好,你上傳到git上的時候可以只上傳src中的東西

.jshintrc是一個叫gulp-jshint插件對應的配置文件,這個插件是用來檢查你的js的書寫規范和錯誤的,配置是配置它的規則

.babelrc是配置es6的,這個后面再說。

 

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());
});

// 預設任務
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);

});

有幾個插件說明一下:

1.gulp-notify這個插件是用來完成任務后給你一個提示音的,因為如果項目大第一次構建會很慢。

2.gulp-concat插件合並js的時候是沒有順序的,所以我用了gulp-order來解決依賴的問題,比如好多文件依賴jquery

3.gulp-cache插件是緩存img,因為img壓縮很費時間,所以這個插件就是指構建有變更的img

4.gulp-livereload這個插件需要chrome中的插件支持,在chrome瀏覽器中右上角,設置->擴展程序->獲取更多擴展程序 在這里搜索livereload,並下載安裝

   安裝完成后會有這樣的圖標,在要用的時候點一下,讓中間的方形變成實心的就好了

 

編譯sass遇到的坑:

編譯sass使用的是插件是gulp-ruby-sass,之前經常報錯是編碼的問題,后面將項目路徑的中文名改成英文名就解決了問題。

網上還有最終方案是在SASS 項目中 config.rb 配置文件 指定SASS的字符集

encoding = “utf-8” 

出處: http://wuyixiang.sinaapp.com/sass-compass-compile-error/

 

感覺gulp這些功能都蠻不錯,但我其實還有一些需求沒說,是關於js的

1.模塊化(避免命名沖突)

2.要用es6(跟上潮流嘛)

3.js能不能按需加載?比如說我有頁面A和頁面B,他們都依賴一個base.js,然后又分別各自依賴a.js和b.js,這種情況我用剛才的gulpfile打包以后合並出來的一個公共的js是將三個js都包括了,但顯然頁面B不需要a.js,所以當用戶單獨訪問頁面B的時候加載的js就顯得多余了,就多費了流量啊,速度也會慢。

上述的前兩個gulp還是能解決,但是第三個問題好像並不好解決。。。在查找各方資料后我決定用webpack,所以就是其他css,html的部分還是gulp來處理,但是把js交給webpack來處理

 

webpack登場!!

其實使用了es6后就可以用新特性export和import寫模塊化的東西了,所以前兩個需求算是合並了。

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' ;

第三個需求使用webpack中的CommonsChunkPlugin這個插件實現的

這個插件可以把多個html中公共依賴的部分打包成一個和多個公共依賴包(chunk),這樣每個頁面只需要引入這個公共chunk和自己單獨的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中每個頁面都要有一個entry,這里index和main就是兩個頁面的entry,在這個entry中定義依賴就好了,output中本來還可以指定生成文件的路徑,但我們將路徑放在gulpfile中統一處理

配置中我們用了babel的loader來編譯用es6標准寫的js文件,這個loader需要前面說到的.babelrc文件來配置

CommonsChunkPlugin的參數:

name:chunk名

filename:生成的文件名

minChunks:最小引用次數,一個依賴最少被引入這個次數才會被加到公共的chunk中

chunks:指定這個chunk是由哪些頁面構成的

 

好了js處理完了,現在將gulp和webpack結合起來就好了

在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來感受一下吧

 

項目github地址:https://github.com/jokermask/gulp_webpack_demo



 
        
 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM