【Parcel 2 + Vue 3】从0到1搭建一款极快,零配置的Vue3项目构建工具

2,277 阅读15分钟

前言

一周时间,没见了,大家有没有想我啊!哈哈!我知道肯定会有的。言归正传,我们切入正题。上一篇文章中我主要介绍了使用Vite2+Vue3+Ts如何更快的入手项目。那么,今天我将会带领大家认识一个新的Vue3项目构建工具——parcel-vue-cli。这是什么?怎么以前没有听说过。有这样的疑问其实并不奇怪,因为这个构建工具是我自己开发的。你可能会这样问:“你自己开发的?这么厉害吗”?是的,豆哥其实就这么厉害。开玩笑啦!其实没有你想得那么厉害。都是搬砖人,主要看思路。好,不扯了!本篇文章我将带大家如何从0到1开发一款极快,零配置的Vue3项目构建工具(parcel-vue-cli)。名字就这么记着吧!

实战

既然,从0开始,那么我们肯定需要先了解parcel 2是什么东东?

一、介绍Parcel 2

了解Parcel 2之前呢,你得知道它上一个版本Parcel 1是啥。这是官方网址:https://parceljs.org/ 官方是这样介绍它的:

Blazing fast, zero configuration web application bundler

极速、零配置的web应用捆绑包。 我们这里就简单地介绍下它的几个特性。

  1. Parcel使用工作进程来启用多核编译,并且有一个文件系统缓存,即使在重新启动后也可以快速重建。
  2. Parcel提供了对JS、CSS、HTML、文件资产等的现成支持—不需要插件。
  3. 当需要时,代码会使用Babel、postss和posthml自动转换,甚至是node_modules
  4. 使用动态import()语法,Parcel拆分输出包,以便只在初始加载时加载所需的内容。
  5. 在开发过程中进行更改时,Parcel会自动更新浏览器中的模块,无需配置。
  6. Parcel在遇到错误时打印语法高亮显示的代码帧,以帮助您确定问题。

看完这些特性之后,是不是感觉跟Vite很相似。https://parceljs.org/getting_started.html这是文档地址,如果还有小伙伴没有接触Parcel的,那么推荐你赶快试试去。今天,我们就不过多地介绍Parcel 1了,主要是为了抛砖引玉,为了咱的主角Parcel 2。Parcel 1都这么强大了,那么Parcel 2不就更厉害了吗?别急!听我细细道来。

如果你在找Parcel 2的官网怎么也没找到,那就对了。https://github.com/parcel-bundler/parcel/tree/v2,你可以打开Parcel 2的github网址。我们滑到Features一栏,你会发现介绍的跟Parcel 1一样,我去~ 还能再懒点吗?整出来一个2,特性介绍还跟1一模一样。莫着急,我们往下看会看到一段文字:

Below is the design document that was created before work on the implementation of Parcel 2 started and some sections are outdated. The actual (somewhat complete) documentation for Parcel 2 is available here: v2.parceljs.org/.

以下是在开始实施Parcel 2的工作之前创建的设计文档,并且某些部分已经过时。 此处提供了包裹2的实际(有些完整)文档:v2.parceljs.org/.

踏破特写无觅处,得来全不费工夫。原来官网在这里,我们毫不留情地打开了它。

截屏2021-03-29 21.46.03.png

Parcel是所有代码的编译器,无论使用哪种语言或工具链。Parcel会获取您的所有文件和依赖项,进行转换,然后将它们合并到较小的一组输出文件中,这些文件可用于运行代码。Parcel开箱即用地支持多种不同的语言和文件类型,从HTML,CSS和JavaScript等网络技术到Rust等低级语言,以及任何可编译为WebAssembly(WASM)的东西,再到图像,字体,视频,和更多。包裹使您的代码可移植。您可以为不同的环境,服务器的Web或应用程序构建代码。您甚至可以一次建立多个目标,并在进行更改时实时更新它们。包裹快速且可预测。它在worker内部并行隔离地编译所有文件,并在运行时将所有文件缓存。缓存在计算机之间是稳定的,并且仅受项目中文件和配置的影响(除非您要传递特定的环境变量)。

