干货分享丨达观数据基于webpack实现web工程

01

引言

随着互联网前端技术的发展,在前端工程愈发复杂多变的今天,模块化已经变成了前端从业者津津乐道的话题,各种模块化工具层出不穷。seajs, requirejs,bower,browserify 以及我们今天所要提到的一款前端模块化工具—webpack。达观数据的前端技术选型中也时常选用webpack作为模块化管理工具。

图1 webpack

02

什么是webapck

Webpack从诞生到现在也有些年头了,现在已经更新到2.0版本了。它是一款优秀的模块加载器兼打包工具,其最大的特点是视一切资源为模块,可以把任何形式的资源都视作模块并引入到工程中,如commonJs模块,AMD模块,Sass, Less, Json, img,es6模块(2.0版本添加支持)等等。并且,你可以通过module, plugins等参数对依赖的模块进行整合打包,可以替代一部分gulp, grunt类似的打包功能。(施列宇 达观数据)

图2 modules with dependencies

03

为什么要用webpack

webpack作为一款模块管理器有着自己独具的优势。首先就是上一段提到的,webpack会把任何形式的资源都当做模块进行打包,传统的模块加载器仅仅针对js,webpack可以对任何形式的资源进行打包,使得项目管理起来更加的方便。

其次,webpack对AMD/CMD的模块加载模式都能兼顾,可以按个人的喜好选择模式进行模块依赖管理。

再者,webpack可以替代一部分gulp/grunt的工作。他的loader机制可以实现一部分压缩混淆的操作。

04

如何使用webpack

笔者准备的是一个单页demo,此处首先列一下目录结构,仅做参考。

├── dist #发布目录

├── package.json

├── src #工程源码

│ ├── assets #静态资源

│ ├── index.html

│ ├── index.js #入口文件

│ ├── js

│ ├── styles

│ └── utils #工具库

└── webpack.config.js #webpack配置文件

1安装

在项目的根目录下运行

npm init

npm install -D webpack

创建webpack配置文件webpack.config.js

2配置

一个webpack配置主要包含entry, output, modules, plugins和resolve这几类字段。

entry定义了文件的入口配置,output对应的是项目的输出配置。(如图3所示)这里的filename使用了hash字段添加hash后缀,解决因缓存导致的页面内容不更新的问题。

本文所提供的例子是单页模式,所以并没有多个入口。如果有多个入口的需求,可以通过以下的形式(图4)生成。编译后,代码会在outputDir目录下生成多个文件的bundle.js。

图3 webpack entry/output配置

图4 webpack 多入口的entry/output配置

Loaders是webpack.config中的核心内容。它规定了每个模块使用哪种加载器来处理。具体配置如图5所示。可以观察到,loaders包含了很多个loader, 每个loader会使用test字段匹配文件名,如果符合其正则,那么可以通过loader字段对该文件进行加载。所有的加载器都需要使用npm进行安装。例如:如果我想使用css-loader,那么在根目录下运行npm install css-loader -D即可安装对应的loader,不用把loader通过require的方式引入,webpack自己可找到对应的加载器。然后在loader字段中写明loader: ‘css-loader’,这里的‘-loader’可以省略不写。文件也有可能会使用多个加载器,使用!进行分隔,多个loader加载的执行顺序是从右向左,在实际操作过程中需要注意这一细节。涉及到参数的字段使用?进行添加,使用’&’进行分隔多个参数。

图5 webpack loader配置

Loaders功能固然强大,但也有很多事情不能通过loaders实现。例如,webpack的loader默认会把所有的文件都打包到一个bundle中,而实际的项目中为了网站的性能,html、css、js等资源一般都是需要分开并有选择的进行异步加载的。这时候就需要plugins在上线过程中进行一些处理了。在此,介绍一些常用的plugins。(施列宇 达观数据)

图6 webpack plugins配置

HtmlWebpackPlugin,用于创建服务wepack打包的bundle的HTML文件。该插件需要安装npm依赖html-webpack-plugin,并通过require引用进来。ExtractTextPlugin,用来从bundle中剥离css的插件,一般在生成线上版本时加入到plugins中。需要通过npm 来安装extract-text-webpack-plugin依赖。UglifyJsPlugin,用于压缩混淆打包生成的bundle文件。这个plugin是webpack内置的,将webpack require进来后,通过webpack.optimize.UglifyJsPlugin进行调用。OptimizeCssAssetsPlugin,用于压缩css文件。需要安装npm依赖optimize-css-assets-webpack-plugin。

Resolve是用来简化模块配置的一项。其中比较常用的字段有alias, extensions等。alias定义模块别名,避免出现依赖名称过长的引用。 extensions定义默认的扩展名,webpack默认忽略的扩展名是.js,也就是说在项目中你可以通过require(‘js/index’)即可获取到js目录下的index.js文件,而通过extensions,你可以设置更多可以识别的后缀。(施列宇 达观数据)

图6 webpack resolve配置

3命令行设置

写好了webpack.config.js后,我们可以在根目录下运行webpack命令,即可实现webpack的工作流。这里顺便提一下webpack命令常用的一些参数。

-colors 输出带颜色的命令

-progress 输出打包显示

-watch 动态监测依赖文件变化并进行更新

-hot 热插拔

-p 对打包的文件进行压缩

在实际项目中,如果有gulp/grunt一类的工具,可以使用gulp/grunt的自身机制设置不同运行环境。如果没有此类工具,也可以选择将命令封装到npm scripts中。如图所示,按照这种方式进行设置,只需要运行npm run + 关键字,即可运行对应的命令,避免了在调试过程中频繁的输入大量 的字符和参数。

图6 npm scripts设置

05

webpack的图片加载

图片资源引用方式多变,在使用webpack的过程中,不同场景下的图片引用往往会困扰着初学者。这里简单介绍一些webpack的图片处理方式。

一般来说,webpack中的图片都可以通过url-loader来实现加载(图7)。这里主要针对js和css文件中依赖的图片资源。(施列宇 达观数据)

图7 通过url-loader实现webpack对图片的加载

url-loader也是一个很实用的loader,它可以对图片资源进行筛选,当图片很小时,url-loader可以选择将图片编译成base64格式放进bundle文件中;也可以实现给图片添加hash码等等。如果图片是通过js代码进行加载,需要注意的是,图片资源必须要用require的方式进行引用,否则webpack不能识别相应的图片。

图8 使用require进行图片加载

如果图片是通过scss/css进行加载。首先,也图片也必须通过入口文件将图片添加至依赖中。这样即使图片路径有发生变动,webpack也会在后续的处理中将css中对应的路径进行替换。

对于html中的图片处理方式,首先是webpack对于多html的支持并不好,进而导致相关页面中的图片路径问题很难解决。如果是使用webpack+react的多入口方式进行项目搭建,react的自身特性决定了它可以通过require的方式解决此类问题。但如果不是react页面我们应该如何处理呢?

笔者在这里向大家推荐一个插件html-withimg-loader。安装了html-withimg-loader后,在入口文件中require相应的html文件,webpack即可识别html中对应的img标签了。

图9 在入口文件中添加含img元素的html

如果图片希望在入口html中也想识别图片资源,可以使用HtmlWebpackPlugin插件中的template字段对其进行设置,在template中补充相应的loader,即可完成配置。

图10 使用html-withimg-loader插件对入口html添加图片依赖

06

总结

webpack是一款十分优秀的模块管理器。它语法易懂,配置简单,可以实现高效快速的搭建前端工程。在实际项目中,webpack的运用已不鲜见。尤其是react框架一经推广后,react好搭档webpack的地位也日益提升。本文从多个角度对webpack进行了阐述,相信读者在阅读完后定能有所收获。

原文发布于微信公众号 - 达观数据(Datagrand_)

原文发表时间:2017-05-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏PHP在线

3种web会话管理的方式

http是无状态的,一次请求结束,连接断开,下次服务器再收到请求,它就不知道这个请求是哪个用户发过来的。当然它知道是哪个客户端地址发过来的,但是对于我们的应用来...

21330
来自专栏小白安全

绕过Edge、Chrome和Safari的内容安全策略

概述 ---- Web应用中有许多基本的安全机制,其中一个是同源(same-origin)策略机制,该机制规定了应用程序代码可以访问的资源范围。同源策略的...

44570
来自专栏卡少编程之旅

手机adb命令学习

40080
来自专栏北京马哥教育

10个方法助你轻松完成Linux系统恢复

在Linux中有一些应用程序可以帮助你保存系统快照。大多数应用程序都是针对于新手的,并不需要高级的Linux操作技巧。我们在这里挑选了10个,你可以从中选择适合...

58450
来自专栏个人分享

RPC远程过程调用协议

  最近学习Hadoop、Hbase、Spark及Storm原理,经常会出现RPC这样的传输术语,为了更好地理解,将知识点详细的整理下吧~

51540
来自专栏数据和云

运维经验:回滚段异常的特殊救急方法

? 冷菠 冷菠,资深DBA,著有《Oracle高性能自动化运维》,有近10年的数据库运维、团队管理以及培训经验。擅长数据库备份恢复、数据库性能诊断优化以及数据...

46190
来自专栏LEo的网络日志

工作中的小技巧分享

36690
来自专栏网站设计制作、数字营销

做网站知识之域名解析易懂介绍

公司在做网站时,在购买了域名、主机空间、及网站源代码和数据库都做好了之后,如果网站备案通过了,就可以做域名解析,如果解析设置没有问题,10分钟之后网站就可正常打...

35540
来自专栏程序猿DD

使用Consul做服务发现的若干姿势

来源:http://blog.bossma.cn/consul/consul-service-register-and-discovery-style/?hms...

1.1K40
来自专栏后端技术探索

Nginx如何做流量控制

英文原文:https://www.nginx.com/blog/rate-limiting-nginx/

68140

扫码关注云+社区

领取腾讯云代金券