时间匆匆如流水继上周熟悉了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: [
]
}

gulp+webpack+angular1的一点小经验(第一部分gulp与webpack的整合)的更多相关文章

  1. gulp+webpack+angular1的一点小经验(第二部分webpack包起来的angular1)

    又一周过去了,项目也已经做得有点模样了.收集来一些小经验,分享给大家,有疏漏之处,还望指正,海涵. 上周整合了gulp与webpack,那么工具准备差不多了,我们就开始编码吧.编码的框架就是angul ...

  2. gulp+webpack+angular1的一点小经验(第三部分使用一些angular1的插件ui-bootstrap与highcharts)

    第一个要介绍的是我们的麻烦制造器:angular-ui-bootstrap ui-bootstrap可以有很多通用的插件给大家用,比如弹窗啊(modal),翻页控件啊(pagination),为什么说 ...

  3. 模仿下拉框datalist的jquery插件的一点小经验

    原本项目里是用h5的新属性data-list,但是这个下拉框的数据太多,而data-list似乎没有设置高度的地方,所以写了个小插件,期间也发现了一些bug,目前这个版本算是可以一用的版本,故写一下这 ...

  4. Global一点小经验

    Global: Global.asax 文件,有时候叫做 ASP.NET 应用程序文件,提供了一种在一个中心位置响应应用程序级或模块级事件的方法,他位于应用程序根目录下. 这个 Global.asax ...

  5. KInect AR沙盒制作的一点小经验

    最近在微博上看到这样一条 微博  >点这看< 看起来非常有意思,就去Google了一下如何制作. 没想到这是一个开源项目,而且还告诉你如何安装 OK,接下来就说说我的制作过程. 首先,先放 ...

  6. Web应用程序并发问题处理的一点小经验

    在web应用中,一个账户,会有N多个涉及到数字的字段.比如一个账户的金额,积分等.这些字段就涉及到增减的情况.如果是在测试环境下,靠程序员或者测试手动点击.一般是发现不了问题. 一旦上到正式环境下.有 ...

  7. 关于前端js拼接字符串的一点小经验

    1.今天在做项目的时候遇到一个问题,就是使用onclick="xxx()"  点击事件的时候,参数如果为全数字就会出现点击无反应的问题.但是当参数为字符串或者动态内容的时候就会出现 ...

  8. 【Django】有关多用户管理的一点小经验分享

    前言 最近,笔者因为需要开发一个系统作为毕设的展示,因此就产生了有关多用户管理的问题.在这里我把自己的需求重新阐明一下:能够通过Django自带的用户管理框架,实现多用户的管理,例如登录.登出.ses ...

  9. 关于cnpm的一点小bug

    在实际工作中,一个项目完成后,在上线前,常常需要把代码进行压缩,一般是用gulp或者 webpack 进行压缩.(小妹是用gulp) gulp是运行在node 环境下的. 所以首先,下载并安装了nod ...

随机推荐

  1. Linux上的文件管理类命令都有哪些,其常用的使用方法及其相关示例演示

    目录管理命令ls:列出指定目录下的内容格式: ls [OPTION]... [FILE]...   -a:显示所有文件包括隐藏文件   -A:显示除.和..之外的所有文件   -l,--long:显示 ...

  2. 持续集成Gitlab CICD Runner&Jenkins

    目录 使用Gitlab Runner实现 再要部署的服务器上安装 gitlab runner 下载可执行文件 设置可执行权限权限 创建用户 运行服务 注册 Runner 到gitlab上找到需要用的U ...

  3. 代码托管服务平台GitHub

    GitHub 可以托管各种 git 库,并提供一个 Web 界面,但与其它像 SourceForge 或 Google Code 这样的服务不同,GitHub 的独特卖点在于从另外一个项目进行分支的简 ...

  4. python机器学习——使用scikit-learn训练感知机模型

    这一篇我们将开始使用scikit-learn的API来实现模型并进行训练,这个包大大方便了我们的学习过程,其中包含了对常用算法的实现,并进行高度优化,以及含有数据预处理.调参和模型评估的很多方法. 我 ...

  5. PHP判断是否关注微信公众号

    PHP判断是否关注微信公众号 1 服务号直接请求这个接口https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140839 su ...

  6. 连接xshell 时 连不上的问题

      最近这一周由于自己的xshell突然连接不到虚拟机,在网上找了很多种方法也没能解决,以至于自己在学习很多知识的时候都没能很好的去验证,去尝试.最后在求助大佬的时候终于将xshell重新连接到了虚拟 ...

  7. SVN--服务端安装和设置---centos7

    一.安装环境 [root@localhost ~]# getenforce Disabled [root@localhost ~]# systemctl disable firewalld 二.yum ...

  8. 【集合系列】- 深入浅出分析Collection中的List接口

    一.List简介 List 的数据结构就是一个序列,存储内容时直接在内存中开辟一块连续的空间,然后将空间地址与索引对应. 以下是List集合简易架构图 由图中的继承关系,可以知道,ArrayList. ...

  9. Windows服务的删除与添加

    Windows服务的删除与添加 以管理员身份运行 CMD 服务的删除 sc delete 服务名称 服务添加 sc create 服务名称 binpath="服务EXE文件所在的目录&quo ...

  10. requests模块使用代理

    1.创建try_proxies.py文件import requestsproxies = {"http":"http:117.135.34.6:8060"}he ...