一个比 webpack 快10倍的打包工具

作为奇舞团的一个小小程序媛,每天都在不断地接受新知识,PostCSS刚学完,PostHTML又出来了。刚研究明白Rollup的配置,又有一个横空出世的打包工具——Parceljs。

我本来是拒绝的,毕竟在这个充满诱惑的年代,我要维持自己内心的纯洁,但当我打开Parcel的官网,看到下面的benchmark数据,我就不淡定了。

居然带缓存的时候比webpack快10倍!!!

虽然是官方给出的单例测试,但是在4个CPU的2016年MPB,拥有1726个模块, 6.5M的未压缩文件的app上跑出这个成绩,简直是令人心动不已!

虽然“又小又快又容易”在自然界中某些场合下并不见得是什么好事,但是在如今的前端领域,这个词简直是对这种解放人类天性的打包产品最好的褒奖!

parcel可以说是将贯彻到极致。一个月前,我由于无法忍受(实际上是因为看不懂记不住)webpack繁复的配置,而拥抱了Rollupjs,然后看到了Parcel之后,估计我又该”移情别恋“了!

据官方介绍,Parceljs拥有这样超快打包速度的原因得益于它开启了多进程打包,并使用文件系统缓存机制,从而提升了重启后重打包的速度。

开始入手

对于parcel,入手过程堪称傻瓜式~

可以使用 Yarn 或者 npm进行安装,对于我们这些年轻的FEer,当然是选择npm了

JavaScript

1

2

3

// 全局安装 parcel

$npminstall-gparcel-bundler

下面就可以开始尝试文件打包了.

Parcel与众不同的一点是,它可以使用任何类型的文件作为入口文件,但是官方推荐是用HTML文件或者是JavaScript文件,如果你在HTML文件中引入了一个相对地址的JavaScript文件,Parcel也会自动给将相对于HTML的地址替换为相对于输出文件的地址,真是超级贴心!

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

// index.html文件

// index.js 文件

console.log("hello world");

如果你的项目没有自己的服务端,感谢Parcel有一个内置的Dev Server👏,你可以使用Parcel提供的这个Dev Server,它会在你修改文件之后自动兼听你的文件改变进行重打包,同样可以配置HMR来加快开发速度。

但是具体怎么添加HMR,这就是后话了,大家收!

当然,如果你的项目有自己的服务端,你可以不使用这个Dev Server,而文件自动监听重打包和HMR也不会受影响。运行下面的代码,你就会在自己目录里面看到一个装满打包好文件的/dist文件夹。

如果你已经为上线做最后一次打包的准备,你可以直接用build模式,Parcel将不会开启监听,只会编译一次!而且Parcel会在生产模式的时候使用 uglify-js ( JavaScript), cssnano ( CSS), 和 htmlnano ( HTML)进行压缩混淆处理。

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

// 没有服务端的时候,启动一个dev server,运行在10086端口

parcelindex.html-p10086

// 开启服务端的时候,开启watch模式

parcelwatchindex.html

// production 模式,没有比上线更令人开心而恐惧的事情了

parcelbuildindex.html

Parcel的食物——Assets

如果说打包工具是一个人的话,那么他吃进去了一堆文件,又输出了一堆文件(这里我用的是输出。。。)。

对于Parcel来说,他的食物其实可以是任何类型的文件,但是Parcel对于JavaScript、CSS和HTML文件有着天生的优秀的支持度。Parcel可以自动分析文件中的依赖,然后将这些依赖打包到最终的输出文件中。

JavaScript

对于最好吃的JavaScript来说,Parcel支持cjs和es6两种语法,他同样可以支持动态import()来异步加载文件,这一点对于之后会谈到的代码分割来说很重要。

JavaScript

1

2

3

4

5

6

7

8

// 使用Cjs引入module

constdep=require('./path/to/dep');

// 使用es6引入module

importdepfrom'./path/to/dep';

对于在JavaScript文件中引入的非JavaScript资源来说,比如CSS,你可以使用import将其引入,他会将所有的同类型文件放在一个另外的单独的打包文件内。对于最终的输出文件来说,这些资源就是一个一个的URL,直接引用就好了,其他的文件类型也是一样的。

而如果你非要坚持inline一个文件的话,就需要你去使用Node.js的fs.readFileSyncAPI了。注意,所用的URL是静态分析的,意味着你不能在URL中拼接变量了,当然__dirname和 __filename除外,对于这些“内部员工”你也没啥办法了!

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

// index.js 中可以这样引入css和其他资源

// 引入CSS文件

import'./test.css';

// 从CSS文件中引入一个CSS模块

importclassNamesfrom'./test.css';

// 引入一个图片文件

importimageURLfrom'./test.png';

// 如果你非要坚持用inline,你只能这么做

importfsfrom'fs';

// 以字符串形式读取内容

conststring=fs.readFileSync(__dirname+'/test.txt','utf8');

// 以buffer形式读取内容

constbuffer=fs.readFileSync(__dirname+'/test.png');

CSS

