Skip to content

Parcel vs Webpack4.0 #10

@MirroZhou

Description

@MirroZhou

前端打包工具:Parcel vs Webpack4

1.打包工具简介

定义(网络定义非官方):把开发中的所有资源(图片、js文件、css文件等)都看成模块,通过loader(加载器)和plugins(插件)对资源进行处理,拆分或者合并打包成符合生产环境部署的前端资源。

2.打包工具原理(or大致工作流)

基本概念解释,有助于理解官方文档。

  • assets:资源,所有的前端资源文件:.html, .css, .js, .png, .less, .vue等。
  • bundle: 打包,将一些资源打包成一个, 在打包工具中有时候指代打包后的代码。相对应的bundler就是打包器或者打包工具
  • chunk:打包后的代码块(一个文件就是一个chunk)
  • loaders:不同的文件类型需要通过不同的loaders进行转换成js模块。
  • plugins: loaders通常作用于单个文件,而plugins 通常(不仅限于)作用于打包后整体的代码。

打包工作流程

image

注:
1 Parsers 对 Assets进行AST语法分析,发现模块之间的依赖;
2 Loaders对 依赖图中的每一个节点使用合适的Loader进行转化;
3 Bundle 对 模块进行打包
4 Plugins 对 打包后的代码块做一些压缩、生成hash等工作

Parcel vs Webpack4.0

1. 安装

Parcel

npm install -i -g parcel-bundler

Webpack4.0 (注 webpack升级以后将webpack-cli提出来了,需要额外安装)

npm install webpack webpack-cli

2. 0配置打包比较

Parcel

parcel ./src/index.js

Webpack

webpack ./src/index.js (备注:默认入口为./src; 默认出口为./dist/main.js)

比较开箱即用:parcel自带js, css,html loaders, 热加载功能。webpack4 带有js loader. 不能直接对css 开箱即用,也本身不支持以html为入口。需要安装依赖,增加配置来启动热加载功能。

3. 项目实战比较

image

实战项目中,除了上面提到的文件转化(使用loaders)和 热加载功能,还需要:
1 TreeShaking功能,减少打包后文件大小;
2 延迟加载,增快首屏速度;
3 需要支持sourceMap, 方便报错调试;
4 需要生成自动引用文件后的html;
5 打包速度和开发中构建速度

主要文件如下:

// index.html
<html>
<body>
  <div id="name"></div>
  <!-- 导入一个 JavaScript 包 -->
  <!-- parcel 引入index.js, webpack 不需要引入 -->
  <script src="./js/index.js"></script>
</body>
</html>
// index.js
import {Student} from './main'
import '../css/main.css'

var node = document.createTextNode(new Student().name);
document.getElementById('name').appendChild(node);
document.getElementById('name').onclick = function() {
    //这里需要点击之后延迟加载handleClick.js
}
// main.js
import {Student} from './main'
import '../css/main.css'

var node = document.createTextNode(new Student().name);
document.getElementById('name').appendChild(node);
// handleClick.js
module.exports = function () {
    alert('clicked!!')
}
// webpack 配置文件
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var path = require('path');
var webpackConfig = {
  entry: './src/js/index.js',
  output: {
    path: path.join(__dirname,'/dist'),
    filename: '[name]-[hash].js'
  },
  //devtool: 'cheap-module-source-map',
  module: {
    rules: [
      {
        test: /\.css$/,
        //  use: ['css-loader' ]
        use:ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: "css-loader"
        })
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
    template: './src/index.html'
  }),
  new ExtractTextPlugin('css/[name].css')
]
}
module.exports = webpackConfig;

3.0 构建

Parcel

parcel build ./src/index.html --public-url ./
--public指定文件引用方式

Webpack

webpack --config ./webpack.config.js --mode=production

3.1 TreeShaking

在index.js中只加载了main.js中的 Student 的类,所以在打包的时候希望打包工具能去除掉没有用到的代码段。
结果: webpack 可以正确去除掉 main.js 中的Teacher 类
parcel 会把整个main.js函数内容全部打包进去, 如下图。
image

3.2 延迟加载

index.html有一个点击事件,点击时调用handleClick.js,但是在用户未点击的时候打包工具不要将该js文件打包进去,这也就是代码分割。
结果: parcel 和 webpack 都能正确的进行代码分割。点击时才去加载handleClick.js

  • webpack: 使用require.ensure 方式延迟加载,修改index.js 中点击事件:
    image

构建之后会生成两个js文件
image

在浏览器运行时只会加载main.js
image

当点击事件响应时,会加载打包后的handleClick.js
image

3.3 sourceMap

Parcel 和 WebPack 打包后都会生成对应.js 文件的.map文件。当浏览器调试时,开启sourceMap后则可以自动加载.map。这对于打包后文件调试来说,还是很方便的。

3.4 自动生成引用文件后的html

Parcel 打包时以index.html文件为入口,打包完成后则可以生成引用对应chunk的页面。
Webpack 只支持以js 文件为入口(这点在网上褒贬不一),若要生成引用对应chunk的页面则需要借助对应的插件'html-webpack-plugin',修改配置文件如下:
image

3.4 打包速度和开发速度对比

  • 打包速度:
    parcel: 2370ms
    parcel-with-cache: 122ms
    webpack: 1165ms

  • 开发监听修改重新构建速度
    parcel:159ms
    webpack: 691ms

注: Parcel官网上的构建速度对比应该是和webpack3+进行对比,webpack在升级成4.0版本后构建速度提高了90%

4. 其他:可扩展性和生态圈

parcel 作为前端打包工具的新星,固然有它的优势。以0配置和快速打包夺得了大家的眼球。但是对应的缺点也明显,0配置和生态圈的不完整,使得定制化、扩展性不如webpack。尤其是比较新,踩坑的人少,遇到问题也有可能不容易找到解决方案。而webpack虽然配置遭人诟病,推出的0配置也略显鸡肋,但是其他方面更加优秀。

最后

前端总是有这么多新的工具,不是说推出一种新的技术就去尝试,但是可以了解下新技术的优势,看看对应的源码,学习学习。毕竟在大项目中,需要衡量学习、替换成本和带来的好处。这也是为什么有些项目还停留在webpack4以下的原因(升级webpack也是需要踩一大堆坑的,这个时候就需要有爱折腾的人出来踩踩了)

参考:
Parcel 中文网
GULP VS WEBPACK
webpack务虚扫盲
Parcel VS Webpack

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions