Express+Less+Gulp配置高效率开发环境

原来用的React+Webpack时,那种同步压缩修改、实时动态刷新页面的感觉真的太棒了。但如果使用Express+ejs+less的话,配置webpack非常繁琐,所以,一番折腾后,于是有了Express+Less+Gulp的配置方案,效果见下图,项目地址:https://github.com/ycjcl868/Express_Gulp

目的

我使用Express+Ejs+Less开发,想开发时对所有资源进行压缩同步到浏览器端,Google搜索一遍,都不是太符合我的项目要求。于是看着Gulp文档结合npmjs.com终于折腾完毕。

配置

下面说下我的配置方法:

我的目录结构:

├── app.js   # Express Server
├── bin
│   └── www  # 启动Server
├── dist     # 编译压缩目录(部署目录)
│   ├── css
│   ├── img
│   ├── js
│   ├── views
│   └── lib  # 第三方库目录(bower安装)
├── .bowerrc # bower前端安装库
├── gulpfile.js  # Gulp配置文件
├── package.json
├── public       # 开发目录 
│   ├── img
│   ├── js
│   └── less     
├── routes
│   ├── index.js
│   └── users.js
└── views      # html
    ├── error.ejs
    └── index.ejs

package.json文件内容:

{
  "name": "voteapp",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "dependencies": {
    "body-parser": "~1.13.2",
    "cookie-parser": "~1.3.5",
    "debug": "~2.2.0",
    "ejs": "~2.3.3",
    "express": "~4.13.1",
    "morgan": "~1.6.1",
    "serve-favicon": "~2.3.0"
  },
  "devDependencies": {
    "browser-sync": "^2.18.6",
    "del": "^2.2.2",
    "gulp": "^3.9.1",
    "gulp-cache": "^0.4.5",
    "gulp-clean-css": "^2.3.2",
    "gulp-concat": "^2.6.1",
    "gulp-ejs": "^2.3.0",
    "gulp-htmlmin": "^3.0.0",
    "gulp-imagemin": "^3.1.1",
    "gulp-less": "^3.3.0",
    "gulp-livereload": "^3.8.1",
    "gulp-nodemon": "^2.2.1",
    "gulp-uglify": "^2.0.0",
    "gulp-watch": "^4.3.11"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

gulpfile.js文件

'use strict';
var gulp = require('gulp');
var minify = require('gulp-clean-css');
var browserSync = require('browser-sync');
var nodemon = require('gulp-nodemon');
var cache = require('gulp-cache');
var uglify = require('gulp-uglify');
var htmlmin = require('gulp-htmlmin');
var imagemin = require('gulp-imagemin');
var less = require('gulp-less');
var path = require('path');
var livereload = require('gulp-livereload');
var concat = require('gulp-concat');
var jshint = require('gulp-jshint');
var cssBase64 = require('gulp-base64');
var del = require('del');

// 删除文件
gulp.task('clean', function(cb) {
    del(['dist/css/*', 'dist/js/*', 'dist/img/*','dist/views/*'], cb)
});

// 压缩ejs
gulp.task('ejs', function() {
  return gulp.src('views/**/*.ejs')
      .pipe(htmlmin({collapseWhitespace: true}))
      .pipe(gulp.dest('dist/views/'));
});

// 压缩less
gulp.task('less', function () {
  return gulp.src('public/less/**/*.less')
      .pipe(less({
          paths: [ path.join(__dirname, 'less', 'includes') ]
      }))
      .pipe(cssBase64())
      .pipe(minify())
      .pipe(gulp.dest('dist/css/'));
});


// 压缩js
gulp.task('js', function () {
    return gulp.src('public/js/**/*.js')
        .pipe(jshint())
        .pipe(jshint.reporter('default'))
        .pipe(uglify({ compress: true }))
        .pipe(gulp.dest('dist/js/'))
});


// 压缩img
gulp.task('img', function() {  
  return gulp.src('public/img/**/*')        //引入所有需处理的Img
    .pipe(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true }))      //压缩图片
    // 如果想对变动过的文件进行压缩,则使用下面一句代码
    // .pipe(cache(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true }))) 
    .pipe(gulp.dest('dist/img/'))
    // .pipe(notify({ message: '图片处理完成' }));
});


