JavaScript 从 webpack 到全面拥抱 Parcel #1 探索 Parcel

hfpp2012 · December 19, 2017 · Last by hfpp2012 replied at December 28, 2017 · 9524 hits

原文发表于 www.rails365.net

最近大家都在关注一个很流行的类似 webpack 的前端构建工具 Parcel。这个库刚出来没多久 (好像截至目前十几天),但是很受欢迎,看下图就知道。

所以值得一探!

官方地址:https://parceljs.org/

github 地址:https://github.com/parcel-bundler/parcel

介绍这个库之前,我们来说一下我个人觉得 webpack 的一些不好的地方(相对于 Parcel)。

  1. 需要写配置文件(webpack.config.js),可能每使用一个功能,比如加载图片或 css,都要添加配置,要维护配置文件,而 Parcel 不需要。

  2. 感觉编译或加载速度有些慢,特别是库多或项目复杂的时候,虽然有一些办法代码拆分的方法可以解决,比如 CommonsChunkPlugin 或 DLLPlugin 之类的,但这些方法有些复杂。

  1. 需要一定的时间去学习如何使用 webpack。

Parcel 有很多优点,可以不使用配置文件,也就是说你只管写代码,它会自动运行,很智能化,打个比方吧,比如在 webpack 中如果要处理 css,那得要安装和加载一个 css 的 loader,然后配置文件写上几行,可是 Parcel 不需要,直接用就行。Parcel 学习起来比较简单,基本上可以说 "不用学习",只是使用就可以了。

除此之外,模块热替换和代码拆分的功能,Parcel 也有,还有,如果要你用 Parcel 写一个 react 的运行环境,可能不需要配置任何内容,只要安装几个 react 的包就可以用起来了。

说了这么多,我还是要把官方对它的特性进行概括的图片放出来:

下面我们要开始来体验 parcel 的神奇之处,请跟紧。(源码我放到 https://github.com/hfpp2012/hello-parcel

1. 安装

$ npm install -g parcel-bundler

然后初始化一个项目。

$ mkdir parcelapp
$ npm init

2. 初体验

新建 html 文件。(这个将会是 parcel 的入口文件)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Joke Generator</title>
</head>
<body>
  <div id="wrap">
    <h1>Joke</h1>
    <h3 id="joke"></h3>
  </div>
  <p id="copy"></p>
  <script src="./index.js"></script>
</body>
</html>

index.js

console.log('Hello');

运行编译命令。

$ parcel index.html

注意:上面的 parcel 命令接的是 html 文件,它会读 html 文件的内容,找到 javascript 文件,进行自运处理,不用像 webpack 那样,还要指定 javascript 的入口文件啥的。

生成了 dist 目录。

dist
├── index.html
└── parcelapp.js

监听在 1234 端口,浏览器效果如下:

3. CommonJS 模块语法

新建 jokes.js 文件。

jokes.js

module.exports = {
  getOne: function () {
    return new Promise((resolve, reject) => {
      // 这个 api 是公开的。
      fetch('http://api.icndb.com/jokes/random')
        .then(res => res.json())
        .then(data => {
          resolve(data.value.joke);
        })
    })
  }
}

index.js

const jokes = require('./jokes');

jokes.getOne()
  .then(joke => {
    document.getElementById('joke').innerHTML = joke;
  });

效果如下:

4. ES6 模块语法

require 改成 import,如下所示:

index.js

// const jokes = require('./jokes');

import { jokes } from './jokes';

jokes.getOne()
  .then(joke => {
    document.getElementById('joke').innerHTML = joke;
  });

jokes.js

export const jokes = {
  getOne: function () {
    return new Promise((resolve, reject) => {
      fetch('http://api.icndb.com/jokes/random')
        .then(res => res.json())
        .then(data => {
          resolve(data.value.joke);
        })
    })
  }
}

5. 使用 axios 代替 fetch

这只是为了演示使用一些库。

首先安装 axios

$ npm install axios

注意,这里每安装一个库,都要重新运行 parcel index.html

jokes.js

import axios from 'axios';

export const jokes = {
  getOne: function() {
    return new Promise((resolve, reject) => {
      axios.get('http://api.icndb.com/jokes/random')
        .then(res => {
          resolve(res.data.value.joke);
        })
    })
  }
}

6. 使用 jquery 代替 getElementById

$ npm install jquery

index.js

import { jokes } from './jokes';
import $ from 'jquery';

jokes.getOne()
  .then(joke => {
    // document.getElementById('joke').innerHTML = joke;
    $('#joke').text(joke);
  });

7. 导入 非 JavaScript 资源

copyright.txt

Copyright 2018

index.js

import fs from 'fs';

...

const copy = fs.readFileSync(__dirname + '/copyright.txt', 'utf8');

$('#copy').text(copy);

8. 简单处理 css

style.css

h1 {
  color: red;
  padding-right: 1rem;
}

#wrap {
  display: flex;
  justify-content: center;
  align-content: center;
  align-items: center;
  padding: 5px;
  border: 1px solid #333;
  border-radius: 4px;
  box-shadow: 0 10px 10px rgba(0, 0, 0, 0.12);
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  ...
  <link rel="stylesheet" href="style.css" />
  <title>Joke Generator</title>
</head>
<body>
  ...
</body>
</html>

9. 在 css 中使用 import

backgrounds.css

body {
  background: #f4f4f4;
}

style.css

@import './backgrounds.css';

...

10. 使用 sass

首先,安装 node-sass。

$ npm install node-sass

这里要花费一定时间,请耐心等待

backgrounds.scss

注意:这里由 backgrounds.css 改名为 backgrounds.scss

@import './variables.scss';

body {
  background: $light-grey;
}

variables.scss

$light-grey: #f4f4f4;

style.css

/* 改名为 scss */
@import './backgrounds.scss';
...

Parcel 还有很多好玩的,我们以后再说。

unstar 了 webpack, star 了 parcel

webpack 强大但是太繁琐了,像我这种就用一点点功能的还是喜欢 轻量切没有过多学习成本的。👍

对 ts 支持还不好,观望。

Reply to bastengao

要直播切些什么吗?

@hfpp2012

这东西支持 proxy 吗?粗一看好像没有提及

Reply to jjx

这个功能暂时没有,慢慢等吧,该有的会有的

对于 rails 开发者有什么利好吗?结合 rails api 模式做前后端分离?

我比较关注打包出来的 bundle size,真的需要用到 axios 吗?

Reply to crazyphage

只是演示一个实例

You need to Sign in before reply, if you don't have an account, please Sign up first.