这是官方对Parcel的解释,总之一点,记住它是一个web应用捆绑包就可以了。我们先不看侧边栏菜单那些内容,先看看Parcel 2到底更新了啥?肯定不只是那些特性。我们打开顶部Blog栏,也就是这个网址https://v2.parceljs.org/blog/alpha1/, 也就是Parcel 2.0.0-alpha.1 。我们会看到下方这样介绍。

截屏2021-03-29 22.08.41.png

Today I’m incredibly excited to release the first alpha version of Parcel 2! Please try it out and help us take Parcel 2 to the finish line. Check it out on Github!

今天,我非常高兴地发布Parcel 2的第一个Alpha版本! 请尝试一下,帮助我们将包裹2送到终点线。 在Github上查看!

看了看日子,是2019年-09-13年推出的,这日子到现在一年多了。看看到底更新了啥?

Parcel 2是对Parcel的彻底改写,我们已经进行了一年多的研究,在此之前进行了将近一年的设计。 它融合了我们从一开始就学习构建Parcel所学到的一切,其结果比Parcel 1更具扩展性,可扩展性和可靠性,同时保留了您对Parcel期望的易用性和开发人员经验。

看到这样的解释,是不是很迫不及待了。不要着急,我们再往下看。

  • Parcel 2从头到尾都是完全可扩展的。插件类型已经扩展,可以通过易于配置的管道扩展和覆盖几乎所有核心行为。尽管默认设置包括包裹1(及更多)中的所有内容,但现在您可以根据需要自定义和扩展几乎所有内容。
  • Parcel一直利用并行性和缓存来扩展到大型应用程序,而在Parcel 2中更是如此。我们现在可以缓存和并行化Parcel的更多工作,因此您可以期望更快的构建,尤其是缓存的构建。我们还保留了更少的内存,因此Parcel 2可以扩展到更大的应用程序。
  • Parcel 2提高了缓存的可靠性,同时将性能最大化。我们利用全新的跨平台文件系统监视程序,即使Parcel未运行,该监视程序也可以检测粒度文件的更改。同时,我们的资产图可以超精细地失效,这意味着缓存的构建几乎具有与监视模式完全相同的性能!

Parcel 2是可配置的。 Parcel 2 CLI内置的默认配置足以满足大多数应用程序的需求,并包括Parcel 1支持的所有功能以及更多功能,但是Parcel 2支持通过专门为每个Parcel核心设计的一整套插件类型,通过其他功能扩展核心阶段。

下面还有很多特性解释,我这里因为篇幅的原因,就不过多解释了。其实我看来,最具特色的更新是TransformersTransformers将代码和其他资产从一种语言编译成另一种语言,或者只是以某种方式转换文件。 例如,TypeScript转换器将TypeScript编译为JavaScript,而Babel转换器将JavaScript转换为其他JavaScript。 转换程序还负责从代码中提取依赖项,例如import语句和要求调用,这些依赖关系将传递回解析器,另一个转换程序,依此类推,直到为应用程序构建完整的资产图。另外,为什么重点说Transformers呢?是因为本篇文章使用了@parcel/transformer-vue,在这里解释Transformers有助于下面理解。

看完了第一个Alpha版本!我们来看第一个Beta版。

截屏2021-03-29 22.00.08.png

  • Improved tree shaking (改进的树状摇动)
  • Faster source map generation (source更快的源地图生成)
  • Improved content hashing (改进的内容散列)
  • Resolver diagnostics (解析器诊断)
  • More accurate bundle reports (更准确的捆绑包报告)
  • Tons of bugfixes and improvements (大量的错误修正和改进)

