webpack 项目构建:(二)ES6 编译环境搭建

注:以下教程均在 windows 环境实现,使用其他操作系统的同学实践过程可能会有些出入。

  在上一章 webpack 项目构建:(一)基本架构搭建 我们搭建了一个最基本的 webpack 项目,现在让我们以此为基础,结合 babel,构建一个可以运行最新 ES6 语法的 webpack 项目。

一、上期回顾

  在上一章,我们搭建了一个如下结构的 webpack 项目:
图片描述

  并通过 webpack.config.js 的 entry 和 output 属性,配置了 webpack 的打包规则:

webpack.config.js
图片描述

  即以当前目录下的 index.js 为打包入口,通过 webpack 打包构建,在当前目录生成一个 test.js 文件。通过简单的配置就能让 webpack 正常工作了。
  现在通过在当前目录执行 webpack 打包命令,我们就能得到 test.js 文件了。
图片描述

二、使用打包生成的 test.js 文件

  第一章中 index.js 文件做的事情很简单,仅仅是声明了一个值为整型 123 的 test 变量。

index.js
图片描述

  在实际的环境中,这样一段代码完成的功能很有限。现在让我们来扩展我们的项目,使之能完成更强大的功能。

  1. 修改 index.js 文件,完成等待 1 秒弹出问候语的功能:
    index.js
    图片描述
  2. webpack 打包生成 test.js 文件;
  3. 新建 index.html 文件,并引用打包生成的 test.js 文件:
    index.html
    图片描述

  现在让我们在浏览器里打开 index.html 文件,等待一秒就会弹出信息为 Hello word! 的弹窗。由此可见打包生成的 test.js 具有 index.js 一样的功能。
  这是因为 webpack 打包的本质,就是从入口文件出发,递归解析所有相关的依赖文件,并打包成一个或多个文件(bundle)。webpack 只是重新组织、精简了你写的代码,并不会影响代码的功能。webpack 的魅力也正是在于其强大的组织、优化代码的能力。现在让我们一步步地深入了解 webpack 的打包配置,一点点揭开 webpack 神秘的面纱。

三、ES6 和 Babel

  ECMAScript6 实现了很多强大的新特性,借助 ES6 我们能用更加优雅的方式完成许多强大的功能。只是鉴于许多老版本的浏览器尚未支持 ES6 语法,需要在使用之前转换为 ES5 语法,以使其兼容更多的浏览器。而完成这些转换工作的就是 Babel 了。
  Babel 本质就是一个 JavaScript 编译器,通过:

  1. 将 JavaScript 源代码解析成抽象语法树(AST);
  2. 将源代码的 AST 结果一系列转换生成目标代码的 AST;
  3. 将目标代码的 AST 转换成 JavaScript 代码。

  就可以完成 ES6 代码到 ES5 代码的转换,当然转换的过程会很复杂,我们在这里先了解一下基本的原理。想深入了解的同学可以通过开发自己的 Babel Plugin,熟悉 AST 的操作流程。

  Babel 本身的安装使用是很简单的,针对我们当前的应用,我们可以通过如下过程实现:

  1. 安装 babel-core 包:cnpm i --save-dev babel-core;
  2. 新建一个 Babel 测试文件 babelTest.js 并使用 babel-core 转换 ES6 代码(我们使用了 ES6 的箭头函数):
    babelTest.js
    图片描述
  3. 安装上一步中使用的 babel-preset-env 和 babel-preset-stage-0 包:cnpm i --save-dev babel-preset-env babel-preset-stage-0;(babel-preset-env 是一个主流的 Babel 插件数组;Stage-X 是实验阶段的 Presets,)
    TC39 将提案分为以下几个阶段:
    Stage 0 - 稻草人: 只是一个想法,可能是 babel 插件。
    Stage 1 - 提案: 初步尝试。
    Stage 2 - 初稿: 完成初步规范。
    Stage 3 - 候选: 完成规范和浏览器初步实现。
    Stage 4 - 完成: 将被添加到下一年度发布。
  4. 在当前目录执行 babelTest.js 文件:node babelTest.js,控制台输出信息:
    图片描述
    可以看到我们的 ES6 箭头函数被转换为了 ES5的 '(function() {})'。

  了解了 Babel 的基本工作原理,现在让我们用 ES6 的新特性,稍微改写一下我们的 index.js:

index.js
图片描述

  在这里我们用了 ES6 的模板字符串箭头函数。模板字符串通过用反引号(`)标识字符串,可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。
  在没有配置 Babel 的情况下,我们通过 webpack 命令打包,可以发现生成的 test.js 文件还是用的 ES6 语法:

test.js
图片描述

注:截图部分是 test.js 的最后参数部分。

  下面让我们看一下如何将 Babel 结合到 webpack 中,来实现 ES6 代码到 ES5 代码的转换。

四、webpack + Babel 构建 ES6 开发平台

  既然要将 webpack 和 Babel 结合在一起,就需要在两者之间建立一条纽带,而通过 webpack 的 loaders 就可以生成这条纽带,现在让我们修改我们的 webpack.config.js 配置文件:

webpack.config.js
图片描述

  可以看到我们在这里加了一段 module.rules 配置项,rules 数组里的每一项就是一条 loader 使用规则,loader 用于对不同类型文件的源代码进行转换,可以使你在 import 或"加载"模块时预处理文件。
  现在我们配置的第一条规则,就是针对以 .js 结尾的文件使用 babel-loader。由于现在我们的项目中还不存在 babel-loader,让我们先通过 cnpm 安装该模块: cnpm i --save-dev babel-loader。

  现在我们已经准备好了 webpack、webpack 和 Babel 的纽带,接下来就需要准备 Babel 的相关配置了。
  在上一节已经介绍了单独使用 Babel 的实现方法,但是在 webpack 中一般情况下我们不会主动调用 babel-core 解析 ES6 代码,而是通过 babel-loader 在 webpack 编译过程中自动解析 ES6 代码。那么现在的问题就是在上一节使用 babel-core 的过程中,我们使用了 env 和 stage-0 两个 preset,现在不使用 babel-core 了,这两个 preset 又应该在哪里配置?
  这里我们有两种方式可以实现上述配置:

  1. 使用 Babel 提供的方法:通过 Babel 目录下的 .babelrc 配置文件完成配置(直接创建 .babelrc 文件可能会有命名规范的问题,可以通过 VS Code、Sublime 等编辑器创建该文件)。这里的 .babelrc 就类似于 webpack.config.js 的作用,只是 .babelrc 文件是在 babel-loader 执行的过程中使用的。
    .babelrc
    图片描述
  2. 使用 webpack 提供的方法:在 webpack.config.js 的 module.rules 规则中,我们还可以通过使用 loader 语法配置 Babel 的 presets:
    webpack.config.js
    图片描述

  我们采用第一种方式配置 .babelrc 文件,项目目录结构如下:
图片描述

  现在让我们在当前目录下执行 webpack 命令并查看生成的 test.js 文件,可以发现我们的 index.js 已经被转换成 ES5 代码了:
图片描述
  在浏览器中打开我们的 index.html,发现打包出来的 test.js 能正常工作:
图片描述

  使用 webpack 搭建 ES6 编译环境就讲完了。下一章我们开始搭建一个 webpack 开发环境。(webpack 项目构建:(三)开发环境——本地服务器搭建

源码下载地址:https://github.com/xh4722/web...

参考资料:
ECMAScript 6入门(阮一峰)
babel-handbook
webpack 中文文档
Babel中文网

阅读 4.6k

推荐阅读