初探parcel及如何简单写plugin

前言

入了前端坑,哪有不研究下打包工具的。但本人还是拖了好久才把webpack作了较全面的了解,webpack确实是十分灵活,这得益于其较多的配置项,特别在resolve里,能达成某些奇特的结果。其外,loader解析文件,plugin注入钩子,修改打包过程。可以说,webpack是十分万能,再复杂的项目也能够驾驭。但是,这些复杂的配置,对于初学者是十分不友好的,即使是再简单的项目,还是要写出一个基本的配置项,这时候往往要到官网去复制粘贴,有时忘记的某个配置项的作用,又要重新找(2018/1/15了解到webpack4.0终于要增加默认配置了issue)。即使你是较了解webpack了,但还有各种优化坑等你,不然开发构建慢、打包出来的js块十分大,没有懒加载、无法清理缓存。

前一段时间,parcel出来,号称零配置,开箱即用(其实有时还是要写配置文件,不过是主要是针对某些plugin,如:typescript)。除零配置之外,还号称在某些情况能大大加快打包速度,理由是针对一个文件只会编译一次,即使是由多个plugin,这是使用的AST的好处。还有一个比较符合我们前端的设计,入口文件就是html。

使用

node的版本请必须的8以上,在源码及其他人提供的plugin源码中,都能容易看到对node是否8以上的版本的判断,低于8的话往往是会报错的,因为基本都使用了async的语法。

使用parcel,开发时就基本只需要使用以下两个命令:

  • 开发:
parcel index.html
  • 打包:
parcel build index.html

目前官方已针对各大框架写了例子,还有推荐的各种plugin,地址:awesome-parcel

各例子其实也十分简洁,没有配置项,只是在package.json里帮你加好打包需要的plugin。

再复杂的例子的话,如vue+typescript的话要自己去加plugin,这个我刚好找到一个vue+typescript

想自己从头敲学习的话,可以看这个all-you-need-to-know-about-parcel

编译过程及plugin

对于如此友好的打包文件,当然是要了解下其过程,还有plugin的编写,方便以后确实需要自己去修改plugin或写自己的plugin的时候。

在源码的src里,cli.js是脚本命令入口,在里面会导入真正的编译入口Bundler.js,并构建对象

const bundler = new Bundler(main, command);

打包前bundler.start是一定会运行的,其中就会加载并注册plugin,怎么加载的呢?就是把package.json的plugin依赖都加载了。

let deps = Object.assign({}, pkg.dependencies, pkg.devDependencies);
      for (let dep in deps) {
        if (dep.startsWith('parcel-plugin-')) {
          let plugin = await localRequire(dep, this.mainFile);//加载
          await plugin(this);//注册
        }
      }

所以我们需要什么plugin,只要把其加入到package.json里就好,虽然可以发现放在生产依赖里也行,但这些明显是开发使用的,还是放在开发依赖中比较好,而且优先级也更高,不会被覆盖。

接着我们进入到plugin,官网内置的plugin其实都在parcel-bundler\src\assets里,只是不叫plugin,他们都继承于parcel-bundler\src\Asset.js里的Asset,其中parse方法就给用来自定义编译内容的。

默认会注册以下插件(是根据文件扩展名去使用对应的插件):

this.registerExtension('js', './assets/JSAsset');
    this.registerExtension('jsx', './assets/JSAsset');
    this.registerExtension('es6', './assets/JSAsset');
    this.registerExtension('jsm', './assets/JSAsset');
    this.registerExtension('mjs', './assets/JSAsset');
    this.registerExtension('ml', './assets/ReasonAsset');
    this.registerExtension('re', './assets/ReasonAsset');
    this.registerExtension('ts', './assets/TypeScriptAsset');
    this.registerExtension('tsx', './assets/TypeScriptAsset');
    this.registerExtension('coffee', './assets/CoffeeScriptAsset');
    this.registerExtension('json', './assets/JSONAsset');
    this.registerExtension('yaml', './assets/YAMLAsset');
    this.registerExtension('yml', './assets/YAMLAsset');
    this.registerExtension('gql', './assets/GraphqlAsset');
    this.registerExtension('graphql', './assets/GraphqlAsset');

    this.registerExtension('css', './assets/CSSAsset');
    this.registerExtension('pcss', './assets/CSSAsset');
    this.registerExtension('styl', './assets/StylusAsset');
    this.registerExtension('less', './assets/LESSAsset');
    this.registerExtension('sass', './assets/SASSAsset');
    this.registerExtension('scss', './assets/SASSAsset');

    this.registerExtension('html', './assets/HTMLAsset');

这样就比较明白如何简单写出一个plugin了,首先项目名需要parcel-plugin-
来作开头。

新建自己的asset文件,并导入继承Asset的对象,并编写parse方法;

最后plugin入口index.js:

module.exports = function (bundler) {
    bundler.addAssetType('你针对的文件扩展名', require.resolve('你的asset文件'));
};

最后

parcel的热度确实比当年的webpack高,但目前来看,其生态还不完善,即使是官网推荐的plugin,里面的某些功能也是表示在实验中的,不建议现有比较复杂的项目从webpack迁移到parcel里。比较简单的起始项目推荐去尝试。

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