gulp+webpack+angular1的一点小经验(第一部分gulp与webpack的整合)

  时间匆匆如流水继上周熟悉了gulp的初步安装与环境配置以后,我的项目又进入了新的阶段!
  这篇文章将把我这一周遇到的一些问题,以及解决的方式做一个小小的总结,不一定记的完整,但都是个人的一点经验,分享给大家。有什么错误疏漏还望指正。
  1.angular还是vue?
  这里我是有很大的犹豫的,最后的结果是angular。这里有很多私心,这个项目需要技术上的认同,angular作为一个热门前端框架拥有更大的知名度,这是我选择angular的一部分原因。另外如果详细的对比,团队技术如果从jquery转型,可以尝试接触vue,vue的上手更简单,这里不做展开了。
  2.requirejs还是webpack
  最后的决定是用webpack,因为我requirejs要到浏览器端去进行代码的组织,而webpack在上线之前就把这些做好了,所以性能应该更好。而且webpack可以打包其他类型资源,如css与图片,虽然我现在不打算用这些功能,但能给我留下一些扩展改变的空间。最后requirejs和angular的组合需要引入angular的异步插件,这样让我望而却步。而webpack引入angular只需要一句require('angular');当然,这里边也有些坑,不过都是后话了。
  3.那么现在开始整合吧,先从webpack与gulp的整合开始。
  webpack与gulp的整合(当然前提是安装了webpack,同学们自己去官网查看安装喽),可以通过gulp的一个插件来做,这个插件的名字叫gulp-webpack,名字是不是相当直观?最简单的使用方式如下:
  gulp-webpack的npm文档

gulpWebpack = require('gulp-webpack');
...//stream
.pipe(gulpWebpack(require('./webpack.config.js')))
...//stream

  遇到的坑一个(采用配置文件运行webpack失败),这个链接里有详细的问答: gulp-webpack的坑
  好了,这两个就配置好了,那么项目整合angular之前,我们还有一件事没有做,那就是watch
  对了,watch很重要啊,实时的编译写好的代码,这样才能更有效率的搭建框架,编写代码。
  watch的同时,我们还想要把自动缓存清理的机制加进去。从网上查了,gulp的插件rev配合revCollector可以完成这个任务。这里有一篇很不错的文章
  gulp解决项目部署缓存
  读完之后,我们了解到,这样做对于我的服务器,还不是很完美,因为我没有静态资源服务器啊,而且上面的资源当然也不是永不过期。相反的,如果资源没用我就希望尽快的删掉。从网上看了一些,感觉没有合适我的,于是就需要自己动手删掉。比如编译sass,直接使用rev的流程是这样的:

.pipe(sass.sync().on('error', sass.logError))
.pipe(minifyCss())
.pipe(rename(function(path){
    path.basename=path.basename;
    path.extname = ".css";
}))
.pipe(rev({merge: true}))
.pipe(gulp.dest(distCss))
.pipe(rev.manifest())
.pipe(gulp.dest(distRev+'/css'));

那么在进入rev步骤之前,我们要把服务器上已有的文件删掉,删文件就用del这个命令,需要一个参数,要删掉的文件的路径,我们用这个through2这个命令来获取gulp流中的文件路径,地址稍微手动修改一下,指到编译结果的文件夹里:

var gulp = require('gulp'),
    sass = require('gulp-sass'),
    rename = require('gulp-rename'),
    minifyCss = require('gulp-minify-css'),
    debug = require('gulp-debug'),
    rev = require("gulp-rev"),
    revCollector = require("gulp-rev-collector"),
    through = require("through2"),
    del = require("del");

gulp.task('compile-sass',function(){
    return gulp.src('src/scss/*.scss')
    .pipe(changed(distCss,{extension:'.css'}))
    .pipe(debug({title:'debuging:'}))
    .pipe(through.obj(function(chunk,encode,callback){
        var delPath = chunk.cwd+"/"+distCss+"/"+chunk.relative.substring(0,chunk.relative.lastIndexOf("."))+"-*"+".css";
        console.log(delPath);
        del(delPath);
        this.push(chunk);
        callback();
    }))
    .pipe(sass.sync().on('error', sass.logError))
    .pipe(minifyCss())
    .pipe(rename(function(path){
        path.basename=path.basename;
        path.extname = ".css";
    }))
    .pipe(rev({merge: true}))
    .pipe(gulp.dest(distCss))
    .pipe(rev.manifest())
    .pipe(gulp.dest(distRev+'/css'));
});

gulp.task('revCollectorHtml',function(){
    return gulp.src(['webContent/rev/**/*.json','webContent/index.html'])//注意参数是一个数组,用【】包起来的,要不然会报无法给第二个参数创建cwd属性的错误
    .pipe(revCollector({
        replaceReved:true          //一定要加上这一句,不然不会替换掉上一次的值
    }))
    .pipe(gulp.dest(distBase));
});

这样,watch的任务就变成了:监听文件变化,并在变化以后,将rev-collector任务完成。我们采用异步的策略来做这件事:

var watchScss = gulp.watch('src/scss/*.*',gulpSync.sync([['compile-sass'],'revCollectorHtml']));

我的文件目录结构如下:

│  gulpfile.js
│  karma.conf.js
│  package.json
│  webpack.config.js
│
├─node_modules
├─src
│  │  index.html
│  │
│  ├─js
│  │  │  app.js
│  │  │  index.js
│  │  │  router.js
│  │  │
│  │  └─modules
│  │          appUsedetailModule.js
│  │          listsModule.js
│  │          statisticModule.js
│  │
│  ├─scss
│  │      index.scss
│  │
│  └─tpls
│          
│
├─test
│      testIndex.js
│
└─webContent
    │  favicon.ico
    │  index.html
    │
    ├─css
    │      index-5067f89afc.css
    │
    ├─js
    │      bundle-588100fbe5.js
    │
    ├─rev
    │  ├─css
    │  │      rev-manifest.json
    │  │
    │  └─js
    │          rev-manifest.json
    │
    └─tpls

