# 模块化编程

# 课程目标

  • 学习掌握 javascriot 发展历史
  • 掌握 npm,wepack 的好处以及基本使用方法
  • 学习 ES6 模块基本语法,以及如何成功在浏览器使用 ES6 模块

# javascript 发展历史

在前端学习过程中,您是否逐渐了解到一些新的工具 npm,webpack,babel...,但是为什么要使用这些工具呢,它们给我们带来了是么便利?

阅读下面这篇文章也许会给你解答:

这是是现代 JavaScript 的快速简单指南之一,给前端初学者详细解释了现代 JavaScript 工作流程。

# Node Package Manage(npm)

Node Package Manager(npm )是一个命令行工具,可以帮助我们查找、安装和更新插件、库和工具存储库。

阅读下面的 npm 链接,但不要担心在您的计算机上运行任何命令。本节是关于提高你对 npm 的认识。您将有机会在接下来的项目中使用您在这里学到的东西。

说到包管理器,yarn 的受欢迎程度不低于 npm,有兴趣的同学可以前往 yarn 官网 (opens new window)进行学习

# wepack 模块打包器

Webpack 是一个模块打包器。但是,这是什么意思?这意味着 Webpack 将 JS 文件编译成一个主文件,或者您想要将代码捆绑到的许多文件,但通常它是一个捆绑文件。

首先查看 webpack 一一个启动并运行它的示例:

阅读下面文章,了解为什么要使用 webpack

阅读下面教程,您将会掌握 webpack 基本入门使用方法:

另外 ,parcel 也是目前很受欢迎的模块打包器,它是一个快速、零配置的 Web 应用程序捆绑器。有兴趣的同学可以前往parcel 官网 (opens new window)进行学习

# ES6 模块

随着 Web 应用程序复杂性的增长,我们需要能够在多个文件中编写代码并从另一个文件中引用函数(或变量)。模块化这有助于代码重用、可读性和维护。

每个 JavaScript 文件都称可以为模块,每个 JavaScript 文件(每个模块)都具有自己的作用域。意味着您在 JavaScript 文件中使用 let 或 const 定义的每个变量(函数、类)仅在该文件中可用,而在其他文件中不可用。

此时,如果您在 util.js 文件中有一个 sum 函数,而在另一个 index.js 文件中想使用它怎么办?

//util.js
const sum = (num1, num2) => {
  return num1 + num2;
};
//index.js
console.log(sum(1, 2)); // ReferenceError: sum is not defined

使用 import 和 export 模块化的好处就可以看到了。你只需要两个步骤

  • 首先,您必须首先导出需要在外部使用的类/函数/变量。
  • 然后,您将它们导入到需要使用它们的其他文件中。
//util.js
export const sum = (num1, num2) => {
  return num1 + num2;
};
// index.js
import { sum } from "./util.js";
console.log(sum(1, 2));

这样就实现了一个简单的模块化编程。为了使用上述功能,您需要将 index.js 连接一个的 HTML 页面中(例如 index.html)

<script src="index.js"></script>

这您还不能在浏览器中正常运行 ES6 模块,先不要着急,后面我们会有详细教程

# ES6 模块语法

请您先认真学习 impor、export 语法:

# 浏览器原生运行 ES6 模块

如何在浏览器中运行 ES6 模块呢?有两种方式:

  • 在浏览器中直接运行 ES6 的模块化,需要使用<script type="module"></script>

  • 您需要使用模块打包器(例如 webpack/parcel)才能使其工作

  • 了解 ES6 模块 (opens new window)

我们先来看第一种方式:

按照上述步骤一步一步实现,您这时还不能在浏览器成功运行 ES6 模块,您将得到语法错误:Uncaught SyntaxError: Cannot use import statement outside a module (opens new window)

使用下面两个步骤,能够成功在浏览器原生运行 ES6 模块

# 第 1 步: 添加 type="module" 到您的脚本中,这样会在浏览器中启用现代 import/export 语法:

<script type="module" src="index.js"></script>

完成以上修改后,您会因为跨域问题得到一个错误:错误截图 (opens new window),具体原因,可以参考这篇文章 (opens new window)

# 第二步:开启一个本地 Web 服务器访问目标文件,它允许您将文件托管在 http:// 而不是 file:// 。这里我们使用 http-server 为例

