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 ...
随机推荐
- Linux上的文件管理类命令都有哪些,其常用的使用方法及其相关示例演示
目录管理命令ls:列出指定目录下的内容格式: ls [OPTION]... [FILE]... -a:显示所有文件包括隐藏文件 -A:显示除.和..之外的所有文件 -l,--long:显示 ...
- 持续集成Gitlab CICD Runner&Jenkins
目录 使用Gitlab Runner实现 再要部署的服务器上安装 gitlab runner 下载可执行文件 设置可执行权限权限 创建用户 运行服务 注册 Runner 到gitlab上找到需要用的U ...
- 代码托管服务平台GitHub
GitHub 可以托管各种 git 库,并提供一个 Web 界面,但与其它像 SourceForge 或 Google Code 这样的服务不同,GitHub 的独特卖点在于从另外一个项目进行分支的简 ...
- python机器学习——使用scikit-learn训练感知机模型
这一篇我们将开始使用scikit-learn的API来实现模型并进行训练,这个包大大方便了我们的学习过程,其中包含了对常用算法的实现,并进行高度优化,以及含有数据预处理.调参和模型评估的很多方法. 我 ...
- PHP判断是否关注微信公众号
PHP判断是否关注微信公众号 1 服务号直接请求这个接口https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140839 su ...
- 连接xshell 时 连不上的问题
最近这一周由于自己的xshell突然连接不到虚拟机,在网上找了很多种方法也没能解决,以至于自己在学习很多知识的时候都没能很好的去验证,去尝试.最后在求助大佬的时候终于将xshell重新连接到了虚拟 ...
- SVN--服务端安装和设置---centos7
一.安装环境 [root@localhost ~]# getenforce Disabled [root@localhost ~]# systemctl disable firewalld 二.yum ...
- 【集合系列】- 深入浅出分析Collection中的List接口
一.List简介 List 的数据结构就是一个序列,存储内容时直接在内存中开辟一块连续的空间,然后将空间地址与索引对应. 以下是List集合简易架构图 由图中的继承关系,可以知道,ArrayList. ...
- Windows服务的删除与添加
Windows服务的删除与添加 以管理员身份运行 CMD 服务的删除 sc delete 服务名称 服务添加 sc create 服务名称 binpath="服务EXE文件所在的目录&quo ...
- requests模块使用代理
1.创建try_proxies.py文件import requestsproxies = {"http":"http:117.135.34.6:8060"}he ...