入手 Gulp 工具流+Webpack模块管理工具

放弃了写了一段时间的 iOS 游戏视频聚合 App 项目,在这过程中使用Python+Flask开发 Restful 的 API 服务端,同时另外单独开发 web客户端,以便以 Hybird 的形式嵌入iOS 的 App 中,这之中开始接触了一些模块化(主要是 javascript)乃至前端工程化的概念。

接下来准备使用Python+Flask开发一个博客程序,准备用于个人使用,完全个人定制。目前的思路是静态资源使用 gulp+webpack 管理,替代之前了解的 sea.js 或者 require.js 做模块化管理。

gulp 与 webpack 简介

gulp 是一款工具流软件,拥有丰富的插件来实现包含但不限于 js/less/sass/html 文件压缩混淆、js/css 错误检查等功能,其官网是Gulp

webpack 是一款资源模块化加载与打包工具,能够管理 js/jsx/css/png 等多种资源的相互依赖以及打包发布,其官网是Webpack

这两款工具均可以使用 npm Node包管理工具来安装,它们之间功能有一定的重叠之处,但仍可以很好的共处。

gulp+webpack 组合实践

在我的项目中,静态资源位于一个专用的 static 文件夹下,因此在此文件夹下做工具的初始化工作。

npm init  
npm install gulp gulp-webpack gulp-less gulp-minify-css gulp-uglify gulp-jshint --save-dev  
touch gulpfile.js  
touch webpack.config.js  

以上命令在当前空间进行初始化,并安装了 gulp、整合于 gulp 的 webpack以及常用的 gulp 插件,同时新建gulpfile.jswebpack.config.js分别作为 gulp 与 webpack 的配置文件。

当前的文件夹结构如下图所示: 文件夹结构

其中:

  • dist - 资源发布根文件夹
  • src - 开发资源暂存根文件夹
  • gulpfile.js - gulp 配置文件
  • package.son - npm包管理配置文件
  • webpack.config.js - webpack 配置文件

gulp 除了使用插件,其本身有 task\src\dest\watch等命令分别实现任务\开发目录\发布目录\文件监控,具体可以留意gulp 中文网教程

为了区分资源,对 src 文件夹进行分支,效果见下图: 文件夹结构2

其中:

  • scripts - js 等脚本文件目录
  • styles - 样式文件目录
  • img - 图片资源目录,放到了样式文件夹下级

另外还在 scripts 以及 styles 文件夹下增加了 utils/plugins/lib 等文件夹,表示工具资源/外部插件资源/外部库资源。

目前 gulp 的主要任务目标有编译 less,js模块化管理,资源压缩以及发布,编辑 gulpfile.js:

var gulp = require('gulp');  
var webpack = require('gulp-webpack');  
var less = require('gulp-less');  
var minify = require('gulp-minify-css');  
var uglify = require('gulp-uglify');  
var jshint = require('gulp-jshint');

gulp.task('default', ['auto-combine'], function () {  
    console.log('default task');
});

gulp.task('less', function () {  
    console.log('start pack less');
    gulp.src('./src/styles/*.less')
        .pipe(less())
        .pipe(minify())
        .pipe(gulp.dest('./dist/styles'));
});

gulp.task('scripts', function () {  
    console.log('start pack scripts');
    gulp.src('./src/scripts/*.js')
        .pipe(webpack(require('./webpack.config.js')))
        .pipe(uglify())
        .pipe(gulp.dest('./dist/scripts'))
});

//自动合并JS,LESS 任务
gulp.task('auto-combine', function () {  
    console.log('execute watch and auto-combine task');
    gulp.watch('./src/scripts/*.js', ['scripts']);
    gulp.watch('./src/styles/*.less', ['less']);
});

//JS代码检查
gulp.task('jshint', function () {  
    gulp.src('./src/scripts/*.js')
        .pipe(jshint())
        .pipe(jshint.reporter());
});

直接执行默认任务时,会自动监控文件的修改并打包压缩发布至 dist 文件夹。

gulp 对 webpack 的使用配置是引用了 webpack.config.js,以下为一个示例:

module.exports = {  
    resolve: {
        root: [process.cwd() + '/src', process.cwd() + '/node_modules'],
        alias: {},
        extensions: ['', '.js', '.css', '.scss', '.ejs', '.png', '.jpg']
    },

    entry: {
        test1: './src/scripts/test1.js',
        test2: './src/scripts/test2.js'
    },

    output: {
        filename : '[hash].[name].js'
    },
}

其中 entry 表示 webpack 资源的入口,它的参数书写形式既可以以字典也可以以数组的形式,以字典形式时,字典的 key 自动作为 chunk 块名,值对应的文件资源即为一个块,以数组形式时,一个数组内的文件将会被合并为一个 chunk,如果不指定 chunk 名,将使用main默认名。

output 为资源输出文件名,文件名可使用固定名称,也可以使用动态解析名称,动态解析参数有[hash] [id] [name],分别是 chunk hash 值,chunk id, chunk名称,这里使用了[hash].[name].js 的形式,这样修改文件并重新发布后并不会覆盖升级,但同样带来的问题是文件在 html 模板引入无法确定,这就需要使用 webpack 的 plugins 参数配置相关工具实现,具体参考webpack-资源路径切换

以上是 gulp 与 webpack 组合的一个浅显例子,接下来随着应用的深入,会发现更多的强大功能。