# 模块化编程
# 课程目标
- 学习掌握 javascriot 发展历史
- 掌握 npm,wepack 的好处以及基本使用方法
- 学习 ES6 模块基本语法,以及如何成功在浏览器使用 ES6 模块
# javascript 发展历史
在前端学习过程中,您是否逐渐了解到一些新的工具 npm,webpack,babel...,但是为什么要使用这些工具呢,它们给我们带来了是么便利?
阅读下面这篇文章也许会给你解答:
这是是现代 JavaScript 的快速简单指南之一,给前端初学者详细解释了现代 JavaScript 工作流程。
# Node Package Manage(npm)
Node Package Manager(npm )是一个命令行工具,可以帮助我们查找、安装和更新插件、库和工具存储库。
阅读下面的 npm 链接,但不要担心在您的计算机上运行任何命令。本节是关于提高你对 npm 的认识。您将有机会在接下来的项目中使用您在这里学到的东西。
- 如何使用 npm | MDN (opens new window)
- 创建一个 package.json 文件 (opens new window)
- npm 学习指南 (opens new window)
说到包管理器,yarn 的受欢迎程度不低于 npm,有兴趣的同学可以前往 yarn 官网 (opens new window)进行学习
# wepack 模块打包器
Webpack 是一个模块打包器。但是,这是什么意思?这意味着 Webpack 将 JS 文件编译成一个主文件,或者您想要将代码捆绑到的许多文件,但通常它是一个捆绑文件。
首先查看 webpack 一一个启动并运行它的示例:
阅读下面文章,了解为什么要使用 webpack
- Webpack:何时使用以及为什么 (opens new window)
- Webpack 是什么 (opens new window)
- Webpack 简介:它是什么以及如何使用它 (opens new window)
阅读下面教程,您将会掌握 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 语法:
- import | MDN (opens new window)
- export | MDN (opens new window)
- Module 的语法 - ES6 (opens new window)
- JavaScript modules 模块 - JavaScript | MDN (opens new window)
# 浏览器原生运行 ES6 模块
如何在浏览器中运行 ES6 模块呢?有两种方式:
在浏览器中直接运行 ES6 的模块化,需要使用
<script type="module"></script>
您需要使用模块打包器(例如 webpack/parcel)才能使其工作
我们先来看第一种方式:
按照上述步骤一步一步实现,您这时还不能在浏览器成功运行 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 模块
本地快速启动一个服务
以下提供几种开启本地服务的方法,选择你喜欢的方式:
- 使用 http-server 开启一个本地服务器教程 (opens new window)
- 如何设置一个本地测试服务器? (opens new window)
- Web Server for Chrome (opens new window)
# 相关阅读
- 万岁,浏览器原生支持 ES6 export 和 import 模块啦!| 张鑫旭 (opens new window)
- 如何在浏览器中的 ES6 模块 (opens new window)
- 浏览器中的 ECMAScript 模块 (opens new window)
# 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 文件,这些文件将在浏览器中自动更新。
# 阅读学习
下面是更多关于模块化的文章:
- JavaScript 模块化七日谈 (JavaScript Modularization Journey) (opens new window)
- JavaScript 模块——用例子解释 (opens new window)
- JavaScript 模块化入门 (opens new window)
- JavaScript 模块化入门 Ⅱ:模块打包构建 (opens new window)
- 了解 JavaScript 模块系统基础知识,搭建自己的库 (opens new window)
- ES6 模块实用指南 (opens new window)
- Javascript 模块化编程 阮一峰 (opens new window)
- 详解 JavaScript 模块化开发 (opens new window)
- 浅谈模块化的 JavaScript (opens new window)
- 再谈 SeaJS 与 RequireJS 的差异 (opens new window)
- 玩转 AMD 系列 by erik@EFE
# 任务
参考示例图 (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 后进行提交。
# 总结
依然把今天的学习用时,收获,问题进行记录。