整个gulpfile.js就变成了这样:

var gulp = require('gulp'),
    sass = require('gulp-sass'),
    rename = require('gulp-rename'),
    minifyCss = require('gulp-minify-css'),
    changed = require('gulp-changed'),
    uglify = require('gulp-uglify'),
    debug = require('gulp-debug'),
    minifyHtml = require('gulp-minify-html'),
    webpack = require("webpack"),
    rev = require("gulp-rev"),
    revCollector = require("gulp-rev-collector"),
    through = require("through2"),
    del = require("del"),
    ngAnnotate = require("gulp-ng-annotate"),
    gulpWebpack = require('gulp-webpack');
var gulpSync = require('gulp-sync')(gulp);


var distCss = 'webContent/css',
    distJs = 'webContent/js',
    distRev = 'webContent/rev',
    distBase = 'webContent';


gulp.task('compile-sass',function(){
    return gulp.src('src/scss/*.scss')
    .pipe(changed(distCss,{extension:'.css'}))
    .pipe(debug({title:'debuging:'}))
    .pipe(through.obj(function(chunk,encode,callback){
        var delPath = chunk.cwd+"/"+distCss+"/"+chunk.relative.substring(0,chunk.relative.lastIndexOf("."))+"-*"+".css";
        console.log(delPath);
        del(delPath);
        this.push(chunk);
        callback();
    }))
    .pipe(sass.sync().on('error', sass.logError))
    .pipe(minifyCss())
    .pipe(rename(function(path){
        path.basename=path.basename;
        path.extname = ".css";
    }))
    .pipe(rev({merge: true}))
    .pipe(gulp.dest(distCss))
    .pipe(rev.manifest())
    .pipe(gulp.dest(distRev+'/css'));
});

gulp.task('compile-js',function(){
    return gulp.src('src/js/**/*.js')
    .pipe(changed(distJs))
    .pipe(debug({title:'debuging js:'}))
    .pipe(through.obj(function(chunk,encode,callback){
        var delPath = chunk.cwd+"/"+distJs+"/bundle-*"+".js";
        console.log(delPath);
        del(delPath);
        this.push(chunk);
        callback();
    }))
    .pipe(gulpWebpack(require('./webpack.config.js')))
    .pipe(ngAnnotate())
    .pipe(uglify())
    .pipe(rev())
    .pipe(gulp.dest(distJs))
    .pipe(rev.manifest())
    .pipe(gulp.dest(distRev+'/js'))
});

gulp.task('compile-html',function(){
    return gulp.src('src/**/*.html')
    .pipe(changed(distBase,{extension:'.html',cwd: ''}))
    .pipe(debug({title:'debuging:'}))
    .pipe(minifyHtml())
    .pipe(rename(function(path){
        path.basename=path.basename;
        path.extname = ".html";
    }))
    .pipe(gulp.dest(distBase));
});

gulp.task('revCollectorHtml',function(){
    return gulp.src(['webContent/rev/**/*.json','webContent/index.html'])//注意参数是一个数组,用【】包起来的,要不然会报无法给第二个参数创建cwd属性的错误
    .pipe(revCollector({
        replaceReved:true          //一定要加上这一句,不然不会替换掉上一次的值
    }))
    .pipe(gulp.dest(distBase));
});

// gulp.task('revCollectorCss',function(){
//  return gulp.src(['webContent/rev/css/*.json','webContent/css/*.css'])
//  .pipe(revCollector({
//      replaceReved:true          //一定要加上这一句,不然不会替换掉上一次的值
//  }))
//  .pipe(gulp.dest(distCss));
// });
function getWatchDelFunc(type){
    return function(event){
        if(event.type==='deleted'){
            var basePath = event.path.substring(0,event.path.lastIndexOf("src"));
            var fileName = event.path.substring(event.path.lastIndexOf("\\")+1,event.path.lastIndexOf("."));
            var delPath = basePath+distCss+"/"+fileName+"-*."+type;
            console.log("watchDelPaths:"+delPath);
            del(delPath);
        }
    }
}

gulp.task('watch',function(){
    var watchScss = gulp.watch('src/scss/*.*',gulpSync.sync([['compile-sass'],'revCollectorHtml']));
    var watchJs = gulp.watch('src/js/**/*.*',gulpSync.sync([['compile-js'],'revCollectorHtml']));
    var watchHtml = gulp.watch('src/**/*.html',gulpSync.sync([['compile-html'],'revCollectorHtml']));
    watchScss.on('change',getWatchDelFunc("css"));
    // watchJs.on('change',getWatchDelFunc("js"));
    watchHtml.on('change',getWatchDelFunc("html"));
});
gulp.task('default',gulpSync.sync([['compile-sass','compile-html','compile-js'],'revCollectorHtml','watch']));

webpack.config.js里只做了最基本的js编译:

var webpack = require("webpack");
module.exports = {
    debug: true,
    watch: false,
    entry: "./src/js/index.js",
    output: {
        path: __dirname+'/webContent/js',
        filename: "bundle.js"
    },
    module: {
        loaders: [   
        ]
    },
    resolve: {
    },
    plugins: [
    ]
}
posted @ 2016-12-06 15:55  拿饭盒当烟灰缸  阅读(219)  评论(0编辑  收藏  举报