对于CSS来说,她不光可以被JavaScript和HTML引用,自己也可以使用@import引入其他的CSS资源,这样引入CSS资源的时候,Parcel会将其inline进来。

而在CSS中引入的其他资源,要使用url(),比如图片和字体神马的,Parcel就会将其改为相对于输出文件的路径,但是你写的时候还是要相对于当前的CSS路径的。

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

/* 引入其他css */

@import'./other.css';

.test{

/* 引入一个图片 */

background:url('./images/background.png');

}

对于Parcel来说无论你是炒CSS还是煮CSS。。。我是说无论是LESS, SASS 还是Stylus,他都一视同仁,采取同样的处理方法,从不挑食。

HTML

你可以将HTML视为Parcel的入口,但是他也可以被引入一个JavaScript文件中。对于其中的各种scripts, style, media 的URL,与上面的处理方式是一样的,但是一定要注意,路径是相对于当前文件的!!

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19


Linktoanotherpage


各种转换工具

与很多(你知道的,例如webpack,rollup这样的)打包工具不同,Parceljs天生集成了Babel,PostCSS,PostHTML,只要Parcel发现了这些的配置文件,他就会自动run这些转换工具。

另外一个神奇之处在于,对于一些第三方的node_modles里面发布时带的配置文件,Parcel都可以为他自动开启编译程序,而且只会加载有用东西,所以当你引入一些特定的文件的时候,无需手动而配置和了解他是怎么样子build的,也可愉快地使用了。

代码分割技术

上文中我们提到的动态加载,也就是使用import()来加载依赖,这种新奇的写法在Parcel上有了用武之地。Parcel不需要额外配置,只要他发现代码中有使用import()引入的模块,就会自动的进行代码分割。最终生成的打包文件夹中,就会将这些模块打包成独立的文件,而在主文件中使用URL的形式引入,最后的主文件打包体积更小、加载速度更快~

如果你已经习惯了之前在文件顶部去集中import的话,也不用担心。在Parcel中动态加载是可以进行懒加载的,你可以使用下面的写法。事实上,这些子打包文件,只会在你使用的时候才加载进来,四不四很开心啊!

JavaScript

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

// 建立一个要动态加载的页面名字的索引地图

// 这些页面实际上只会在真正使用的时候去加载

constpages={

about:import('./pages/about'),

blog:import('./pages/blog')

};

asyncfunctionrenderPage(page){

// 懒加载请求页面

constrender=awaitpages[page];

returnrender();

}

想要对动态加载有更深入的了解,可以回翻我们之前的文章,《 chrome63支持动态 import() 》。

🌟注意哦!因为动态加载返回的是一个Promise,所以你是可以用async/await的,但是如果你的浏览器是不支持这个写法的话,一定要使用bable-polyfill(app)或 babel-runtime& babel-plugin-transform-runtime(library)

HMR 模块热替换

HMR(Hot Module Replacement)模块热替换可以说是改变FE生活,拯救懒癌末期患者的福利技术。他会自动更新浏览器端的改变的模块,而不需要重新去reload整个页面,大大提升了开发速度。     据官方称, Parcel的HMR实现支持JavaScript和CSS,而且会在生产模式的时候自动禁止掉。当改动保存后,Parcel会将改变的内容重新打包,并发送一个update的信号通知所有运作的端,比如说你的浏览器。     但是实际我测试结果发现,js的改变应该是可以进行热替换的,但是CSS改变之后,页面并没有反应,如果我想让他有反应的话,就需要配置PostCSS。蜜汁尴尬啊,人家只是想单纯地写一个css而已。。。。

更友好的日志信息

当运行Parcle的时候,终端里面打印的日志中会显示目前打包的进度,以及打包完成所耗费的时间。Mac用户还有一些惊喜的福利,就是会出现一些很可爱的emoji,让等待也不会无聊,比如这样:

当打包遇到问题的时候,Parcel会打印出来带有语法高亮的代码,让你更容易的去进行排错。

总结

总之,Parcel对于一些希望快速搭建项目的人来说,是一个节省时间的方式,这种0配置的打包工具可以极大减轻项目搭建初期的工作,私下称它是“打包保姆”也不为过。

但是如果你想要有些个性化的处理,比如说在rollup中就提供了一个可以将打包文件中的代码排成想要的形状的插件,Parcel可能就无法帮你实现了。想知道我说的这个插件什么,并且对Rollup有更深入的了解的话,你可以去我的PPT看一看,rollup 小巧又有趣打包工具-声享: https://ppt.baomitu.com/d/e0af330f

下面我精选了一些知乎上对于Parcel的评价,如果侵犯了答主的著作权,可以在奇舞周刊的后台联系我~

陈成

链接:https://www.zhihu.com/question/263676981/answer/272172727

看到 ParcelJS 还是眼前一亮的。新建 index.html、index.js 和 index.css,然后 parcel index.html,就能拿到可运行的 html、js 和 css 组合。html 可以作为入口正是我期望的,这让前端开发回归到本来的状态,很舒服。