// 浏览器同步,用7000端口去代理Express的3008端口
gulp.task('browser-sync', ['nodemon'], function() {
  browserSync.init(null, {
    proxy: "http://localhost:3008",
        files: ["dist/views/*.*","dist/css/*.*","dist/js/*.*","dist/img/*.*"],
        browser: "google chrome",
        port: 7000
  });
});

// 开启Express服务
gulp.task('nodemon', function (cb) {
  
  var started = false;
  
  return nodemon({
    script: 'bin/www'
  }).on('start', function () {
    // to avoid nodemon being started multiple times
    // thanks @matthisk
    if (!started) {
      cb();
      started = true; 
    } 
  });
}); 

gulp.task('build',['clean','less','ejs','js','img'],function () {
    
});

gulp.task('default',['browser-sync'],function(){
  // 将你的默认的任务代码放这

    // 监听所有css文档
    gulp.watch('public/less/*.less', ['less']);

    // 监听所有.js档
    gulp.watch('public/js/*.js', ['js']);

    // 监听所有图片档
    gulp.watch('public/img/**/*', ['img']);
    // 监听ejs
    gulp.watch('views/**/*.ejs', ['ejs']);

   // 创建实时调整服务器 -- 在项目中未使用注释掉
  var server = livereload();
   // 监听 dist/ 目录下所有文档,有更新时强制浏览器刷新(需要浏览器插件配合或按前文介绍在页面增加JS监听代码)
  gulp.watch(['public/dist/**']).on('change', function(file) {
    server.changed(file.path);
  });
});

app.js文件

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'dist/views'));
app.set('view engine', 'ejs');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'dist')));

app.use('/', routes);
app.use('/users', users);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});


module.exports = app;

然后先在根目录下执行安装:

npm install,使用时先运行gulp build将文件压缩、打包、编译,然后再执行gulp开启自动更新服务器

相关推荐

腾讯云上Winpcap网络编程二之环境配置

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏向治洪

React Native开发必备的10个插件包

Sublime Text 具有漂亮的用户界面和强大的功能,例如代码缩略图,多重选择,快捷命令等。Sublime Text 更妙的是它的可扩展性。所以,这里挑选了...

1866
来自专栏云计算教程系列

如何在Ubuntu 14.04上使用Bower管理前端JavaScript和CSS依赖项

Bower是前端模块的包管理器,通常由JavaScript和/或CSS组成。它使我们可以轻松搜索,安装,更新或删除这些前端依赖项。

80
来自专栏一个爱瞎折腾的程序猿

.NET Core+Selenium+Github+Travis CI => SiteHistory

)。 想知道YouTube今天的首页长啥样么?点此查看 想知道YouTube2017年8月31日的首页长啥样么?改天再点开 想为你的网站增加访客么?不要问...

791
来自专栏九彩拼盘的叨叨叨

Chrome 插件收藏

Chrome 上有非常多的功能强大的和插件。这些插件让 Chrome 变得更加强大。下面是我常用的一些插件。

1011
来自专栏lhyt前端之路

pwa+webpack,初探与踩坑0.前言1.webpack2.pwa3.基于webpack的pwa

我们都知道pwa是一个新技术.,依靠缓存,离线了还能正常跑,而且秒开。我把以前原生写的小游戏迁移到react,再迁移到webpack+react,最后再升级到p...

732
来自专栏web编程技术分享

Tomcat的安装配置与JavaWeb入门教程

3225
来自专栏新工科课程建设探讨——以能源与动力工程专业为例

2.3.2 基于bootstrap框架写加法器

    什么是bootstrap?一套用js和CSS编写的框架模板,自己组装一下就可以编写比较美观的网页。官当介绍是组件库:

843
来自专栏Python中文社区

Django 博客教程:建立django工程(连载二)

專 欄 ❈追梦人物,电子科技大学计算机学院研究生,从事大数据分析研究方向。主要使用 Python 语言进行相关数据的分析,熟练使用 django 开发网站系统。...

1966
来自专栏阮一峰的网络日志

我的Tweet档案

很长一段时间,我都想不出它有什么用,140个字可以说什么?大概只有自恋狂,才会把自己的一举一动贴上网,让全世界看到吧!

722
来自专栏MoeLove

利器系列-终端分屏利器 tmux

首先,我们先来了解下终端分屏是什么。顾名思义,终端分屏就是把一个终端屏幕拆解为多个窗口,并且可以进行切换。

632

扫码关注云+社区