5

下一代零配置打包工具 Parcel 初体验

 3 years ago
source link: https://zhuanlan.zhihu.com/p/34033344
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

下一代零配置打包工具 Parcel 初体验

JavaScript话题下的优秀回答者

过于复杂繁琐的 webpack 配置一直是前端项目里的一个痛点,而新一代的“零配置”打包器 parcel 正在解决这个问题,春节回来之后的这几天我尝试把手上的业务迁移到 parcel 构建,下面就是一些踩坑心得。

先说结论:

  • parcel 极其适合小型单页 React 页面的打包构建,真的是完全零配置
  • 对于 vue,目前 parcel-plugin-vue 存在一些坑(详细请看这个 issue),现在已经修复,但 parcel-plugin-vue 还未更新。
  • 对于大型多页的项目,parcel 打包构建没有问题,但目前 parcel 1.6.2版本还不支持 CommonsChunk 和 Tree Shaking,对于 alias 的支持在下个版本才会加入,所以构建出来的 js 体积还比较大。

先从一个极简的 React 应用开始,首先当然是先安装:

npm i parcel-bundler -g

然后你可以随便写一个 React 的 Hello World:

<!-- index.html -->
<html>
<body>
    <div id="root"></div>
    <script src="./index.js"></script>
</body>
</html>
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
  <h1>Hello, parcel!</h1>,
  document.getElementById('root')
);

我们这里用到了 ES6 语法,以及 JSX,但与 webpack 不同的是,我们不需要额外地配置一堆 loader 和插件,不需要区分开发/生产环境的构建配置。

为了这段 ES6/JSX 的代码能跑起来,只需要安装一些 babel 插件就可以了:

npm install babel-preset-env
npm install babel-preset-react

然后写一个 .babelrc:

{
  "presets": ["env", "react"]
}

然后,就可以跑起一个自带 HMR,支持 ES6/JSX 语法等等高阶特性的本地开发环境:

parcel index.html

对于常见的图片、less文件什么的,parcel 当然是天生支持的,无需任何配置:

// 来一张图片
import yourImage from '123.png';
// 来一个 less 文件
import 'index.less';
ReactDOM.render(
  <img src={yourImage} />,
  document.getElementById('root')
);

构建也很简单:

parcel build index.html

使用 Parcel 构建 Vue 项目

与 React 稍有不同的是,我们要额外安装一个 parcel-plugin-vue 来支持对于 .vue 文件的加载:

npm i parcel-plugin-vue

然后就非常简单了:

<!-- index.html -->
<html>
<body>
    <div id="root"></div>
    <script src="./index.js"></script>
</body>
</html>
// index.js
import Vue from 'vue'
import App from './index.vue'
new Vue({
  el: '#root',
  render: h => h(App)
})
<!-- index.vue -->
<style lang="less" scoped>
    div {
        font-size: 50px;
        text-align: center;
    }
</style>

<template>
  <div>hello {{text}}!</div>
</template>

<script>
    export default {
        data() {
            return {
                text: 'parcel'
            }
        }
    }
</script>
parcel index.html

我们这里使用了 .vue 文件,里面包含了 less 方言、es6 语法,而这些都不需要额外的配置。

vue 项目的一些坑

1、报错 Uncaught TypeError: Cannot read property 'add' of undefined

我们上面的例子使用的是 parcel 1.6.2 以及 parcel-plugin-vue 1.5.0,有可能会遇到这个错误,这个错误本质上是 parcel-plugin-vue 中错误地重写了 parcel 的一处方法导致的,现在已经得到修复(详情请看这个issue),不过目前 parcel-plugin-vue 还没发布修复后的新版本,可能要再等几天。

2、报错 Unknown Version 6.2 of samsung

在一些旧项目中可能会遇到,这是由于本地 browserlist 依赖的 caniuse-lite 版本太旧导致的,更新 caniuse-lite 可以解决:

npm i caniuse-lite

生产环境中使用 parcel 的正确姿势

1、本地开发环境

parcel 打开开发环境其实很简单:

parcel xxx.html

但在大多数项目中,我们更偏向于使用项目内安装的 parcel,而不是全局安装的 parcel,所以我们会写一个 npm script,然后 npm run dev

{
    "scripts": {
        "dev": "parcel xxx.html"
    }
}

但项目内有可能会存在多个页面,为每个页面都写一个 npm scripts 会很麻烦,所以我们可以配合 npm scripts 的参数来解决:

{
    "scripts": {
        "dev": "parcel" // 这里不写页面名
    }
}
npm run dev -- /path/to/xxx.html

注意 -- 和路径之间有一个空格,这样 npm 就会把路径识别为 parcel 的参数。

2、多页面项目的构建

parcel 目前还不支持多入口,所以只能一页一页地构建,我们可以通过 shell 脚本来自动解决。

例如,我们的项目结构是这样的:

src
└── page
    ├── page1
        ├── index.html
        └── index.js 
    ├── page2
        ├── index.html
        └── index.js 
    ├── page3
        ├── index.html
        └── index.js 
    └── page4
        ├── index.html
        └── index.js

那么我们可以写一个 build.sh 作为构建脚本:

# 先清空 dist
rm -rf dist
mkdir dist

# 对 page 文件夹下的每一个 name 都进行构建
cd ./src/page
for name in $(ls)
do
    echo building $name ...
    npm run parcel:build -- src/page/$name/index.html -d dist/$name --detailed-report
done

注意我们这里使用了 parcel:build 这个命令:

{
    "scripts": {
        "parcel:build": "parcel build"
    }
}

使用 parcel 构建的优劣总结

  • 零配置真的爽,爽啊爽啊就是爽,用了就回不来了,完全告别几百行复杂的 webpack 配置。
  • 构建速度比 webpack 快很多,内置了大量 webpack 配起来十分蛋疼的东西(比如 HMR、dev server、各种 loader)。
  • 完全可以应对大型项目的开发及构建。
  • webpack 的一些高阶特性还不支持,比如 CommonsChunk、Tree Shaking、多入口文件、自定义构建出的文件名、内联小尺寸的图片、内联css等,所以构建出来的资源体积都比较大。
  • 目前对于大型项目的构建还需要额外写 shell 脚本(但我真的觉得比写 webpack 构建简单太多了)。
  • 还处在快速迭代期,特殊情况下可能会有奇怪的报错,需要自行 debug 解决。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK