3 前端模块化
3.1 ES模块化的导入和导出
export基本使用
export指令用于导出变量,比如下面的代码:
|
上面的代码还有另一种写法:
|
在需要使用的地方导入:
|
export default
某些情况下,一个模块中包含某个功能,我们并不希望给这个功能命名,而且让导入者自己来命名
这个时候就可以使用export default
// info.js
export default function() {
console.log('default function');
}我们来到main.js中,这样使用就可以了
- 这里myFunc是我自己命名的,你可以根据需要命名它对应的名字
|
另外要注意:
export default在同一个模块中,不允许同时存在多个。
但是通常情况下我们需要给*起一个别名,方便后续使用
import * as info from './info.js'
console.log(info.name, info.age, info.height);
3.2 WebPack
3.2.1 前模块化
- 在前面学习中,我已经用了大量的篇幅解释了为什么前端需更模块化。而且也提到了目前使用前端模块化的一些方案: AMD. CMD. CommonJs, ES6.
- 在ES6之前,我们要想进行模块化开发,就必须借助于其他的工具,让我们可以进行模块化开发,并且在通过模块化开发完成了项目后,还需要处理模块间的各种依赖,并且将其进行整合打包。
- 而webpack其中一个核心就是让我们可能进行模块化开发,并且会帮助我们处理模块间的依赖关系,而且不仅仅是JavaScript文件,我们的CSS,图片、json文件等等在webpack中都可以被当做模块来使用(在后续我们会看到)。
这就是webpack中模块化的概念
打包如何理解呢
- 理解了webpack可以帮助我们进行模块化,并且处理模块间的各种复杂关系后,打包的概念就非常好理解了.
- 就是将webpack中的各种资源模块进行打包合并成一个或多个包(Bundle).
- 并且在打包的过程中,还可以对资源进行处理比如压缩图片,将scss转成css,将ES6语法转成ES5语法,将TypeScript转成JavaScript等等操作。
- 但是打包的操作似乎grunt/gulpt可以帮助我们完成,它们有什么不高呢
WebPack模块打包
WebPack为了可以正常运行,必须依赖node环境,node环境为了可以正常执行很多代码,必须包含各种各样依赖的包,npm工具是node的包管理工具。
3.2.2 WebPack安装
安装WebPack首先需要安装Node.js,Node.js自带了软件包管理工具npm
查看自己的node版本:node -v
全局安装WebPack(这里我们先指定3.6版本)
|
局部安装WebPack(后续才需要)
|
–save-dev 是开发时依赖,项目打包后不需要继续使用的
为什么全局安装后,还需要局部安装呢?
- 在终端直接执行WebPack命令,使用的全局安装的WebPack
- 当在package.json中定义了scripts时,其中包含了WebPack命令,那么使用的是局部WebPack
3.2.3 WebPack简单使用
目录结构如下:
文件内容如下:
info.js:
|
mathUtils.js:
|
在main.js中使用上述两个文件中内容:
|
此时在命令行使用webpack ./src/main.js ./dist/bundle.js
命令,将上述文件打包到dist目录下的bundle.js文件中
|
如上所示,表明打包成功。
在index.html中引入bundle.js:
|
可以在页面控制台看到之前main.js中引入的代码已经正确执行:
JS文件打包
现在的js文件中使用了模块化的方式进行开发,他们可以直接使用吗?不可以。
- 因为如果直接在index.htmlsl入这两个js文件,浏览器并不识别其中的模块化代码。
- 另外,在真实项目中当有许多这样的js文件时,我们一个个引用非常麻烦,并且后期非常不方便对它们进行管理。
我们应该怎么做呢?使用webpack工具,对多个js文件进行打包。
- 我们知道, webpack就是一个模块化的打包工具,所以它支持我们代码中写模块化,可以对模块化的代码进行处理。(如何处理的,待会儿在原理中,我会讲解)
- 另外,如果在处理完所有模块之间的关系后,将多个js打包到一个js文件中,引入时就变得非常方便了。OK,如何打包呢?使用webpack的指令即可
局部安装WebPack
目前,我们使用的webpack是全局的webpack,如果我们想使用局部来打包呢?
因为一个项目往往依赖特定的webpack版本,全局的版本可能很这个项目的webpack版本不一致,导出打包出现问题。
所以通常一个项目,都有自己局部的webpack.
第一步, 项目中需要安装自己局部的webpack
这里我们让局部安装webpack3.6.0
Vue CL13中已经升级到webpack4 ,但是它将配置文件隐藏了起来,所以查看起来不是很方便
npm install webpack@3.6.0 --save-dev
第二步,通过node_moduels/.bin/webpack
启动WebPack打包
|
package.json中定义启动
但是,每次执行都敲这么一长串有没有觉得不方便呢?
- ок,我们可以在package.json的scripts中定义自己的执行脚本。
package.json中的scripts的脚本在执行时,会按照一定的顺序寻找命令对应的位置。
- 首先,会寻找本地的node_modules/.bin路径中对应的命令。
- 如果没有找到,会去全局的环境变量中寻找。
- 如何执行我们的build指令呢?
npm run build
|
3.2.4 loader
什么是loader
loader是webpack中一个非常核心的概念。
- webpack用来做什么呢?
- 在我们之前的实例中,我们主要是用webpack来处理我们写的js代码,并且webpack会自动处理js之间相关的依赖。
- 但是,在开发中我们不仅仅有基本的js代码处理,我们也需要加载css、图片,也包括一些高级的将ES6转成ES5代码,将TypeScript转成ES5代码,将scss, less转成css ,将jsx. .vue文件转成js文件等等
- 对于webpack本身的能力来说,对于这些转化是不支持的
那怎么办呢?给webpack扩展对应的loader就可以啦。
loader使用过程
步骤一:通过npm安装需要使用的loader
步骤二:在webpack.config.js中的modules关键字下进行配置
大部分loader我们都可以在webpack的官网中找到,并且学习对应的用法
css文件处理— style-loader
我们来安装style-loader:
npm instatt -save-dev style-loader
注意: style-loader需要放在css-loader的前面。
- 疑惑:不对吧?按照我们的逻辑,在处理css文件过程中,应该是css-loader先加载css文件,再由style-oader来进行进一步的处理,为什么会将style-loader放在前面呢?
- 答案:这次因为webpack在读取使用的loader的过程中,是按照从右向左的顺序读取的。
目前, webpack.config.js
的全部配置如下:
|
less文件处理
继续在官方中查找,我们会找到ess-loader相关的使用说明.和css文件类似:
首先,还是需要安装对应的loader
注意:我们这里还安装了less ,因为webpack会使用less对less文件进行编译
npe install -save-dev less-loader tess
其次,修改对应的配置文件
- 添加一个rules选项,用于处理less文件
|
图片文件处理
和上面类似,使用npm命令安装相关包:
|
只有在webpack.config.js
中新增配置:
|
我们发现webpack自动帮助我们生成一个非常长的名字
这是一个32位hash值,目的是防止名字重复
但是,真实开发中,我们可能对打包的图片名字有一定的要求
比如,将所有的图片放在一个文件夹中,跟上图片原来的名称,同时也防止重复
最终正确配置:
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
// 当加载的图片小于limit时,会将图片编译成base64字符串形式
// 当加载的图片大于limit时,需要使用file-loader模块进行处理
limit: 8192,
name: 'img/[name].[hash:8].[ext]' //定义命名规则
}
}
]
}
所以,我们可以在options中添加上如下选项:
- img :文件要打包到的文件夹
- name :获取图片原来的名字,放在该位置
- hash:8:为了防止图片名称中突,依然使用hash ,但是我们只保留8位Dext:使用图片原来的扩展名
但是,我们发现图片并没有显示出来,这是因为图片使用的路径不正确
- 默认情况下, webpack会将生成的路径直接返回给使用者
- 但是,我们整个程序是打包在dist文件夹下的,所以这里我们需要在路径下再添加一个
dist/
ES6转ES5
如果你仔细阅读webpack打包的js文件,发现写的ES6语法并没有转成ES5 ,那么就意味着可能一些对ES6还不支持的浏览器没有办法很好的运行我们的代码
在前面我们说过,如果希望将ES6的语法转成ES5 ,那么就需要使用babel.
而在webpack中,我们直接使用babel对应的loader就可以了
npm install babel-loader babel-core babel-preset-env webpack
之后同样修改
webpack.config.js
文件{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
}
之后重新编译即可
3.3 Vue Cli
3.3.1 介绍
如果你只是简单写几个Vue的demo程序,那么你不需要Vue Cli
如果你在开发大型项目,那么你需要并且必然需要使用Vue Cli
- 使用Vue.js开发大型应用时,我们需要考虑代码目录结构、项目结构和部署、热加载、代码单元测试等事情
- 如果每个项目都要手动完成这些工作,那无疑效率比较低,所以通常我们会使用一些脚手架工具来帮助完成这些事情
cli是什么意思?
- cli是Command-Line-Interface,翻译为命令行界面,但是俗称脚手架
- Vue Cli是一个官方发布vue.js项目脚手架
- 使用vue-cli 可以快速搭建Vue开发环境以及对应的webpack配置
Vue-cli使用前提
- 安装NodeJS
- 检测安装的版本
- 默认情况下自动安装Node和NPM
- Node环境要求8.9以上或者更高版本
node -v
notes: 由于国内直接使用npm官方镜像是非常慢的,这里推荐使用淘宝NPM镜像
你可以使用淘宝定制的cnpm(gzip压缩支持)命令行工具代替默认的npm:
npm install -g cnpm --registry=https://registry.npm.taobao.org
这样就可以使用cnpm命令来安装模块了:
cnpm install [name]
WebPack
Vue.js官方脚手架工具就使用了webpack模板
- 对所有的资源会压缩等优化操作
- 它在开发过程中提供了一套完整的功能,能够使得我们开发过程中变得高效
webpack全局安装:
npm install webpack -gs
什么是NPM呢?
- NPM的全称是Node Package Manager
- 是一个NodeJS包管理和分发工具,已经成为了非官方的发布Node模块(包)的标准
- 后续我们会经常使用NPM来安装一些开发过程中依赖包
3.3.2 Vue Cli的使用
安装Vue脚手架
npm install -g @vue/cli
注意: 上面安装的是Vue Cli 3的版本,如果需要安装Vue Cli 2的方式初始化项目是不可以的
notes: 注意3版本是不能直接兼容2版本的,需要使用如下命令拉取2版本的模板:
npm install @vue/cli-init -g
,vue cli 2初始化项目:
vue init wepack [my-project]
vue cli 3初始化项目:
vue create [my-project]
vue-cli3 与 2的区别
- vue-cli3 是基于webpack 4打造,vue-cli2 还是基于webpack 3
- vue-cli3的设计原则是“0配置”, 移除了配置文件的
.build
和config
等目录 - vue-cli3提供了vue ui命令,提供了可视化配置,更加人性化
- 移除了static文件夹,新增了public文件夹,并且index.html移动到public中
Runtime-Compiler和Runtime-only的区别
如果你需要在客户端编译模板(例如,向template选项传入一个子模板中的非dom和HTML挂载到一个元素),你需要带有编译器的版本
// 这种情况需要编译器(compiler)
new Vue({
template: '<div>{{ hi }}</div>'
})
// 这种情况不需要编译
new Vue({
render (h) {
return h('div', this.hi)
}
})在使用vue-loader或vueify时, *.vue文件中的模板会在构建时(build time)预编译(precompilet为Javascript,最终生成的bundle中你不再需要编译器(compilen),因此可以直接使用只含有进行时的构建版本runtime ontyl.
由于只含有运行时构建版本runtime-only)t完整构建版本full-bulil轻大约30%,你应该尽可能使用只含有运行时的构建版本,如果你还是希望使用完整构建版本,则常要在打包器中配置名
由于运行时版本的构建比其全面版本的重量轻约30%,因此你可以随时使用它,如果你仍然希望使用完整版本,则需要在期M程序中配置别名:
vue 3目录结构详解
|
3.3.3 补:匿名函数
ES5函数写法:
|
匿名函数的写法:
|
放入一个参数
|
放入两个参数
|
函数中
|
|
|
箭头函数的this使用
|