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

hfpp2012 · 2017年12月19日 · 最后由 hfpp2012 回复于 2017年12月28日 · 9532 次阅读

原文发表于 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 支持还不好,观望。

bastengao 回复

要直播切些什么吗?

@hfpp2012

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

jjx 回复

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

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

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

crazyphage 回复

只是演示一个实例

需要 登录 后方可回复, 如果你还没有账号请 注册新账号