这是Parcel 2的第一个beta版本。这意味着它比每晚或alpha版本更稳定,但是在完全稳定的版本发布之前,仍需要进行一些更改。 特别是,beta表示我们不打算更改大多数面向用户的API。例如配置格式(在package.json和.parcelrc中)和CLI参数。

二、入门Parcel 2

我们从这里开始https://v2.parceljs.org/getting-started/webapp/,从如何安装Parcel 2。

yarn add -D parcel@next

OR

npm install -D parcel@next

我们可以这样使用它,当然这里是以React.js项目为例,你还可以安装其他语言。

package.json

{
  "name": "my-project",
  "scripts": {
    "start": "parcel serve index.html",
    "build": "parcel build index.html"
  },
  "dependencies": {
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  },
  "devDependencies": {
    "parcel": "next"
  }
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>My Parcel Project</title>
  </head>

  <body>
    <div id="root"></div>
    <script type="module" src="./index.js"></script>
  </body>
</html>

index.js

import React from "react";
import { render } from "react-dom";

render(<h1>Hello World</h1>, document.getElementById("root"));

在上面的示例中,您可以看到两个命令,开发命令parcel serve index.htmlparcel build index.html用于创建生产版本。

示例中的命令以index.html作为入口点,而不是JavaScript文件作为入口点,这与其他捆绑程序不同。 使用HTML文件作为入口点使Parcel易于使用,因为它可以直接从HTML文件中检测依赖关系,并将所有检测到的依赖关系自动捆绑到各自的捆绑包中,而无需进行任何配置。 Parcel甚至可以自动执行更高级的功能,例如差异服务和编译内联脚本和样式,而无需任何配置。

这里是不是跟Vite很相似呢!

三、使用Parcel 2搭建一个Vue3项目

既然觉得跟Vite这么相似,那么我们要不也搭建一个项目构建工具?首先,我们来到了这里https://v2.parceljs.org/languages/vue/。惊奇的发现这样一段话:

Note that Parcel does not support using SFCs with Vue 2, you must use Vue 3 beta or later.

请注意,Parcel不支持在Vue 2中使用SFC,必须使用Vue 3 beta或更高版本。

既然都这么说了,我们就用Vue 3。官网说,Parcel支持Vue,而无需任何其他配置。顿时爱了!

截屏2021-03-29 22.52.43.png

话不多说,我们开始开发。

我们参照VueCLI的项目目录开始创建文件以及文件夹。(我会在文末放出源码地址,我这里先给出大概的文件目录)

截屏2021-03-29 23.07.54.png

我们来直接看package.json文件。

{
  "name": "parcel-vue-app",
  "version": "1.0.3",
  "description": "Blazing fast, zero configuration vue application bundler.",
  "keywords": [
    "parcel",
    "vue"
  ],
  "private": false,
  "author": {
    "name": "maomincoding",
    "email": "17864296568@163.com",
    "url": "https://www.maomin.club"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/maomincoding/parcel-vue-app.git"
  },
  "license": "MIT",
  "engines": {
    "node": ">=14"
  },
  "source": "src/main.js",
  "targets": {
    "index": {
      "includeNodeModules": {
        "axios": true,
        "vue": true,
        "vue-router": true,
        "vuex": true,
        "mockjs": false
      },
      "context": "browser",
      "distDir": "./buildDir",
      "outputFormat": "esmodule",
      "scopeHoist": false,
      "optimize": true,
      "publicUrl": "/"
    }
  },
  "scripts": {
    "serve": "parcel ./public/index.html --port 3000 --no-source-maps",
    "build": "parcel build ./public/index.html --no-source-maps"
  },
  "devDependencies": {
    "@parcel/transformer-image": "2.0.0-beta.2",
    "@parcel/transformer-sass": "2.0.0-beta.2",
    "@parcel/transformer-vue": "2.0.0-beta.2",
    "@vue/compiler-sfc": "^3.0.9",
    "babel-eslint": "^10.1.0",
    "eslint": "^7.23.0",
    "eslint-plugin-vue": "^7.8.0",
    "mockjs": "^1.1.0",
    "parcel": "^2.0.0-beta.2",
    "sass": "^1.32.8"
  },
  "dependencies": {
    "axios": "^0.21.1",
    "vue": "^3.0.9",
    "vue-router": "4",
    "vuex": "^4.0.0"
  }
}

为什么我这里会给出package.json文件呢?第一点呢?主要是让大家看下我安装的依赖就知道我要干什么了第二点呢?也是最重要的一点。我们知道像Webpack、VueCLI、Vite这些工具都有自己的配置文件,那么Parcel 2在哪配置呢?啥?不是说Parcel 2是零配置吗?我可不想背锅啊!官方这样解释:

Parcel famously requires zero configuration. This never meant non-configurable, just that Parcel attempted to infer as much as possible from the code itself, and used existing config files for other tools (e.g. .babelrc). Users have loved the ease of use and developer experience that this has provided, but there are always edge cases and real use cases that require a bit more customizability.

Parcel著名地要求零配置。 这绝不是意味着不可配置,只是Parcel试图从代码本身中推断出尽可能多的信息,并将现有的配置文件用于其他工具(例如.babelrc)。 用户喜欢它提供的易用性和开发人员体验,但是总是有一些边际情况和实际用例需要更多的可定制性。

也就是说定制化配置你可以在package.json文件中配置。其他详情配置参数你可以查看这里https://v2.parceljs.org/configuration/package-json/

首先,我们来解读下上面的package.json文件。我们的目的是为了搭建像Vite这样的项目构建工具。那么,既然是Vue3项目,肯定少不了vue-routervuexvue。接口请求工具我们使用axios。css预处理语言我们使用scss。模拟数据我们肯定使用mockjs。代码检测工具eslint这个大家肯定很熟悉了。@vue/compiler-sfc该软件包包含较低级别的实用程序,如果您正在为将Vue单个文件组件(SFC)编译为JavaScript的捆绑器或模块系统编写插件/转换,则可以使用这些实用程序。注意,这里需要与Vue版本一致。剩下的两个依赖@parcel/transformer-vue@parcel/transformer-sass。则会在启动项目时自动安装,不需要你的手动安装。我最后讲一下@parcel/transformer-image这个依赖,一句话,当时被它坑惨了。 我下面总结了一下,你需要仔细看下面的内容,要不然跟我一样。熬夜熬到两点钟,也解决不了问题。

当我安装完上面依赖时,那时还没安装@parcel/transformer-image依赖(因为没仔细看文档)。我非常高兴地启动项目,结果发现img标签引入图片显示不出来。我就疑问了,我又采用了require()也不好使。最重要的是一顿报错。于是,又回头看了下文档。我看到这里https://v2.parceljs.org/recipes/image/,我心里觉得原来没有安装它啊,于是我手动的安装了@parcel/transformer-image。但是,一直在安装sharp这地方卡着。我又看了下文档。

要进行这些图像转换,我们依赖于图像转换库Sharp,因此我们要求您使用npm install sharp -D或yarn add sharp -D在本地安装它。

好吧,我终止了下载,我就不信了。单独安装下sharp还不行吗?果然,出错出在这。我通过查看sharp的官方文档,总结了一下解决措施。

  1. 获取文件

打开网址:

https://github.com/lovell/sharp-libvips/

查找与您的计算机环境匹配的两个文件。它们是以下两个文件,xxx代表计算机环境。

libvips-8.9.0-xxx.tar.gz
libvips-8.10.5-xxx.tar.br

在Mac OS环境中为darwin-x64。在Windows环境中为win32-x64。

  1. 查找文件夹 键入以下命令以获取NPM缓存路径。
npm config get cache

获取路径后,在该路径下找到_libvips该文件夹,将上述两个文件放入该文件夹中并重新启动安装命令。

这样,你直接安装@parcel/transformer-image即可,因为安装它的时候自动安装上了sharp

安装依赖的问题现在已经解决完了,下面,我们简单地讲一下Parcel 2配置。我摘要出package.json文件中Parcel 2配置如下。

{
 "source": "src/main.js",
  "targets": {
    "index": {
      "includeNodeModules": {
        "axios": true,
        "vue": true,
        "vue-router": true,
        "vuex": true,
        "mockjs": false
      },
      "context": "browser",
      "distDir": "./buildDir",
      "outputFormat": "esmodule",
      "scopeHoist": false,
      "optimize": true,
      "publicUrl": "/"
    }
  },
  "scripts": {
    "serve": "parcel ./public/index.html --port 3000 --no-source-maps",
    "build": "parcel build ./public/index.html --no-source-maps"
  },
  }

你可以参照如下两个网站进行查阅。

https://v2.parceljs.org/configuration/package-json/
https://v2.parceljs.org/features/cli/

这里就简单地介绍下。

  • source 指定要映射到目标的源代码的入口点,可以是字符串或数组。
  • targets 可以通过package.json#targets对象进一步配置目标。
  • includeNodeModules 是否捆绑所有/无/某些node_module依赖项。
  • context 捆绑软件应在哪个运行时中运行。
  • distDir 指定输出文件夹(而不是输出文件)
  • outputFormat 应该排放哪种类型的进出口
  • scopeHoist 是否启用示波器吊装对于ESM和CommonJS outputFormat,需要为true。
  • optimize 是否启用缩小功能(确切的行为由插件决定)。
  • publicUrl 捆绑软件在运行时的公共网址。

--port 3000就是设置端口号为3000的服务器网址。--no-source-maps不启用source-maps

终于,解释完配置项了。下面到了关键时期,就是我们启用下项目好使不。

键入命令:

yarn serve

OR

npm run serve

打开网址http://localhost:3000/#/

截屏2021-03-30 00.20.24.png

启动Vue3项目成功!!!

下面我们试试热更新有多快!

截屏2021-03-30 00.21.55.png

哇塞!150ms!的确很快。

验证完开发环境,我们试下生产环境。

yarn build

OR

npm run build

打包速度也非常快!

截屏2021-03-30 00.24.42.png

那么我们放到线上,看看好使不!

https://www.maomin.club/site/test1/#/

截屏2021-03-30 00.20.24.png

丝毫不差!

源码地址:

https://github.com/maomincoding/parcel-vue-app

但是,到这里我们虽然成功运行起来项目了。但是离搭建Vue3项目构建工具还差一点。

四、搭建一款极快,零配置的Vue3项目构建工具

这里,我们将使用commander这个命令行工具作为主导开发一套命令行脚手架工具。除了它,我还有用到chalk,它的作用主要是美化命令行输出样式。inquirer它的作用是进行命令行交互的。

我这里就不过多介绍了,大家可以去它们的官方网站了解详情。

我们目的就是通过命令行来安装我们搭建的项目模板,所以肯定是需要推送到NPM上。关于怎样将插件推送到NPM上,我的其他文章也有讲述,可以浏览了解下。

我们命名脚手架为parcel-vue-cli———Parcel-vue-app项目构建工具。

你可以这样使用它:

安装

npm install parcel-vue-cli -g

初始化

parcel-vue-cli init <projectName>

查看版本

parcel-vue-cli -v

赶快行动起来,构建Parcel-vue-app项目吧!

截屏2021-03-30 00.54.12.png

源码地址:

https://github.com/maomincoding/parcel-vue-cli

结语

谢谢阅读,希望没有浪费您的时间。Parcel 2还有很多可以玩的地方,比如说你也可以自己搭建一个parcel-react-cli,然后全局命令使用它。是不是有种成就感呢!此处赶紧艾特尤大大。

我创建了一个技术交流、文章分享群,群里有很多大厂的前端大佬,关注公众号后,点击下方菜单了解更多即可加我微信,期待你的加入。

公众号:前端历劫之路