终端进入目标文件夹(也就是需要启动服务的文件夹),然后在终端输入如下命令:

http - server - c - 1;

默认端口为 8080 。 复制 http:// localho:8080 粘贴到浏览器中

恭喜你!这样您就成功在浏览器中运行 ES6 模块

本地快速启动一个服务

以下提供几种开启本地服务的方法,选择你喜欢的方式:

# 相关阅读

# webpack 编译模块

# 第 1 步 :为您的应用程序创建一个文件夹,假设命名为 my-project,然后在其中打开一个终端。

# 第 2 步:创建 package.json

请运行,npm init,回答所有基本问题,这将在您的项目中创建一个 package.json 文件。

# 第 3 步:安装 webpack、webpack-cli 和 webpack-dev-server

webpack-dev-server 是一个包,它允许您拥有一个我们将在最后一步中使用的本地 Web 服务器。 在终端输入如下命令即可:

npm install webpack webpack-cli webpack-dev-server html-webpack-plugin --save-dev

# 第四步:创建 index.html ,index,js,util.js ,webpack.config.js

webpack.config.js 用于配置 webpack

在 index.html 中 ,添加以下 HTML,将 JavaScript 文件链接到 HTML 文件。

//index.html
<!DOCTYPE html>
<html>
<head>
    <title>My App</title>
</head>
<body>
<script src="bundle.js"></script>
</body>
</html>

在 util.js 实现 sum 函数

//util.js
export const sum = (num1, num2) => {
  return num1 + num2;
};

在 index.js 中,引入 util 模块中的 sum 功能函数。添加以下 js 代码

//index.js
import { sum } from "./util.js";

alert(sum(1, 2));

在 webpack.config.js 内部,编写以下配置:

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");

const config = {
  mode: "development",
  entry: "./index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./index.html",
      filename: "index.html",
      inject: false,
    }),
  ],
};

module.exports = config;

# 第五步:运行服务器

在终端输入如下命令即可:

npx webpack serve

您现在可以在浏览器中打开http://localhost:8080 (opens new window)并更改您的 HTML 和 JS 文件,这些文件将在浏览器中自动更新。

# 阅读学习

下面是更多关于模块化的文章:

# 任务

参考示例图 (opens new window) , 运用 Es6 模块化编程思想,完成一个如下 Simon 游戏。

SimonGame 介绍:

  • 功能: 色块亮起的顺序是随机的.
  • 功能: 每次以正确的顺序点击色块后, 色块需要以原来的顺序依次亮起, 并增加一个新的序列.
  • 功能: 当色块自动按顺序亮起时, 以及用户点击色块时, 需要能够发出声音.
  • 功能: 当用户点错时, 要提示用户
  • 功能: 可以看到当前游戏中点对的色块序列的数量.
  • 功能: 可以通过点击一个按钮重新开始游戏, 并且游戏会重新从一个序列开始.
  • 功能: 在输入正确 20 个序列时获胜。将会提示胜利, 并结束游戏

用例需求

  • 默认下面显示 Start Game 按钮,用户点击开始之后,按钮自动变为 Reset game,点击可以实现重置游戏
  • 点击四个不同的按钮,发出不个不同的声音,音效素材提取:sound.zip (opens new window)
  • 开始游戏后,显示相关游戏信息:当前关卡和得分
  • 系统点击色块时,显示 Computer' turn ,轮到用户 显示 Your turn
  • 当用户点击错误,弹出提示框,提示YOU LOSE
  • 得分 20 之后,提示YOU WIN 表示用户闯关成功

要求

  • 请使用模块化编程编程实现
  • 不使用任何第三方的布局或样式库
  • 不使用任何第三方的 JavaScript 库
  • 代码风格优雅,代码结构合理,技术设计恰到好处
  • 示例图仅供参考,页面样式结构可以自行设计,实现功能需和上述用例描述一致

# 自测问题

  • 使用模块化有什么好处?
  • 如何引入模块?实现方案有哪些?
  • npm,yarn 这些模块管理器有什么好处?
  • webpack,Browserify 这些模块打包器有什么作用?

# 提交

把你今天觉得做得最好的代码放在 Github 后进行提交。

# 总结

依然把今天的学习用时,收获,问题进行记录。