从gulp到webpack-技术笔记

接触gulp是从南洋的分享后开始的,而webpack则是在实践了gulp之后,在开发react程序时开始上手的。两者都是和前端自动化以及工程化相关的工具,可以说在使用上都是十分愉悦的,在很大程度上提高了自己的开发效率;从对于资源的处理上来说,两种工具也各有优势。下面就基于自己对于这两种工具的使用,从简说说我对他们的理解。

gulp

gulp是前端的自动化构建工具,通过gulp可以对资源文件进行检查、压缩处理等操作,同时提供了部署文件生成、启动浏览器自动刷新等功能,实时对资源文件进行自动化的构建,为前端开发提供了便利。gulp的上手难度相比于webpack来说更为简单,主要的一点我认为是在gulp中借鉴了Unix操作系统的管道(pipe)思想,在文件流进入插件进行处理后,输出的文件流可以作为下一个插件的输入进行下一个阶段的处理。(如下图所示)

使用gulp工具的核心文件为 gulpfile.js 文件,通过该文件来构建gulp工具的使用,其中比较核心的API包括下面列出的几个API,将结合实际中的使用来进行介绍:

在上图中展示了gulp工具对于less文件所进行的一些处理,在其中用到了less插件和autoprefixer插件来对文件进行处理并输出,最后又将其引入实时刷新的browserSync插件中进行其他处理。

1. gulp.task(name[, deps], fn) 在gulp中对于task来说每个task定义了一个gulp任务。其中: - name:name也就是上图的"less",定义了gulp任务的名称。(名称中间不应该有空格,如果有空格则不能用命令行运行该任务) - deps:一个任务可以依赖其他的任务,依赖的任务可以在deps中添加,deps是一个数组,里面存储的是这个任务所依赖任务的名称。例如:gulp.task("A", ["B", "C", "D"],fn…)在这代码里面,任务A依赖于任务B、C、D的完成。而任务A的输入流也就是任务B、C、D的输出流,所以我们的任务B、C、D中需要返回当前任务的事件流。 - fn:该函数定义任务所要调用的插件操作,其使用形式通常为:gulp.src().pipe(someplugin())

下面有几点对于task的说明: - 在命令行中采用gulp命令执行工具,默认的情况执行"default"任务 - 在默认情况下,在gulp中的task任务将会以最大的并发数执行,也就是说:gulp会一次性运行所有的task而不做等待。如果需要对task进行序列化操作可以采用依赖或者加入promise等操作来实现。

2. gulp.src(globs[, options]) 该方法说明了需要处理的源文件的路径。如图中所示gulp.src("./src/less/*.less")指定了less文件所在的位置。后面通过pipe方法来piped到其他的插件中进行处理操作。这里我们可以看到在获取到其位置后将其中符合的文件piped到less插件进行处理。 3. gulp.dest(path[, options]) 该函数在使用时,将流pipe进来,并且写文件,重新输出(emits)所有数据。通过这个函数可以将其pipe到多个文件夹。如果某文件夹不存在的时候,将会自动创建它。在上图中我们将其pipe到"./src/css"的位置,也就是输出了css文件。

上面是对gulp中比较核心API的简单介绍,通过基本的了解不难以发现,基于“流式”的输入输出让我们可以很明晰地理解gulp的工作原理,而加之丰富的插件以及简单的使用方法,低成本而高效率地上手gulp为开发带来了非常多的好处。此外,像“browserSync”这样的插件实现了在开发过程中的页面实时刷新,为前端开发带来了完全不同的感受。所以gulp很自然而然地成为了我们在开发过程中对于前端自动化实现时的工具选择。

webpack

在了解完gulp之后,来看看webpack的相关的知识与应用。之所以开始接触webpack,正如前面所说,是在开发react应用的时候,想实现一些像之前采用gulp一样自动化的构建方式来为开发提高效率。而在上网了解相关实现的过程中发现,大部分关于react的实现都和webpack结合在了一起,所以便开始了解webpack的相关应用。 相比于gulp的学习成本来说,webpack学习起来就没有那么的容易了,之所以说不那么容易有这么几点原因:首先,webpack在开始的时候便提供了一个相对模糊的概念图,在开始的理解上不那么的直观。(如下图) 然后由于相关的文档都是以纯英文的方式提供,并且在阅读上比较少提供直接的使用方式,从实践入手比较有难度,而且在代码的复杂度上个人感觉入门是比gulp要难的,所以导致了其学习成本的提高。那下面就以我自己对于webpack的理解和使用来介绍一下webpack这个前端模块加载器。那首先先介绍一下webpack中的一些概念: - 首先在webpack中,所有的资源文件(例如日常开发中的js脚本、css、less或者是图片等)都被当成一个个模块,可以在其他资源文件用进行引用,说的直白一些就是,你可以在你的js里面把css因进去,把你想要的资源模块因进去都是可以的,于是便有了我们上图中的左边哪些模块之间互相依赖的表示。在这里可以顺便提一句为什么我们会把css引入到js中这么奇怪呢?当然这个只是我自己的见解:在采用react进行组件的构建时,组件内部的结构都是在js脚本中的,而如果可以把样式通过模块的方式引入到这个构建的脚本中,就相当于封装了一个react组件。 - 在webpack中对应于不同文件类型的资源有对应的模块leader来对资源进行处理,这里有就一些像之前gulp插件对于各类型文件的处理,不过这里是采用loader来识别各类型的文件,并通过不同的loader来进行。这一些工作在一定程度上可以代替gulp来进行对于前端文件的处理,而在某些方面还存在一些使用便利上的优势。 - 通过webpack来进行对不同文件的依赖的绑定处理,如上图最后可以输出如右边所示的一些静态资源文件,实现我们的打包等工作。 所以webpack的主要工作便如上所属,综合来看,这是个功能强大的工具,从对文件的依赖处理来说,资源模块化让我们对于资源可以有更好的管理方式,而从对于不同文件类型的资源文件来说,各种可扩展的处理方式为其带来了强大的处理能力。下面主要介绍一下关于wabpack的相关知识与应用。 正如在gulp中的构建文件为gulpfile,在webpack中的配置构建文件为webpack.config.js,通过该文件可以构建配置我们的webpack工具。那还是从实际的代码出发来介绍一些其中最基本核心的几个部分。++(在说明中展示的都是基本配置项,通过这些基本配置项可以进行webpack的基础功能的使用,如果需要进行其他功能的集成可以在网上进行其他配置选项的选择)++ 1. entry:在entry中指定了打包的入口文件,其中采用键值对的方式来进行关系的对应。每有一个键值对就是一个入口文件,如下面例子所示:

