# 为什么需要模块化
回顾下 JavaScript
原始功能
在网页开发的早期, js
制作作为一种脚本语言,做一些简单的表单验证或动画实现等,那个时候代码还是很少的。
那个时候的代码是怎么写的呢?直接将代码写在 <script>
标签中即可
随着 ajax
异步请求的出现,慢慢形成了前后端的分离
客户端需要完成的事情越来越多,代码量也是与日俱增。
为了应对代码量的剧增,我们通常会将代码组织在多个 js
文件中,进行维护。
但是这种维护方式,依然不能避免一些灾难性的问题。
比如全局变量同名问题:(下图)
另外,这种代码的编写方式对 js
文件的依赖顺序几乎是强制性的
但是当 js
文件过多,比如有几十个的时候,弄清楚它们的顺序是一件比较同时的事情。
而且即使你弄清楚顺序了,也不能避免上面出现的这种尴尬问题的发生。
# 模块化?组件化?
- 《浅谈前端工程化、模块化、组件化》 - https://www.cnblogs.com/angel648/p/11370327.html
个人理解:
-
一个 APP 有多个组件(如:头部搜索栏、中间数据展示框、底层的选项框)
-
一个组件有多个模块(如:搜索栏有输入模块、搜索模块、缓存模块等。。。)
【两个组件之间的模块没关系,可以重复,可以不重复】
# 匿名函数的解决方案
以前,我们可以使用匿名函数来解决方面的重名问题
在aaa.js文件中,我们使用匿名函数
但,这会导致代码不可复用。
# 使用模块作为出口
作为成年人,变量重名的解决、代码复用 我全都要!!
name,就把闭包 return 出一个 变量导出
接下来,我们在main.js中怎么使用呢?
我们只需要使用属于自己模块的属性和方法即可
这就是模块最基础的封装,事实上模块的封装还有很多高级的话题:
但是我们这里就是要认识一下为什么需要模块,以及模块的原始雏形。
幸运的是,前端模块化开发已经有了很多既有的规范,以及对应的实现方案。
常见的模块化规范:
CommonJS、AMD、CMD,也有ES6的Modules
# CommonJS(了解)
模块化有两个核心:导出和导入
CommonJS
的导出:
CommonJS
的导入
# ES6的export和import
+《JS - 13 - 模块化》 - https://blog.csdn.net/LawssssCat/article/details/104463632
## export基本使用
export指令用于导出变量,比如下面的代码:
上面的代码还有另外一种写法:
## 导出函数或类
上面我们主要是输出变量,也可以输出函数或者输出类
上面的代码也可以写成这种形式:
## export default
某些情况下,一个模块中包含某个的功能,我们并不希望给这个功能命名,而且让导入者可以自己来命名
这个时候就可以使用export default
我们来到main.js中,这样使用就可以了
这里的myFunc是我自己命名的,你可以根据需要命名它对应的名字
另外,需要注意:
export default在同一个模块中,不允许同时存在多个。
## import使用
我们使用export指令导出了模块对外提供的接口,下面我们就可以通过import命令来加载对应的这个模块了
首先,我们需要在HTML代码中引入两个js文件,并且类型需要设置为module
import指令用于导入模块中的内容,比如main.js的代码
如果我们希望某个模块中所有的信息都导入,一个个导入显然有些麻烦:
通过可以导入模块中所有的export变量
但是通常情况下我们需要给起一个别名,方便后续的使用
# 什么是Webpack?
前端、模块化、打包、工具
我们先看看官方的解释:
At its core, webpack is a static module bundler for modern JavaScript applications.
从本质上来讲,webpack是一个现代的JavaScript应用的静态模块打包工具。
我们从两个点来解释上面这句话:模块 和 打包
## 模块
模块概念前面说了。
就是 过程闭包、结果导出、使用导入
但是这样,又有一个问题,模块和模块之间相互依赖,需要管理工具。管理的手段就是“打包”
## 打包
就是将 webpack中各种模块进行合成一个包(Bundle)
在打包过程中,会对资源进行加工。
如:压缩图片、将scss转成css、将es6语法转成es5语法、将typeScript转成javaScript等
# 和 grunt/gulp 的对比
grunt/gulp 也是一个类似的工具。但是没有webpack强大。
下面左下对比
- 模块依赖简单、只需要进行简单的合并、压缩 ,那么,你可以使用 grunt/gulp
- 但是要对模块进行管理(模块之间依赖非常复杂了),那么需要用 webpack
- grunt/gulp 强调的是 前端流程的自动化,模块化不是核心
- webpack 强调模块化开发管理,前端自动(如文件压缩合并、预处理等)只是他的附带功能
# webpack 全局安装
官方教程:https://www.webpackjs.com/guides/installation/
安装webpack首先需要安装Node.js,Node.js自带了软件包管理工具npm
查看自己的node版本: (要大于9)
node -v
全局安装webpack(这里我先指定版本号3.6.0,因为vue cli2依赖该版本)
官方不推荐全局安装,我们学习,怎么方便怎么来
npm install [email protected] -g
这里,版本太高会依赖其他东西,你不会调的话,会报错哦
# 创建工程目录
准备工作
我们创建如下文件和文件夹:
文件和文件夹解析:
dist
文件夹(distribution):用于存放之后打包的文件src
文件夹:用于存放我们写的源文件main.js
:项目的入口文件。具体内容查看下面详情。mathUtils.js
:定义了一些数学工具函数,可以在其他地方引用,并且使用。具体内容查看下面的详情。
index.html
:浏览器打开展示的首页htmlpackage.json
:通过npm init生成的,npm包管理的文件(暂时没有用上,后面才会用上)
mathUtils.js
文件中的代码:
function add(num1, num2) {
return num1 + num2;
}
function mul(num1, num2) {
return num1 * num2;
}
module.exports = {
add,
mul
}
main.js
文件中的代码:
const {
add,
mul
} = require('./mathUtils.js');
console.log(add(20, 30))
console.log(mul(20, 30))
# js文件的打包
不可以直接使用我们前面写好的js
因为如果直接在index.html引入这两个js文件,浏览器并不识别其中的模块化代码。
且后期非常不方便对它们进行管理。
所以,我们需要用到webpack工具,对多个js文件进行打包。
来到 工程根目录,控制台输入命令
webpack .\src\main.js .\dist\bundle.js
工程目录 ./dist
下就 多了个打包好的文件
# 使用打包后的文件
打包后会在dist文件下,生成一个bundle.js文件
文件内容有些复杂,这里暂时先不看,后续再进行分析。
bundle.js文件,是webpack处理了项目直接文件依赖后生成的一个js文件,
我们只需要将这个js文件在index.html中引入即可
# webpack配置
## 入口和出口
我们考虑一下,如果每次使用webpack的命令都需要写上入口和出口作为参数,就非常麻烦,有没有一种方法可以将这两个参数写到配置中,在运行时,直接读取呢?
当然可以,就是创建一个 webpack.config.js
文件