ParcelJS 是以 assets 方式组织的,assets 可以是任意文件,所以你可以构建任意文件。而在 webpack 中,只有 JS 是一等公民(webpack@4 会增加 CSS 为一等公民),所以必须是以 JS 为入口去组织其他文件,这很别扭。

速度是 ParcelJS 主要卖点。体验下来确实快,原因是多核(通过 worker 平行构建)和文件系统缓存(二次构建会快,和 webpack 的 dll 异曲同工)。不过 webpack 也有多核处理 loader 和压缩的插件,没对比过,不知道差异如何。另外 webpack 的构建速度慢在 dev 模式下还是可以的,主要还是压缩慢,在压缩速度上没有突破,仅提升编译速度,只能解决一部分问题。

关于 0 配置。ParcelJS 本身是 0 配置的,但 HTML、JS 和 CSS 分别是通过 posthtml、babel 和 postcss 处理的,所以我们得分别配 .posthtmlrc、.babelrc 和 .postcssrc。功能上,Code Splitting 和 Hot Module Replacement 没啥新的,和 webpack 等工具相同。

对于我来说,功能目前还缺 SourceMap、公共文件提取、publicPath 配置(Code Splitting 需要)、Tree Shake 和 Scope Hoist 等。很好的开始,持续维护的话应该不缺用户。

周左左

链接:https://www.zhihu.com/question/263676981/answer/271919415

但是对于打包工具来说速度不是最首要的,生态才是。

下面从实践出发谈谈我个人对打包工具的理解

曾经

打包工具的出现,很大程度上缓解了传统的手动引入资源文件(css, js等)到html带来的不便。从。从最初的require.js模块加载库以及相关规范出现开始,社区就开始进行各种尝试。到gulp利用pipe以及watch概念来构建前端自动化流程,之后引入了browserify打包作为构建工具中的一环,最终到了现在webpack集大成者。

webpack当年首先是作为一款与browserify功能相当的打包工具/库,出现在社区中的。所以你会常常看见社区里的教程/问答贴:gulp + webpack或是gulp + browserify。当然还有但是风韵犹存的grunt,以上组合可以自行想象。

之后webpack重点开发了自身作为一个构建工具的作用,而不是仅仅作为一个打包库寄人篱下。在这之前,我们都没见过打包工具需要去监听文件变动而触发打包动作(例子一个),他们都只是从gulp/grunt这种构建工具的pipe来获取到具体变化,再去执行打包动作。所以一句话,像监听变化、assets资源优化等等这种事情,在以往打包工具/库是触及不到的。打包工具只针对js作为入口文件,递归获取依赖,建立依赖树,逐个利用自带的或第三方的中间件来最终输出bundle js。

当下

刚刚提到webpack不满足于自己仅仅只是一介打包工具而存活于世,或是说社区本意就是将它打造成为一款前端项目构建工具。webpack推出了一系列的功能,渐渐发觉,gulp能做的事情,现在webpack都能做到了,甚至还多了一系列的gulp配合打包库才能做到的功能。Parcel无配置,从assets出发的构建工具,崭露头角。

我超喜欢在webpack的 个个loader、plugin都是人才说话又好听

未来

未来肯定是属于操作简单便捷的构建工具的,它要能支持js、html、css三剑客的打包,速度足够快,生态够好。但是依然要有定制性:

1.一半是传统多页面应用,一半是SPA的业务场景。

2.添加各种稀奇古怪的js语言。

3.针对css进行优化,像js那样能够提取出common chunk。webpack 4添加了许多特性对css打包进行了支持。我们拭目以待。

4.针对业务进行分组打包,而不是所有的entry都要强制打包(目前可以利用多config特性来解决,但是要小心webpack-dev-server的坑)。

思考:针对场景的配置成本

如果你要使用react,就用create-react-app,如果你要使用angular,就用angular-cli。

但是如果你不用前端框架,或者嫌这些cli太重了,或不透明(其实不然),当然可以用parcel。

但是如果你又要引入typescript或者一些其他神奇的plugin到parcel中,那么又成了铁头娃、填坑侠。


+群289683894领取资料,交流学习

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容

  • 无意中看到zhangwnag大佬分享的webpack教程感觉受益匪浅,特此分享以备自己日后查看,也希望更多的人看到...
    小小字符阅读 8,084评论 7 35
  • 版权声明:本文为博主原创文章,未经博主允许不得转载。 webpack介绍和使用 一、webpack介绍 1、由来 ...
    it筱竹阅读 10,933评论 0 21
  • 在现在的前端开发中,前后端分离、模块化开发、版本控制、文件合并与压缩、mock数据等等一些原本后端的思想开始...
    Charlot阅读 5,391评论 1 32
  • 写在开头 先说说为什么要写这篇文章, 最初的原因是组里的小朋友们看了webpack文档后, 表情都是这样的: (摘...
    Lefter阅读 5,234评论 4 31
  • 最近在学习 Webpack,网上大多数入门教程都是基于 Webpack 1.x 版本的,我学习 Webpack 的...
    My_Oh_My阅读 8,096评论 40 247