entry: {  
entry1: './entry/entry1.js',  
entry2: './entry/entry2.js'  
  }
  1. output:在output中配置了打包出来静态资源的路径,具体的配置项可以从下面的代码示例看到:
output: {  
        path: __dirname,
        filename: '[name].entry.js'
    }

在output中我们可以看到定义了path和filename两个配置项。path定义了我们的文件在经过打包之后输出的目录,而filename则配置了我们打包输出文件的名字。通过对output的配置可以帮助我们实现文件打包输出的配置。 3. resolve:在resolve中我们配置了一些解析模块路径时候的配置,其中比较常用的是extensions,通过extensions可以来指定我们模块的后缀,这样在引用模块的时候就不需要再补全资源的后缀名了。如下代码所示:

resolve: {  
        extensions: ['', '.js', '.jsx','.json', '.less'],
        alias: {
          'react': pathToReact,
          'fontAwesome': fontAwesome
        }
  }

在代码中我们可以看到我们在extensions中配置了一些资源文件的后缀名,这样在我们引用这些资源文件的时候就不需要再去引用我们的资源后缀名称了,可以方便我们的操作。另外在alias我们可以看到定义了一些资源的路径,通过这些配置,在我们使用这些资源的时候就不需要把全部的路径补全而直接使用其别名就可以了,也在一定程度上为我们的开发提供便利。 5. module:module是一个重要的部分,在这个地方我们定义了对模块的处理逻辑,也就是对于我们输入的资源模块都会通过这里面的逻辑进行处理。在这里面我们用loaders定义了一系列的加载器,通过这些加载器我们可以对我们的资源模块进行一系列的处理。下面可以通过代码看看具体的使用方法:

module: {  
    loaders: [{
      test: /\.js?$/,
      loader: 'babel',
      query: {
        presets: ['es2015', 'react']
      }
    },{
      test: /\.less?$/,
      loader: 'style!css!autoprefixer!less'
    },{
      test: /\.(gif|jpg|png|woff|svg|eot|ttf)\??.*$/,
      loader: 'url-loader?limit=50000&name=[path][name].[ext]'
    }]
  }

如上面代码所示,我们在loaders里面定义了很多加载器,这些加载器包括babel,css,less等,其中我们根据代码可以看到我们通过test中的正则表达式,在我们需要加载的文件资源匹配了test中的正则就可以调用后面的loader来进行处理。而这也就意味着,相同类型的文件可以通过这些加载器来进行处理上的扩展,丰富的加载器为我们对文件的处理提供了极大的便利,也是webpack工具十分强大的一个方面。 上面便是一些webpack中比较核心的一些内容,通过上面的内容我们也可以看到webpack和gulp之间存在的一些差异,两种工具之间的不同。从个人的使用角度而言,在开发react应用的时候可以明显感受到webpack带来的好处,因为组件化的集成和webpack中资源模块的依赖有一些共通的地方,在理解和资源的组织上提供了很好的管理。而在开发一些平时零散的页面,使用gulp则会有用轻量级的感觉,开发起来的简易程度更佳。而且可以从直观上的感受就是,gulp在处理文件的时候采用的是流这样的概念去处理的,会有更加注重处理的中间过程这样的思想。而在使用webpack来说,更加注重对于资源的管路以及打包过程,所以各有各的侧重点,因此现在也有webpack和gulp结合的使用工具,以后有机会也会尝试这样的操作,而我们现在团队内部的spon工具也是结合了gulp和webpack两者来进行处理,可以到看这种工具的强大之处。 以上便是在学习和使用gulp以及webpack过程中的一些笔记与总结~

悟空

前端开发码农一枚,爱摄影,爱旅游