2021-06-08
时至今日,该篇文章的内容已有所过时。
Parcel 的地位也似乎一直有些尴尬。
零配置的确是一个亮点,但是到真正编写复杂庞大的项目,我们还真的需要零配置吗?
而谈起配置,似乎又难与悠久历史生态的 Webpack 同台竞技。
至于速度,则难以与新诞生的基于 ES 打包的 Vite 相匹敌。
现今的我基本已经转向使用 Vite,而并未再尝试 Parcel 的使用。

去年(已经是三年前了!)年末便听得新一代打包工具 Parcel.js 的风风火火,今日(两年前的某一天)也终于得以静下心来试一试。

five-year

Parcel

如官网所述,极速零配置 Web 应用打包工具。

Vue

鼎鼎大名,自不多言。


Vue 官方提供的模板 vuejs-template/webpack 是基于 Webpack 打包的。所以尝试着用 parcel.js 来替代 webpack 与 vue 结合在一起。

自己的小 Demo

过程

初始化

基本可以参照 vuejs-template/webpack 进行修改。

vue init webpack vue-parcel-demo 使用 vue 脚手架生成 webpack 模板

? Project name vue-parcel-demo
? Project description A Vue.js project
? Author YunYouJun <me@yunyoujun.cn>
? Vue build runtime | Runtime-only
? Install vue-router? Yes
? Use ESLint to lint your code? No
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) yarn
  • 删除 build, config, static, node_modules(之后重装) 文件夹与 .editorconfig, .postcssrc.js, package.json(之后重新生成) 文件。

  • README.md(可以重写)

  • 进入文件夹下,执行 yarn init (配置默认即可)

安装依赖

yarn add parcel-bundler vue vue-router --dev

parcel-plugin-vue

parcel-bundler/parcel @1.7.0 support Vue Now. This plugin will be not recommended.

Parcel 1.7.0 版本似乎已经支持 Vue 了。所以不需要再安装 parcel-plugin-vue 插件了。(默默删去了一段

(果然配置越来越少 2333,再之后这篇文章说不定都没有存在的必要了。)


虽说零配置,实际上是 Parcel 帮我们把要配置的东西做了。

在打包 Vue 的时候,发现它调用 yarn 安装了几个插件。当然我们也可以自己先安装上。

yarn add -D vue-template-compiler @vue/component-compiler-utils vue-hot-reload-api
# -D 与 --dev 一个意思,将依赖安装在 devDependencies

Babel 配置

Babel · The compiler for next generation JavaScript

Parcel 已经默认支持 Babel 转换

index.html

<html lang="zh-cmn-Hans"></html>

网页头部的声明应该是用 lang=”zh” 还是 lang=”zh-cn”? - 知乎

emmm, 纠结地搜到了这个答案。简体中文页面原来是用 lang="zh-cmn-Hans"

引入 main.js

...
<body>
  <div id="app"></div>
  <script src="./src/main.js"></script>
</body>
...

package.json 添加 scripts 字段

{
  "name": "vue-parcel-demo",
  "version": "1.0.0",
  "main": "index.js",
  "repository": "https://github.com/YunYouJun/vue-parcel-demo",
  "author": "YunYouJun <me@yunyoujun.cn>",
  "license": "MIT",
  "scripts": {
    "start": "npm run dev",
    "dev": "parcel index.html -p 2333 --open",
    "build": "parcel build index.html --public-url ./ --no-cache"
  },
  "devDependencies": {
    "@vue/component-compiler-utils": "^3.1.1",
    "autoprefixer": "^9.7.4",
    "parcel-bundler": "^1.12.4",
    "postcss-modules": "^1.5.0",
    "vue": "^2.5.16",
    "vue-hot-reload-api": "^2.3.0",
    "vue-router": "^3.0.1",
    "vue-template-compiler": "^2.5.16"
  },
  "dependencies": {}
}
  • -p 2333 设置端口号为 2333
  • --open 自动打开浏览器
  • --public-url ./ 设置要提供服务的公共 URL(./ 也就是设置为当前 dist 目录下)
  • --no-cache 禁用文件系统缓存

.gitignore

使用 git 管理仓库时,切记添加自定义忽略文件

  • .cacheparcel 构建时的缓存
  • dist 是打包后的文件
# Custom
.cache
dist

# ...

node_modules/

# ...

如果使用 VS Code 编辑器,也可以对工作区进行配置,不对 .cache dist 等文件夹进行搜索。

搜索排除

使用 SCSS

Command

  • npm run dev 运行
  • npm run build 构建

输入 npm run dev 运行试试。

出现如下报错:

Server running at http://localhost:1234
× C:\Users\YunYou\Documents\GitHub\vue-parcel-demo\src\router\index.js:3:23: Cannot resolve dependency ‘@/components/HelloWorld’

原因是 @ 是 webpack 默认配置中使用 alias (别名) 指代 src 文件夹的符号。

// 位于 build/webpack.base.conf
module.exports = {
  // ...
  resolve: {
  // 路径别名
    alias: {
      '@': resolve('src'),
      'vue$': 'vue/dist/vue.esm.js' // 这一个之后解释
    }
  },
}

进入 src/router/index.js , 将路径修改为相对路径

import HelloWorld from '../components/HelloWorld'
// ---
import HelloWorld from '@/components/HelloWorld'

再次运行 npm run dev, 打开 http://localhost:1234 即可看到 Vue 的主页了。

FAQ

运行时 + 编译器 vs. 只包含运行时

在使用 vue 脚手架 vue init webpack vue-parcel-demo 生成 vue-webpack 模板过程中,有如下提示:

? Vue build (Use arrow keys)
> Runtime + Compiler: recommended for most users
  Runtime-only: about 6KB lighter min+gzip, but templates (or any Vue-specific HTML) are ONLY allowed in .vue files - render functions are required elsewhere

如果选择 Runtime + Compiler ,此后会发生如下报错。

[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.(found in )

因为 vuejs-templates/webpackmain.js 源码如下

vuejs-templates/webpack/template/src/main.js

/* eslint-disable no-new */
new Vue({
  el: '#app',
  {{#router}}
  router,
  {{/router}}
  {{#if_eq build "runtime"}}
  render: h => h(App)
  {{/if_eq}}
  {{#if_eq build "standalone"}}
  components: { App },
  template: '<App/>'
  {{/if_eq}}
})

如果选择 Runtime + Compiler, main.js

// ...
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

如果选择 Runtime-only, main.js 则为

// ...
new Vue({
  el: '#app',
  router,
  render: h => h(App)
})

Vue 模板中 webpack 的默认配置通过 alias 设置了 vue 的别名,引用了完整版的 vue 。

// 位于 build/webpack.base.conf
module.exports = {
  resolve: {
  // 路径别名
    alias: {
      '@': resolve('src'),
      'vue$': 'vue/dist/vue.esm.js' // 即此处
    }
  },
}

最终打好的包里实际上是不需要编译器的,所以只用运行时版本即可。

Parcel 使用 runtime-only, 修改 main.js 中内容为 Runtime-only 形式 render: h => h(App) 即可。

后记

= =,意外的访问量很高。

时至今日,许多当初的配置已经不再需要,会逐步去除。