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: [
]
}
gulp+webpack+angular1的一点小经验(第一部分gulp与webpack的整合)的更多相关文章
- gulp+webpack+angular1的一点小经验(第二部分webpack包起来的angular1)
又一周过去了,项目也已经做得有点模样了.收集来一些小经验,分享给大家,有疏漏之处,还望指正,海涵. 上周整合了gulp与webpack,那么工具准备差不多了,我们就开始编码吧.编码的框架就是angul ...
- gulp+webpack+angular1的一点小经验(第三部分使用一些angular1的插件ui-bootstrap与highcharts)
第一个要介绍的是我们的麻烦制造器:angular-ui-bootstrap ui-bootstrap可以有很多通用的插件给大家用,比如弹窗啊(modal),翻页控件啊(pagination),为什么说 ...
- 模仿下拉框datalist的jquery插件的一点小经验
原本项目里是用h5的新属性data-list,但是这个下拉框的数据太多,而data-list似乎没有设置高度的地方,所以写了个小插件,期间也发现了一些bug,目前这个版本算是可以一用的版本,故写一下这 ...
- Global一点小经验
Global: Global.asax 文件,有时候叫做 ASP.NET 应用程序文件,提供了一种在一个中心位置响应应用程序级或模块级事件的方法,他位于应用程序根目录下. 这个 Global.asax ...
- KInect AR沙盒制作的一点小经验
最近在微博上看到这样一条 微博 >点这看< 看起来非常有意思,就去Google了一下如何制作. 没想到这是一个开源项目,而且还告诉你如何安装 OK,接下来就说说我的制作过程. 首先,先放 ...
- Web应用程序并发问题处理的一点小经验
在web应用中,一个账户,会有N多个涉及到数字的字段.比如一个账户的金额,积分等.这些字段就涉及到增减的情况.如果是在测试环境下,靠程序员或者测试手动点击.一般是发现不了问题. 一旦上到正式环境下.有 ...
- 关于前端js拼接字符串的一点小经验
1.今天在做项目的时候遇到一个问题,就是使用onclick="xxx()" 点击事件的时候,参数如果为全数字就会出现点击无反应的问题.但是当参数为字符串或者动态内容的时候就会出现 ...
- 【Django】有关多用户管理的一点小经验分享
前言 最近,笔者因为需要开发一个系统作为毕设的展示,因此就产生了有关多用户管理的问题.在这里我把自己的需求重新阐明一下:能够通过Django自带的用户管理框架,实现多用户的管理,例如登录.登出.ses ...
- 关于cnpm的一点小bug
在实际工作中,一个项目完成后,在上线前,常常需要把代码进行压缩,一般是用gulp或者 webpack 进行压缩.(小妹是用gulp) gulp是运行在node 环境下的. 所以首先,下载并安装了nod ...
随机推荐
- day 1 堆 hash 线段树 树状数组 冰茶姬 字典树 二叉查找树
来郑州的第二天,早上开始也没说什么就说了些注意安全,各种各样的注意安全... 冰茶姬: 原来再打食物链时看了一下冰茶姬,只注意了路径压缩,没想到还有什么按秩排序但确实快了不少... int find( ...
- Java面向对象程序设计第15章5
5. 利用URLConnetction对象编写程序返回某网站的首页,并将首页的内容存放到文件当中. import java.net.*; import java.io.*; public class ...
- 网站搭建-windows 系统 本地 网站搭建 - IIS
上一章有提到IIS安装,现在打开它: 点击浏览,如果没有启动的话,先点击启动. ip先选好,第一个吧,本机的(IIS自己提供了初始网页的东西). 然后可以自己去https://www.freemoba ...
- go 学习笔记之咬文嚼字带你弄清楚 defer 延迟函数
温故知新不忘延迟基础 A "defer" statement invokes a function whose execution is deferred to the momen ...
- spark集群搭建(三台虚拟机)——spark集群搭建(5)
!!!该系列使用三台虚拟机搭建一个完整的spark集群,集群环境如下: virtualBox5.2.Ubuntu14.04.securecrt7.3.6_x64英文版(连接虚拟机) jdk1.7.0. ...
- C#winfrom将XML数据保存读取删除
//创建一个数据集,将其写入xml文件 string name = "1.xml"; System.Data.DataSet ds = new System.Data.DataSe ...
- Cesium坐标系及坐标转换详解
前言 Cesium项目中经常涉及到模型加载.浏览以及不同数据之间的坐标转换,弄明白Cesium中采用的坐标系以及各个坐标系之间的转换,是我们迈向三维GIS大门的前提,本文详细的介绍了Cesium中采用 ...
- Ubuntu 16.04 安装Docker
1 更改apt源,更改前先对sources.list文件进行备分 ccskun@test:~$ sudo cp /etc/apt/sources.list /etc/apt/sources.list. ...
- 从无到有实现搭建vue+ElementUI+less+ES6的开发环境并进行简单的开发的项目
项目简介:该项目是基于日常计算宿舍水电煤气费的需求写的,旨在从无到有实现搭建vue+ElementUI+less+ES6的开发环境并进行简单的开发,使用webpack进行代码的编译.压缩和打包,并疏通 ...
- vscode在终端运行脚本时出现“因为在此系统上禁止运行脚本”
首先关闭vscode,再以管理员的身份运行vscode,然后打开终端执行: get-ExecutionPolicy,显示的是Restricted,表示状态是禁止的; 再执行:set-Execution ...