gulp+webpack構建配置

gulp+webpack構建配置

使用構建工具以前我以爲前端好蠢,css沒有變量,不能寫循環,爲了兼容要寫好多前綴,hmtl寫多頁面中有同一個header,我就粘貼複製,而後修改的時候每一個都要改。css

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

構建工具正是解決這些問題的集合。雖然網上gulp和webpack的教程不少,我仍是根據本身的需求整理了一下。前端

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

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

 

基本的需求:android

css:要能編譯sass,要壓縮,要能本身補前綴webpack

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

img: 要壓縮git

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

 

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



 
 
 
 
分類:  js, node
相關文章
相關標籤/搜索