初探Parcel
昨天趁有点时间看了前不久很火的构建工具Parcel,这里说下初步使用的感受,尤其是将其放到实际项目中和Webpack进行比较。
一、前言
首先说下笔者目前的技术栈。最近的前端项目主要以管理后台为主,技术栈都是React.js + Redux + React-Router + Antd + Create-react-app这套,版本均为较新的版本。Webpack构建工具体系由Create-react-app脚手架初始化,因默认打包功能不太丰富,笔者eject出打包相关的配置文件,在原基础上添加了额外功能:
1. 代码分割与模块异步懒加载
2. 模块按需加载
3. less以及postcss的支持
4. 字体文件的打包
5. JS模块热替换(原始只支持样式的热替换)
6. dev-server(Express)正向代理、代理的destination参数接收、HTTPS的启用以支持h/2协议
前5项考虑到资源大小、首屏性能、样式的兼容以及书写的方便、整体开发的便捷性,是无论在dev或是production环境都会有的。
第6项正向代理是因为笔者这个项目的底层是分布式文件存储系统 + 基于Cluster模块的Node.js集群 + MongDB分片式集群 + HA集群,dev环境是跑在Vagrant Centos7.x虚拟机集群里的,production环境是直接跑在Centos7里的,对操作系统以及机器硬件依赖大。数据流从文件存储系统底层传递到Node.js层再传递到Web前端,且Web前端和Node.js后端只有基于HTTP、Websocket的交互,在开发时出于工程化的考虑,直接和底层环境隔离,进而方便调试,无需到Vagrant起的虚拟机中部署修改后的前端代码,也无需Fiddler或者Charles代理服务端的文件到本地文件,或是依赖Jekins持续集成。只需要Webpack的dev-server代理到Node.js上层Nginx即可,在'npm start'后跟上协议 + 跑有Node.js服务的IP + Node.js进程监听的端口号即可,会将此参数传给dev-server的正向代理配置。
由此可见,如果说你的项目很简单,CLI提供的初始功能即可满足需求,正是如此Facebook在Create-react-app中,直接把最基本的构建有关的文件都放到了node_modules中,只暴露出了命令,使用者根本不需要去维护构建有关的文件。如果说业务需求较复杂会对工程化要求高,如果CLI工具初始化的Webpack打包体系的初始功能不满足业务需求,也是需要额外加入很多东西的,并且需要我们手动去配置。
Webpack的功能确实强大,相对于Browserify来说,Webpack真的是大而全。但类似于字典的API文档和各种loader与plugin运用,无形中提高了整个工具链的技术门槛,对于大多数没有深入研究的开发者来说,只能是知道Webpack的基本用法和要点的概念,再用到具体的loader和plugin的时候再去查看文档,然后过一定时间不使用基本又会忘掉。对于初学者来说而要准确的说出某个loader或者plugin的功能和配置方法是有一定难度的。而且Webpack的每个大版本之间也存在一定的功能和API上的变化,当你熟悉了这个版本后,下一个版本就来了...... 有没有一种"铁杵磨成针"的感觉呢?
目前前端的开发模式、技术栈与工具链基本都相同,为什么不能在构建工具内部就给出能适配大多数业务需求的默认的配置而省去烦人的手动配置呢?所以Parcel号称的零配置的吸引力是很大的。
二、Parcel初探
笔者新起了一个demo项目,但功能复杂度模拟真实项目:
按照Parcel官方要求做了最基础的package.json和.babelrc配置,其他都应用零配置默认的项,不做额外配置。Parcel版本为1.9.3.
index.html为Parcel打包的入口,依赖src/index.js文件。
src文件夹为源资源目录:
src --
|-- components 存放高度抽象的公用组件
|-- redux 存放redux初始化、action、reducer
|-- styleSheets 存放公共和各组件的样式less
|-- views 存放业务视图组件
|-- index.js JS入口文件
路由、代码分割、Antd UI组件按需加载、Redux相关、样式等功能都支持。这是使用Parcel打包过程:
打包后的结果:
这是打包过程中对计算机硬件资源的利用:
用笔记本开发的同学请注意散热...
三、使用Webpack打包同一个项目
笔者再起了一个项目,技术栈和上个段落中的项目相同,但使用前言中提到的Webpack工具链打包该项目。懒得修改index.html的目录,于是新建了public文件夹把index.html放进去,并删除了<script>引入,由'html-webpack-plugin'插件注入JS脚本依赖。
结果如下:
这是打包过程中对计算机硬件资源的利用:
四、有区别处的对比
1. 打包速度
首先当前版本Parcel在速度上绝对比Webpack未使用HappyPack时要快上很多,从计算机CPU使用率可以看出,笔者计算机CPU是i7 4770HQ 4c/8t,在执行Parcel构建时,8个线程均被使用上了,虽然超线程技术产生的额外线程的是引用率并比不上物理核心,但已经很不错了。第二次使用Parcel打包后,可以看到速度较上次还有明显提升,这是因为第一次打包生成了.cache目录的原因,可以记录上一次打包的状态。反观Webpack仅仅只能使用4个物理核心的线程,对核心线程的利用率也并不高,对超线程技术支持不友好,而且耗时很长,拖拖拉拉,当然使用上了HappyPack后会有一定改善。这就是Parcel打包速度快的原因。
2. 打包质量
在零配置下Parcel似乎没有类似于TreeShaking的按需引用技术,而导致打包出来的资源大小要大很多。总所周知,Webpack的TreeShaking能够抖掉引入包中并未真正使用的模块,但是parcel并没有,我们在disk文件夹下的src.js的下,发现了如下代码:
笔者只在代码中引用了Button组件,但是整个Antd UI库的所有组件都被打包进来了,这个srcjs文件异常庞大。如果说我们在loadsh的时候,引入了全部loadash,看在它不大的份上还情有可原,但是整个UI库的引入,导致大小提升到了4Mb,以及和使用Webpack打包出的main.js(200KB)做比较,就难以接受了。
3. 使用场景的支持性
在纯的web前端项目中,Parcel似乎没有什么问题和报错,而当我们打包Node.js项目时,会产生因为有些require写法不支持而报错等问题,当然打包后端醒目可能不是Parcel的目的。而Webpack在这方面做得较好,支持构建的应用较为丰富得多,基本上使用JS的各种项目都支持。
五、通过HappyPack给Webpack打包加速
直接上个代码例子:
没有使用的HappyPack的情况:
使用以后,需要在plugins配置下增加对应的HappyPack实例:
加入HappyPack后,在打包时,CPU使用率较之前高出很多,打包速度有明显提升。
但是笔者在HappyPack实际使用中还遇到了两个问题:
1. 对图片资源的打包,会使图片资源数据被破坏,导致图片资源无法正常使用。这个问题笔者在HappyPack的Github项目Issue里也看到有人提出过,但并没有找到明确的解决办法。
2. 对extract-text-webpack-plugin支持不好,这个插件堪称webpack里面最不稳定的一个插件。
当然以上问题可能和笔者所使用的Webapck有关的loader和plugin自身有关联。
六、总结
Parcel的零配置打包着实让人眼前一亮,但是限制还是很多的,并且为了零配置而抛弃掉了很多灵活配置,导致对打包过程和资源输出有自定义需求的时候还必须自己去修改或者使用额外的插件。那么这样一来岂不是又回到了Webpack等的老路上去了。总之如果没有太复杂的自定义的构建业务需求、也没有引用某些重型UI库,使用Parcel能够让整个打包过程很清爽,反之请使用Webpack。如果觉得Webpack构建太慢,可以使用HappPack增加多进程处理以达到模拟多线程的目的,充分利用计算机CPU超线程技术的功能(如果支持的话)。但HappyPack并不能完美适配所有loader或plugin,这点也不能忽视。当然这也不是必须的,因为又会有谁在不停地打包开发环境的代码呢?而且一般大型项目,也会直接使用CLI脚手架工具搭建环境,像React.js官方的Create-react-app一样,构建相关的文件都没有暴露出来的,提供可以直接使用的'npm start'、'npm run build'等命令。如果你不需要自定义修改,从某种程度来说脚手架工具就是零配置的。新的Webpack4.0大版本也支持零配置,如果你不需要额外的自定义功能的话。
所以Parcel还需打磨,它还不具备让开发者放弃现有构建工具的吸引力。
初探Parcel的更多相关文章
- 初探领域驱动设计(2)Repository在DDD中的应用
概述 上一篇我们算是粗略的介绍了一下DDD,我们提到了实体.值类型和领域服务,也稍微讲到了DDD中的分层结构.但这只能算是一个很简单的介绍,并且我们在上篇的末尾还留下了一些问题,其中大家讨论比较多的, ...
- CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探
CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码 ...
- 从273二手车的M站点初探js模块化编程
前言 这几天在看273M站点时被他们的页面交互方式所吸引,他们的首页是采用三次加载+分页的方式.也就说分为大分页和小分页两种交互.大分页就是通过分页按钮来操作,小分页是通过下拉(向下滑动)时异步加载数 ...
- JavaScript学习(一) —— 环境搭建与JavaScript初探
1.开发环境搭建 本系列教程的开发工具,我们采用HBuilder. 可以去网上下载最新的版本,然后解压一下就能直接用了.学习JavaScript,环境搭建是非常简单的,或者说,只要你有一个浏览器,一个 ...
- .NET文件并发与RabbitMQ(初探RabbitMQ)
本文版权归博客园和作者吴双本人共同所有.欢迎转载,转载和爬虫请注明原文地址:http://www.cnblogs.com/tdws/p/5860668.html 想必MQ这两个字母对于各位前辈们和老司 ...
- React Native初探
前言 很久之前就想研究React Native了,但是一直没有落地的机会,我一直认为一个技术要有落地的场景才有研究的意义,刚好最近迎来了新的APP,在可控的范围内,我们可以在上面做任何想做的事情. P ...
- 【手把手教你全文检索】Apache Lucene初探
PS: 苦学一周全文检索,由原来的搜索小白,到初次涉猎,感觉每门技术都博大精深,其中精髓亦是不可一日而语.那小博猪就简单介绍一下这一周的学习历程,仅供各位程序猿们参考,这其中不涉及任何私密话题,因此也 ...
- Key/Value之王Memcached初探:三、Memcached解决Session的分布式存储场景的应用
一.高可用的Session服务器场景简介 1.1 应用服务器的无状态特性 应用层服务器(这里一般指Web服务器)处理网站应用的业务逻辑,应用的一个最显著的特点是:应用的无状态性. PS:提到无状态特性 ...
- NoSQL初探之人人都爱Redis:(3)使用Redis作为消息队列服务场景应用案例
一.消息队列场景简介 “消息”是在两台计算机间传送的数据单位.消息可以非常简单,例如只包含文本字符串:也可以更复杂,可能包含嵌入对象.消息被发送到队列中,“消息队列”是在消息的传输过程中保存消息的容器 ...
随机推荐
- STM32F1固件库文件讲解与基于固件库新建MDK工程模板
操作系统:win10 1.文件目录 (在cmd下用"cd 文件夹" 进入到要显示的文件夹,如cd d:\en.stsw-stm32054,然后输入tree 回车就会出现上图的目录结 ...
- SSRS报表服务随笔(rdl报表服务)-报表结构与样式
设计rdl报表,比设置HTML页面简单多了,Reporting报表分为页眉,页脚,主体三个部分 rdl文件实际是xml结构的文件,具体是什么语言呢,很抱歉,这点我还不能回复,在我看来,是由固定节点的x ...
- 看板记录工具wekan
wekan 1. 功能 看板工具 2. 安装 环境: centos7.4 安装链接 snap方式 安装脚本(root用户) #!/bin/bash yum makecache fast yum ins ...
- 学习CSS3之实心圆
CSS3是最新版本的CSS,学习后可以更好的用于工作及自己修改自己代码的各种样式. border-radius圆角方法画实心圆.相当于在长方形(正方形)上画半径为边长一半的圆弧. 效果如上图,代码如下 ...
- Java秋招面经大合集
微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...
- 使用bootstrap table 数据绑定
1.最近一直在用bootstrap table 这个前端框架做项目,下面是使用bootstrap table 的一些总结 这个使用.Net 中MVC做的: 2.这个是基本的boostrap table ...
- 【php性能优化】关于写入文件操作的取舍方案
对于使用php对文件进行写入操作有两种方案一种使用 file_put_contents() 和 fopen()/fwrite()/fclose() 两种方案至于应该怎么选,我觉得应该分情况选择,下面是 ...
- MongDB集群容灾方案步骤
MongoDB复制集优/特点支持大数据量.高扩展性.高性能.灵活数据模型.高可用性.同步机制数据复制的目的是使数据得到最大的可用性,避免单点故障引起的整站不能访问的情况的发生,Mongodb的副本集在 ...
- Java提取URL某个参数的值
Java提取Url中某个参数的值. public static String getParam(String url, String name) { String params = url.subst ...
- 阿里云SLB出现502 Bad Gateway 错误排查解决方法
502 Bad Gateway The proxy server received an invalid response from an upstream server. 原本系统是通过一个SLB转 ...