学习目标
- 能够按照文档安装 Node.js
- 能够使用 npm 安装组件
- 能够使用 webpack 打包 js
- 能够说出 es6 中 let 和 const 变量的区别
- 使用解构表达式处理对象属性
- 能够使用 export 导出模块文件
- 能够使用import导入模块文件
Node.js
什么是Node.js
简单的说 Node.js 就是运行在服务端的 JavaScript。
Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。
Node.js安装
下载对应你系统的Node.js版本:https://nodejs.org/en/download/
选安装目录进行安装,完成以后,在控制台输入:
# 查看node版本信息
node -v
快速入门
创建测试工程
控制台输出
现在做个最简单的小例子,演示如何在控制台输出,创建文本文件demo1.js,
代码内容
var a = 1;
var b = 2;
console.log(a + b);
在命令提示符下输入命令:
node demo1.js
使用函数
创建文本文件demo2.js
var c = add(100, 200);
console.log(c);
function add(a, b) {
return a + b;
}
命令提示符输入命令:
node demo2.js
运行后看到输出结果为300
Nodejs模块化编程
每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。
创建文本文件demo3_1.js
exports.add = function (a, b) {
return a + b;
}
每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports
属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。
创建文本文件demo3_2.js
// 引入模块demo3_1
var demo = require('./demo3_1');
console.log(demo.add(100, 200));
在命令提示符下输入命令:
node demo3_2.js
结果为300
创建Nodejs Web服务器
创建文本文件demo4.js
var http = require('http');
http.createServer(function (request, response) {
// 发送 HTTP 头部
// HTTP 状态值:200 :OK
// 内容类型: text/plain 纯文本
response.writeHead(200, {'Content-Type': 'text/plain'});
// 发送响应数据 "Hello World"
response.end("Hello World\n")
}).listen(8888);
// 终端打印如下信息:
console.log("Server running at http://127.0.0.1:8888/")
http
为node内置的web模块
在命令提示符下输入命令:
node demo4.js
服务启动后,我们打开浏览器,输入网址:http://127.0.0.1:8888/
即可看到网页输出结果Hello World
在命令行中按 Ctrl+c
终止运行。
理解服务端渲染
创建demo5.js
,将上边的例子写成循环的形式
var http = require('http');
http.createServer(function (request, response) {
// 发送 HTTP 头部
// HTTP 状态值: 200 : OK
// 内容类型: text/plain
response.writeHead(200, {'Content-Type': 'text/plain'});
// 发送响应数据 "Hello World"
for (var i = 0; i < 10; i++) {
response.write('Hello World\n');
}
response.end('');
}).listen(8888);
// 终端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');
在命令提示符下输入命令启动服务:
node demo5.js
浏览器地址栏输入http://127.0.0.1:8888即可看到查询结果。
右键“查看源代码”发现,并没有我们写的for循环语句,而是直接的10条Hello World ,这就说明这个循环是在服务端完成的,而非浏览器(客户端)来完成。这与JSP很是相似。
处理Nodejs Web请求参数
需求:http://127.0.0.1:8888?id=123&name=zcf 获取到请求路径中参数及值并输出
在node.js中可以引入url内置模块对请求地址进行处理:
创建demo6.js
//引入node.js内置http模块
var http = require("http");
var url = require("url");
//创建并监听web服务器
http.createServer(function (request, response) {
//发送http头部
//参数1:响应状态码,200表示成功
//参数2:响应头部信息,Content-Type内容类型:纯文本
response.writeHead(200, {"Content-Type": "text/plain"});
//解析请求地址
//参数1:请求地址
//参数2:true的话使用query解析参数到一个对象,默认false
var params = url.parse(request.url, true).query;
for (var key in params) {
response.write(key + " = " + params[key]);
response.write("\n");
}
//发送响应数据
response.end("");
}).listen(8888);
console.log("服务器运行在 http://127.0.0.1:8888 ");
在命令提示符下输入命令:
node demo6.js
在浏览器访问 http://127.0.0.1:8888/?id=123&name=zcf 测试结果:
包资源管理器NPM
什么是NPM
npm全称Node Package Manager,是node包管理和分发工具。其实我们可以把NPM理解为前端的Maven 。
通过npm 可以很方便地下载js库,管理前端工程。
现在的node.js已经集成了npm工具,在命令提示符输入 npm -v
可查看当前npm版本。
NPM命令
初始化工程
init
命令是工程初始化命令。
建立一个空文件夹或者在上述的示例工程中,在命令提示符进入该文件夹 执行命令初始化。
npm init
按照提示输入相关信息,如果是用默认值则直接回车即可。
- name: 项目名称
- version: 项目版本号
- description: 项目描述
- keywords: {Array}关键词,便于用户搜索到我们的项目
最后会生成 package.json
文件,这个是包的配置文件,相当于maven的pom.xml 之后也可以根据需要进行修改
本地安装
install
命令用于安装某个模块,可以通过require引入到项目中使用。如我们想安装express模块(node的web框架),输出命令如下:
npm install express
出现警告信息,可以忽略,请放心,你已经成功执行了该命令。
在该目录下已经出现了一个node_modules文件夹 和package-lock.json
文件。
node_modules文件夹用于存放下载的js库(相当于maven的本地仓库)
package-lock.json
是当 node_modules 或 package.json
发生变化时自动生成的文件。
这个文件主要功能是确定当前安装的包的依赖,以便后续重新安装的时候生成相同的依赖,而忽略项目开发过程中有些依赖已经发生的更新(可能存在切换了不同的镜像源后,同一个大版本号下可能出现兼容问题,package-lock可以保证即使换了源,下载的文件和原来的可以保持一致)。
我们再打开package.json
文件,发现刚才下载的express
已经添加到依赖列表中了。
关于版本号定义
指定版本:比如1.2.2,遵循“大版本.次要版本.小版本”的格式规定,安装时只安装指定版本。
波浪号(tilde)+指定版本:比如~1.2.2,表示安装1.2.x的最新版本(不低于1.2.2),但是不安装1.3.x,也就是说安装时不改变大版本号和次要版本号。
插入号(caret)+指定版本:比如ˆ1.2.2,表示安装1.x.x的最新版本(不低于1.2.2),但是不安装2.x.x,也就是说安装时不改变大版本号。需要注意的是,如果大版本号为0,则插入号的行为与波浪号相同,这是因为此时处于开发阶段,即使是次要版本号变动,也可能带来程序的不兼容。
latest:安装最新版本。
全局安装
刚才我们使用的是本地安装,会将js库安装在当前目录,而使用全局安装会将库安装到你的全局目录下。
全局安装之后可以在 命令行 使用该安装的模块对应的内容或命令。
如果你不知道你的全局目录在哪里,执行命令查看全局目录路径
npm root -g
默认全局目录在:C:\Users\zhuchifeng\AppData\Roaming\npm\node_modules
比如全局安装jquery, 输入以下命令:
# 安装之后在全局目录下会存在对应的jquery目录,其里面的dist则包含有对应的jquery.js文件
npm install jquery -g
注意
- 本地安装:将下载的模块安装到当前目录(项目);
- 全局安装:将下载的模块安装到全局的目录(
npm root -g
)
批量下载
从网上下载某些代码,发现只有package.json
,没有node_modules文件夹,这时需要通过命令重新下载这些js库。
进入目录(package.json
所在的目录)输入命令:
npm install
此时,npm会自动下载package.json
中依赖的js库。
切换NPM镜像
有时我们使用npm下载资源会很慢,所以可以切换下载的镜像源(如:淘宝镜像);或者安装一个cnpm(指定淘宝镜像)来加快下载速度。
1、如果使用切换镜像源的方式,可以使用一个工具:nrm
首先安装nrm
,这里 -g
代表全局安装
# 管理员身份 打开cmd执行如下命令
npm install nrm -g
然后通过 nrm ls
命令查看npm
的仓库列表,带*的就是当前选中的镜像仓库:
通过 nrm use taobao
来指定要使用的镜像源:
2、如果使用cnpm的方式,则先安装cnpm,输入如下命令:
# 如果不使用nrm 切换,可以在安装cnpm的时候指定镜像仓库
npm install -g cnpm --registry=https://registry.npm.taobao.org
安装后,我们可以使用以下命令来查看cnpm
的版本:
cnpm -v
使用cnpm
cnpm install 需要下载的js库;一般只有在下载模块的时候才使用cnpm,其它情况还是一样使用npm;
运行工程说明
如果我们想运行某个工程,则使用run
命令。
如果package.json
中定义的脚本中有:
- dev是开发阶段测试运行
- build是构建编译工程
- lint 是运行js代码检测
运行时命令格式:
npm run dev或者build或者lint
编译工程说明
编译后的代码会放在dist
文件夹中,进入命令提示符输入命令
npm run build
生成后会发现只有个静态页面,和一个static文件夹
这种工程我们称之为单页Web应用(single page web application,SPA),就是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序。
这里其实是调用了webpack
来实现打包的,关于webpack
下面的章节将进行介绍。
Webpack入门
什么是 Webpack
Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。webpackjs
从图中我们可以看出,Webpack 可以将多种静态资源 js、css等转换成一个静态文件,减少了页面的请求。 接下来简单为大家介绍 Webpack 的安装与使用。
Webpack 安装
全局安装
npm install webpack -g
npm install webpack-cli -g
如果安装失败;则将全局目录下的webpack的相关文件夹删除再执行上述命令
安装后查看版本号
webpack -v
快速入门
JS打包
(1)创建src文件夹,创建bar.js
exports.info = function (str) {
document.write(str);
}
(2)src下创建logic.js
exports.add = function (a, b) {
return a + b;
}
(3)src下创建main.js
var bar = require("./bar");
var logic = require("./logic");
bar.info("100 + 200 =" + logic.add(100, 200));
(4)创建配置文件webpack.config.js
,该文件与src处于同级目录
var path = require("path");
// exports 就是 module.exports,
// 但是这里直接是赋值,所以不能直接使用exports,否则exports就不是module.exports了
module.exports = {
// 入口文件
entry: "./src/main.js",
output: {
// __dirname 是node的一个全局变量,获得当前文件所在目录的完整目录名
path: path.resolve(__dirname, "./dist"),
filename: "bundle.js"
}
}
以上代码的意思是:读取当前目录下src文件夹中的main.js
(入口文件)内容,把对应的js文件打包,打包后的文件放入当前目录的dist
文件夹下,打包后的js文件名为bundle.js
(5)执行编译命令
webpack
执行后查看bundle.js
会发现里面包含了上面两个js文件的内容
(6)创建index.html
,引用bundle.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>nodejs测试</title>
<script src="dist/bundle.js"></script>
</head>
<body>
</body>
</html>
(7)浏览器上访问index.html
文件,会发现有内容输出
CSS打包
(1)安装style-loader
和 css-loader
Webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader
进行转换。
Loader 可以理解为是模块和资源的转换器,它本身是一个函数,接受源文件作为参数,返回转换的结果。这样,我们就可以通过 require 来加载任何类型的模块或文件,比如 CoffeeScript、 JSX、 LESS 或图片。
首先我们需要安装相关Loader插件,css-loader
是将 css 装载到 javascript;style-loader
是让 javascript 认识css
cnpm install style-loader css-loader --save-dev
-save 的意思是将模块安装到项目目录下,并在package文件的dependencies节点写入依赖。运行npm install–production或者注明NODE_ENV变量值为production时,会自动下载模块到node_modules目录中。
-save-dev 的意思是将模块安装到项目目录下,并在package文件的devDependencies节点写入依赖。运行npm install --production或者注明NODE_ENV变量值为production时,不会自动下载模块到node_modules目录中。
cnpm install less less-loader --save-dev
(2)修改webpack.config.js
var path = require("path");
// exports 就是 module.exports,
// 但是这里直接是赋值,所以不能直接使用exports,否则exports就不是module.exports了
module.exports = {
// 入口文件
entry: "./src/main.js",
output: {
// __dirname 是node的一个全局变量,获得当前文件所在目录的完整目录名
path: path.resolve(__dirname, "./dist"),
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
}
}
(3)在src文件夹创建css文件夹,css文件夹下创建css1.css
body {
background-color: blue;
}
(4)修改main.js
,引入css1.css
require("./css/css1.css")
(5)重新运行webpack
(6)运行index.html
看看背景是不是变成蓝色
ES6
ES6?就是ECMAScript
第6版标准。
什么是ECMAScript
编程语言JavaScript
是ECMAScript
的实现和扩展 。
ECMAScript
是由ECMA
(一个类似W3C的标准组织)参与进行标准化的语法规范。
ECMAScript
定义了:
ECMAScript
标准不定义HTML或CSS的相关功能,也不定义类似DOM(文档对象模型)的Web API,这些都在独立的标准中进行定义。ECMAScript涵盖了各种环境中JS的使用场景,无论是浏览器环境还是类似node.js的非浏览器环境。
ECMAScript
标准的历史版本分别是1、2、3、5。
那么为什么没有第4版?其实,在过去确实曾计划发布提出巨量新特性的第4版,但最终却因想法太过激进而惨遭废除。
(这一版标准中曾经有一个极其复杂的支持泛型和类型推断的内建静态类型系统)。
ES4饱受争议,当标准委员会最终停止开发ES4时,其成员同意发布一个相对谦和的ES5版本,随后继续制定一些更具实质性的新特性。这一明确的协商协议最终命名为“Harmony”,因此,ES5规范中包含这样两句话
ECMAScript是一门充满活力的语言,并在不断进化中。
未来版本的规范中将持续进行重要的技术改进
2009年发布的改进版本ES5,引入了Object.create()、Object.defineProperty()、getters和setters、严格模式以及JSON对象。
ECMAScript 6.0
(以下简称ES6)是JavaScript语言的下一代标准,2015年6月正式发布。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
ECMAScript的快速发展
而后,ECMAScript
就进入了快速发展期。
1998年6月,ECMAScript 2.0 发布。
1999年12月,ECMAScript 3.0 发布。这时,ECMAScript 规范本身也相对比较完善和稳定了,但是接下来的事情,就比较悲剧了。
2007年10月。。。。ECMAScript 4.0 草案发布。这次的新规范,历时颇久,规范的新内容也有了很多争议。在制定ES4的时候,是分成了两个工作组同时工作的。
一边是以 Adobe, Mozilla, Opera 和 Google为主的 ECMAScript 4 工作组。
一边是以 Microsoft 和 Yahoo 为主的ECMAScript 3.1 工作组。
ECMAScript 4 的很多主张比较激进,改动较大。而 ECMAScript 3.1 则主张小幅更新。最终经过 TC39 的会议,决定将一部分不那么激进的改动保留发布为 ECMAScript 3.1,而ES4的内容,则延续到了后来的ECMAScript5和6版本中
2009年12月,ECMAScript 5 发布。
2011年6月,ECMAScript 5.1 发布。
2015年6月,ECMAScript 6,也就是 ECMAScript 2015 发布了。 并且从 ECMAScript 6 开始,开始采用年号来做版本。即 ECMAScript 2015,就是ECMAScript6。
ES6的一些新特性
这里只把一些常用的进行学习,更详细的大家参考:阮一峰的ES6教程
创建测试工程
let 和 const 命令
var
之前,js
定义变量只有一个关键字: var
var
有一个问题,就是定义的变量有时会莫名奇妙的成为全局变量。
例如这样的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>es6 测试</title>
<script type="text/javascript">
for (var i = 0; i < 5; i++) {
console.log(i);
}
console.log("var 循环外:" + i);
</script>
</head>
<body>
</body>
</html>
打印的结果:
let
let
所声明的变量,只在 let 命令所在的代码块内有效。
把刚才的 var
改成 let
试试:
for (let i = 0; i < 5; i++) {
console.log(i);
}
console.log("let 循环外:" + i)
结果:
const
const
声明的变量是常量,不能被修改;在浏览器控制台进行如下操作:
模板字符串
第一个用途,基本的字符串格式化。将表达式嵌入字符串中进行拼接。用${}来界定。
// es5
let name1 = "itcast";
console.log("hello " + name1);
// es6
const name2 = "itcast";
console.log(`hello ${name2}`);
第二个用途,在ES5时我们通过反斜杠()来做多行字符串或者字符串一行行拼接。ES6反引号(``)直接搞定。
// es5
var msg = "Hello \
world!";
// es6
const template = `<dev>
<span>hello world!</span>
</dev>`
对象初始化简写
ES5对于对象都是以键值对的形式书写,是有可能出现键值对重名的。例如
function person5(name, age) {
return {name: name, age: age};
}
console.log("es5=>" + JSON.stringify(person5("xiaoming", 13)));
以上代码可以简写为
function person6(name, age) {
// 属性和值是同名的则可以省略为如下
return {name, age};
}
console.log("es6=>" + JSON.stringify(person6("xiaoming", 13)));
解构表达式
数组解构
比如有一个数组:
let arr = [1,2,3]
想获取其中的值,只能通过角标。ES6可以这样:
// x,y,z将与arr中的每个位置对应来取值
const [x,y,z] = arr
// 然后打印
console.log(x,y,z)
结果:
对象解构
例如有个person
对象:
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
可以这么做:
// 解构表达式获取值
const {name, age, language} = person;
// 打印
console.log(name);
console.log(age);
console.log(language);
结果:
如果想要用其它变量接收,需要额外指定别名:
{name:n}
:name是person中的属性名,冒号后面的n是解构后要赋值给的变量。
拷贝对象属性
比如有一个person
对象:
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
想获取它的 name
和 age
属性,封装到新的对象,该怎么办?
在解构表达式中,通过 language 接收到语言,剩下的所有属性用 ... obj
方式,可以一起接收,这样 obj 就是一个新的对象,包含了 person 中,除了 language 外的所有其它属性
数组也可以采用类似操作。
函数优化
箭头函数
ES6中定义函数的简写方式:
在es-demo.html
中测试;一个参数时:
var print = function (obj) {
console.log(obj);
};
print("print");
var print2 = obj => console.log(obj);
print2("print2");
多个参数:
// 两个参数的情况:
var sum = function (a, b) {
return a + b;
}
console.log(sum(1, 2));
// 简写为:
var sum2 = (a, b) => a + b;
console.log(sum2(1, 2));
代码不止一行,可以用 {} 括起来
var sum3 = (a, b) => {
console.log(a + b);
return a + b;
}
console.log(sum3(1, 2));
对象的函数属性简写
比如一个Person
对象,里面有eat
方法:
let person = {
"name": "jack",
// 以前,也可以给food默认值
eat1: function (food = "肉") {
console.log(this.name + "在吃" + food);
},
// 箭头函数版,不能使用this
eat2: (food = "肉") => console.log(person.name + "在吃" + food),
// 简版
eat3(food) {
console.log(this.name + "在吃" + food)
}
}
person.eat1("111");
person.eat2("222");
person.eat3("333");
箭头函数结合解构表达式
比如有一个函数:
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
function hello(person) {
console.log("hello " + person.name);
}
hello(person);
如果用箭头函数和解构表达式:
var hello2 = ({name}) => console.log("hello " + name);
hello2(person);
map
和reduce
数组中新增了map和reduce方法。
map
map()
:接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。
举例:有一个字符串数组,希望转为int数组
let arr = ['1', '20', '-5', '3'];
console.log(arr)
arr = arr.map(s => parseInt(s));
console.log(arr)
reduce
reduce(function(),初始值(可选))
:接收一个函数(必须)和一个初始值(可选),该函数接收两个参数:
- 第一个参数是上一次reduce处理的结果
- 第二个参数是数组中要处理的下一个元素
reduce() 会从左到右依次把数组中的元素用reduce处理,并把处理的结果作为下次reduce的第一个参数。如果是第一次,会把前两个元素作为计算参数,或者把用户指定的初始值作为起始参数
举例:
let arr = [1, 20, -5, 3]
// 没有初始值
arr.reduce((a, b) => a + b)
// 设置初始值为1
arr.reduce((a, b) => a + b, 1)
arr.reduce((a, b) => a * b)
arr.reduce((a, b) => a * b, 0)
执行结果:
小结:
reduce方法会从左到右依次把数组中的元素用函数处理(reduce方法的第一个参数),会返回一个执行结果。
let arr = [1, 2, 3]
arr.reduce((a,b)=>a+b)
第1次:(1,2) => 1+2
第2次:(3, 3) => 3+3 --------》 6
promise
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
可以通过Promise的构造函数来创建Promise对象,并在内部封装一个异步执行的结果。
语法:
const promise = new Promise(function (resolve, reject) {
// ... 执行异步操作
if (/* 异步操作成功 */) {
resolve(value);// 调用resolve,代表Promise将返回成功的结果
} else {
reject(error);// 调用reject,代表Promise会返回失败结果
}
});
这样,在promise
中就封装了一段异步执行的结果。
如果我们想要等待异步执行完成,做一些事情,我们可以通过promise
的then方法
来实现语法:
promise.then(function (value) {
// 异步执行成功后的回调
});
如果想要处理promise
异步执行失败的事件,还可以跟上catch
:
promise.then(function(value){
// 异步执行成功后的回调
}).catch(function(error){
// 异步执行失败后的回调
})
示例:
const promise = new Promise(function (resolve, reject) {
setTimeout(() => {
let num = Math.random();
if (num < 0.5) {
resolve("成功!num = " + num);
} else {
reject("失败!num = " + num);
}
}, 300)
});
promise.then(function (msg) {
console.log(msg);
}).catch(function (msg) {
console.log(msg);
})
结果:
对象扩展
ES6给Object拓展了许多新的方法,如:
- keys(obj):获取对象的所有key形成的数组
- values(obj):获取对象的所有value形成的数组
- entries(obj):获取对象的所有key和value形成的二维数组。格式: [[k1,v1],[k2,v2],…]
- assign(dest, …src) :将多个src对象的值 拷贝到 dest中(浅拷贝)。
let p2 = {"name": "jack", "age": 21}
Object.keys(p2)
Object.values(p2)
Object.entries(p2)
// 测试覆盖问题
let obj = {"name": "rose"}
Object.assign(obj, p2)
Object.assign(obj, p2, {"address": "China"})
数组扩展
ES6给数组新增了许多方法:
- find(callback):把数组中的元素逐个传递给函数callback执行,如果返回true,则返回该元素
- findIndex(callback):与find类似,不过返回的是匹配到的元素的索引
- includes(element):判断指定元素是否存在
let arr = [1, 20, -5, 3]
//元素能整除2的
arr.find(i => i % 2 === 0)
//查询元素能整除2的索引号
arr.findIndex(i => i % 2 === 0)
arr.includes(3)
arr.includes(4)
export和import
ES6 在语言标准的层面上,实现了模块功能。ES6 模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。遗憾的是export和import命令不能在浏览器直接使用,不过可以通过babel转换为es5再运行。import导入模块
、export导出模块
。
安装babel
babel是JavaScript
语法的编译器。
(1)babel转换配置,项目根目录添加 .babelrc
文件;注意不要忘记了这个文件中的 .
{
"presets" : ["es2015"]
}
(2)安装es6转换模块
cnpm install babel-preset-es2015 --save-dev
(3)全局安装命令行工具
# 管理员身份 执行
cnpm install babel-cli -g
(4)使用
babel-node js文件名
命名导出(Named exports)
此方式每一个需要输出的数据类型都要有一个name,统一输入一定要带有 {} ,即便只有一个需要输出的数据类型。
export导出模块:编写export1.js
// 方式一
/*
export let name = "itcast";
export let age = 13;
export let gender = "男";
export let say = function (str) {
console.log(str);
}
*/
// 方式二
let name = "itcast";
let age = 13;
let gender = "男";
let say = function (str) {
console.log(str);
}
export {name, age, gender, say};
import导入模块:编写import1.js
import {name, age, gender, say} from "./export1";
console.log(name, age, gender);
// import命令输入的变量都是只读的,因为它的本质是输入接口。也就是说,不允许在加载模块的脚本里面,改写接口。
// name = "heima" //会报错 "name" is read-only
//上面代码中,脚本加载了变量name,对其重新赋值就会报错,因为name是一个只读的接口。
// 但是,如果name是一个对象,改写name的属性是允许的。也就是name.abc = xxx 这样是可以的
say("hello world");
import {name as abc, say as hello} from "./export1";
console.log(abc); // itcast
hello("hello world ....")
运行命令测试:
babel-node import1.js
默认导出(Default exports)
默认输出不需要name,但是一个js文件中只能有一个export default
。
export导出模块:编写export2.js
// 方式一
export default function (str) {
console.log(str);
}
// 方式二 一个文件只能一个export default,不能1个以上同时存在
/*
export default {
eat(sth) {
console.log("eat " + sth);
},
drink(sth) {
console.log("drink " + sth);
}
}
*/
需要注意 export default
在一个模块(文件)中只能使用一次;并且不能放置在函数或条件代码里面
import导入模块:编写import2.js
// 导入default的模块文件不需要使用{}
import itcast1 from "./export2";
itcast1("hello itcast");
/*
import abc from "./export2";
abc.eat("meat");
abc.drink("water");
*/
运行命令测试:
babel-node import2.js