在 Ruby 环境安装 Sass 我们使用了 gem ,那么在安装 node-sass 的时候我们需要使用 npm ,作为前端你一定是知道 npm 包管理器的,所以我们直接像下面这样使用 npm 安装:$ npm install node-sass// 将 node-sass 写入项目的 package.json 中$ npm install node-sass --save-dev上面我们仅仅是在 Node 环境安装了 Sass,但我们前端的项目是使用 Webpack 来构建,那么我们还需要使用 sass-loader 来编译项目中的 Sass ,所以我们需要在 Webpack 的配置中配置 sass-loader ,配置如下:// webpack.config.jsmodule.exports = { ... module: { rules: [{ test: /\.scss$/, use: [{ loader: "style-loader" // 将 JS 字符串生成为 style 节点 }, { loader: "css-loader" // 将 CSS 转化成 CommonJS 模块 }, { loader: "sass-loader" // 将 Sass 编译成 CSS }] }] }};上面就是在我们的前端项目中安装 Sass 的方式,后面我们将详细介绍 Sass 的使用,更多关于 Webpack 的配置请查阅 Webpack 文档。
基于 Node 环境来安装 Swagger Editor ,是 Swagger Editor 官方推荐使用的第一种方式,通过 Node 来安装 Swagger Editor ,无论是 Windows 系统还是 OS X 系统,都要求电脑中首先要有 Node ,如果你的电脑中还没有 Node 环境,那么请先安装 Node 。Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,同时提供了前台界面和后台服务的支持,而 Swagger Editor 的运行首先需要一个 http 服务器,所以在正式安装 Swagger Editor 时,我们首先需要安装一个 http 服务器。
我们在项目的根目录下创建 server.js,用来启动 vue 项目:const fs = require("fs");const path = require("path");const bodyParser = require("body-parser");const express = require("express");const app = express();const list = require("./mock/list.json");app.use(bodyParser.json());app.use(bodyParser.urlencoded({ extended: false })); // 服务开启后访问指定编译好的dist文件下的数据app.use(express.static(path.resolve(__dirname, "./dist")));app.get("/todo/list", (req, res) => { res.json({ data: list });});app.get("*", function(req, res) { const html = fs.readFileSync( path.resolve(__dirname, "./dist/index.html"), "utf-8" ); res.send(html);});app.listen(8081);运行命令:node start.js然后,访问 http://localhost:8081/#/ 就可以正常预览项目了。
node-sass 是提供了一个自定义导入器的选项,并将它作为了 JavascriptAPI 的一部分暴露了出来。使用它需要 node-sass v2.0.0 及以上的版本,从 v3.0.3 版本开始导入程序可以返回错误。我们举个例子来感受下:var result = sass.renderSync({ file: '/path/to/file.scss', data: 'body{background:blue; a{color:black;}}', outputStyle: 'compressed', outFile: '/to/my/output.css', // 自定义导入 importer: function(url, prev, done) { // url: 路径 // prev: 上一个解析路径 // done: 一个可选的回调函数 myImportFunction(url, prev, function(result){ done({ file: result.path, contents: result.data }); }); // OR var result = myImportFunction(url, prev); return {file: result.path, contents: result.data}; }});从上面的代码我们可以看到,在 node-sass 的自定义导入是通过 JavascriptAPI 来使用的,也就是我们上面配置的 importer ,importer 可以是一个函数也可以是一个函数数组, Sass 会按照数组中的顺序依次调用函数。
在 Node 环境中,提供了很多 http 服务器的支持,例如:Express 、 http server 等。针对 Swagger Editor 的特点和后台服务器的适用条件,这里我们采用 http server 来当做 Swagger Editor 的服务器支持。至于为什么选择 http server 来做后台服务器,这是不属于本节所介绍的内容,希望同学们可以在课下了解原因。我们使用一下命令来在 Node 环境中安装 Http Server 服务器: npm install ‐g http‐server-g 表示全局安装 http-server 服务器,这样我们就可以不用专门去 http-server 服务器目录下启动该服务了。我们看到如下提示信息就表明安装 http-server 服务器成功:
父节点:每个元素都有一个父亲节点;子节点:每个元素节点可以有零个,一个或者多个父亲节点;兄弟节点:相同父亲节点的节点;先辈节点:一个元素的父亲节点的父亲节点;后辈节点:一个元素的子节点的子节点。表达式基本语法表达式功能简介node选取node下面的所有的节点/node斜杠是代表绝对路径,这个表达式语法的意思就是选择根上的node//node选择所有的node的节点,与XML的位置无关.选择当前节点…选择当前节点的父亲节点node/child选取node子节点的所有的child元素node//child选取所有后备节点的chiid信息//@href选取所有的href的属性
表达式功能简介/books/python[1]选取books子元素中的第一个python元素/books/python[last()]选取books子元素中的最后一个元素/books/python[position()<10]选取books子元素的前9个元素.选择当前节点…选择当前节点的父亲节点node/child选取node子节点的所有的child元素node//child选取所有后备节点的chiid信息//@href选取所有的href的属性
引用计数的优点在于:实现简单系统检测到对象的引用计数变为 0 后,可以及时的释放废弃的对象处理回收内存的时间分摊到了平时引用计数的缺点在于:维护引用计数消耗性能,每次变量赋值时,都需要维护维护引用计数无法释放存在循环引用的对象下面是一个存在循环引用的例子:class Node: def __init__(self, data, next): self.data = data self.next = nextnode = Node(123, None)node.next = nodenode = None在第 6 行,创建对象 node对象 node 的 next 指向 None此时对象 node 的引用计数为 1在第 7 行,对象 node 的 next 指向 node 自身此时对象 node 的引用计数为 2在第 7 行,对象 node 指向 None此时对象 node 的引用计数为 1对象 node 的 next 字段指向自身,导致:即使没有外部的变量指向对象 node,对象 node 的引用计数也不会变为 0,因此对象 node 就永远不会被释放了。
这一小节我们来学习如何安装 Sass ,本小节会分别讲解在 Ruby 环境和 Node 环境下安装 Sass 。 一般来讲我们前端的项目工程都是在 Node 环境下的,所以我会重点讲解在 Node 环境下的前端工程中安装 Sass ,同时本节还会讲述在安装 Sass 时容易遇到的问题和解决方案。
执行命令安装本地 rollup 环境:npm i -D rollup rollup-plugin-uglify rollup-plugin-node-resolve在跟目录下新建配置文件 rollup.config.js,输入内容:import resolve from 'rollup-plugin-node-resolve';import { uglify } from 'rollup-plugin-uglify';import babel from 'rollup-plugin-babel';export default { input: './src/index.js', plugins: [resolve(), babel(), uglify()], output: { format: 'umd', sourcemap: true, file: 'dist/bundle.js', },};
使用NPM的方法进行安装需要先在本地安装Node环境。3.1、Windows 上安装 Node.js32 位安装包下载地址64 位安装包下载地址下载对应的安装包后,双击安装包,傻瓜式下一步安装就好了。3.2、Mac 上安装 Node.js1、在官方下载网站下载 pkg 安装包,直接点击安装即可。2、使用 brew 命令来安装:brew install nodebrew install node# 查看本地node环境$ node -vv10.16.0在用 Vue 构建大型应用时推荐使用 NPM 安装。当然,仅仅使用npm install是不能完整搭建Vue开发环境的。还需要webpack或 Browserify 等模块打包器配合使用。# 创建项目目录$ mkdir demo# 进入项目文件夹$ cd demo$ npm init -y# 最新稳定版$ npm install vue# 安装指定版本Vue$ npm install vue@2.6.3安装完成后可以查看到demo目录下多了 node_module/vue 文件夹。说明Vue成功安装。
在两个主要的 Sass 库 node-sass 和 dart-sass 中都支持 JavaScriptAPI ,并且它们的 API 语法都是相同的,本节内容我们使用的是 node-sass 。使用的时候需要加载 Sass 并赋给一个变量,然后就可以调用 API 了,我们举例看下:var sass = require("node-sass");sass.render({ file: "style.scss"}, function(err, result) { // ...});上面的代码就是使用的方式,其实就是普通的 Javascript 语法,下面我们看下 Sass 都为我们提供了什么 API 。
通过单链表实现堆栈,图示如下: 在上图中,每个节点有两个字段: item 和 next,item 用于存储数据,next 指向下一个节点,head 指针指向堆栈的顶部。描述堆栈的 Python 代码如下:class Node: def __init__(self, item): self.item = item self.next = Noneclass Stack: def __init__(self): self.head = None def push(self, item): node = Node(item) node.next = self.head self.head = nodestack = Stack()stack.push('a')stack.push('b')stack.push('c')在第 1 行,定义了类 Node 用于描述链表中的节点在第 6 行,定义了类 Stack 描述堆栈在第 8 行,定义了头指针 head,指向链表中的首个节点在第 10 行,定义了成员方法 push,将元素压如到堆栈中在第 11 行,创建一个新节点 node在第 12 行,新节点 node 的 next 指向头结点在第 13 行,头结点指向新节点在第 15 行,创建一个对象 stack在第 16 行到第 18 行,依次压入 3 个元素 ‘a’、‘b’、‘c’
NPM 的全称是 Node Package Manager,翻译成中文就是 node 包管理器。安装 node.js 运行环境时会自动安装 npm,uni-app 支持使用 npm 安装第三方包,后面我们通过 npm 来下载安装 uni-app 相关的软件包。NPM 中文文档:https://www.npmjs.cn/
要深入前端学习时绕不开的是 Node 的学习,而 Node 中自带了模块化系统,Node 中的模块化是基于 CommonJS 规范实现的。而 ES6 中的模块化与之还有很多的不同的地方。现阶段 Node 还依然使用的是 CommonJS 规范,而前端正在逐渐使用 ES6 module 规范。两个规定统一是一个漫长的过程,两者都存在历史遗留问题和兼容问题需要浏览器和 Node 核心的支持。有必要搞清楚两个规范的区别和注意事项,有助于我们深入地学习前端。上一节我们学习 ES6 Module 的环境搭建和基本用法,本节将继续学习模块化的相关知识,本节主要是学习 CommonJS 规范,还有对比 ES6 module 规范的一些区别和注意事项。
通过单链表实现堆栈,图示如下:通过单链表实现堆栈 在上图中,每个节点有两个字段: item 和 next,item 用于存储数据,next 指向下一个节点,head 指针指向堆栈的顶部。描述堆栈的 Python 代码如下:class Node: def __init__(self, item): self.item = item self.next = Noneclass Stack: def __init__(self): self.head = None def push(self, item): node = Node(item) node.next = self.head self.head = nodestack = Stack()stack.push('a')stack.push('b')stack.push('c')在第 1 行,定义了类 Node 用于描述链表中的节点在第 6 行,定义了类 Stack 描述堆栈在第 8 行,定义了头指针 head,指向链表中的首个节点在第 10 行,定义了成员方法 push,将元素压如到堆栈中在第 11 行,创建一个新节点 node在第 12 行,新节点 node 的 next 指向头结点在第 13 行,头结点指向新节点在第 15 行,创建一个对象 stack在第 16 行到第 18 行,依次压入 3 个元素 ‘a’、‘b’、‘c’
在目前主流的前端项目中,一般是使用 Webpack 来构建我们的前端项目,并且大多数都跑在 Node 环境下,所以首先我们要安装 node-sass,在前面的安装章节已经讲解。安装好 node-sass 后还需要执行如下命令安装 sass-loader :npm install sass-loader --save-dev安装好 sass-loader 后按照 Webpack 文档 配置 sass-loader 后就可以在项目中使用了。下面配出视频演示:74
上面我们讲了在 Ruby 环境中安装 Sass ,但我们前端在 Ruby 环境下开发是非常少的,我们前端现在基本都使用 Webpack 构建,一般都是在 Node 环境开发,那在前端项目里是如何安装 Sass 呢?首先你要知道 node-sass 和 dart-sass ,这两个都是提供好的类库,是 Sass 的实现,本身 Sass 是使用 Ruby 语言写的,但是它提供了很多接口以方便其他语言来集成和封装,node-sass 和 dart-sass 就是基于 LibSass( Sass 的 C 版本) 封装而来的。它们和 LibSass 的关系就是橘子和橘子汁的关系,我们前端基本也都是通过这两个库来使用 Sass ,我们画个图来看下它们的关系:本章节我们以 node-sass 为例,本教程中所有的内容都是以 node-sass 为例的。
本节我们主要讲解了在 Ruby 环境下安装 Sass 和在 Node 环境下安装 Sass ,以及在前端使用 Webpack 构建的项目中安装 Sass,我们画个流程图来回忆一下本节的内容,首先我们回忆下在 Ruby 环境安装 Sass 的流程:最后我们再回顾下在 Node 环境中安装 Sass:
JavaScript 在设计之初主要用来开发 Web 页面的交互、动画和表单验证等单一的功能,而且程序的体积很小,大多数都是独立执行的。随着前端的发展 JavaScript 承接的功能越来越多,Node 的出现让 JavaScript 可以作为一门后端开发语言,程序的复杂度瞬间提升,所以有必要提供一种将 JavaScript 程序拆分为可按需导入的单独模块的机制。Node 是 JavaScript 的先行者,它使用了 CommonJS 的规范来实现模块化的。在 ES6 没出来之前有很多模块化的实践,比较有名的有:CommonJS、AMD、CMD,每个规范都有自己独立的思考。随着 ES6 模块的发布,AMD 和 CMD 慢慢地淡出了我们的视野。现在主要常见的场景是 Node 端还采用 CommonJS 规范,这是历史原因。前端使用的是 ES6 module 规范,但是不能直接在前端使用,需要通过打包工具进行编译如:Webpack、Babel、Rollup 等。本文中我们将使用 Webpack 进行模块化编译工具,源代码放在 GitHub 上,仅供参考。
AQS 的实现依赖内部的同步队列,也就是 FIFO 的双向队列,如果当前线程竞争锁失败,那么 AQS 会把当前线程以及等待状态信息构造成一个 Node 加入到同步队列中,同时再阻塞该线程。当获取锁的线程释放锁以后,会从队列中唤醒一个阻塞的节点 (线程)。如下图所示,一个节点表示一个线程,它保存着线程的引用(thread)、状态(waitStatus)、前驱节点(prev)、后继节点(next),其实就是个双端双向链表,其数据结构如下:Tips:AQS 队列内部维护的是一个 FIFO 的双向链表,这种结构的特点是每个数据结构都有两个指针,分别指向直接的后继节点和直接前驱节点。所以双向链表可以从任意一个节点开始,很方便的访问前驱和后继。每个 Node 其实是由线程封装,当线程争抢锁失败后会封装成 Node 加入到 ASQ 队列中去。
一般我们比较常见的问题就是安装 sass 或者 node-sass 特别慢导致安装失败,由于国内网络的限制我们需要切换 gem 和 npm 源。切换 gem 源使用如下命令:gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/// 查看 gem 源gem sources -l使用 npm 安装 node-sass 过慢的话我们可以使用 cnpm 来替换 npm ,或者使用如下命令切换 npm 源:npm install -g mirror-config-china --registry=http://registry.npm.taobao.org
本节我们带大家学习了项目的打包部署,主要有以下知识点:利用 npm run build 打包项目。利用 node 服务部署打包后的项目。
当出现锁竞争以及释放锁的时候,AQS 同步队列中的节点会发生变化,首先看一下添加线程的场景。这里会涉及到两个变化:队列操作的变化:新的线程封装成 Node 节点追加到同步队列中,设置 prev 节点以及修改当前节点的前置节点的 next 节点指向自己;tail 指向变化:通过同步器将 tail 重新指向新的尾部节点。
使用浏览器运行原生 ES6 模块的源码在 ES6-wiki 的 mjs 文件中,浏览器是不能直接运行 ES6 模块化的,需要做一些准备工作。首先,在引入 js 文件时需要定义 script 的类型:type="module" 。另外,js 文件的后缀不能使用 .js 了,需要使用 .mjs 。这样还是不能在浏览器中运行,还需要最后一步。模块化会涉及到文件系统,而本地打开的 html 文件是没有服务的,所以我们要使用 node 服务的方式打开 html 文件,这里我们使用 node 的包 http-server 可以在相应的文件目录中启动 node 服务。安装如下:npm install --global http-server安装完启动服务的工具还是会有问题,依然打不开,这是需要在浏览器中打开一些配置:浏览器地址栏输入:chrome://flags/ 然后搜索 JavaScript 把 Experimental JavaScript 项选择 Enabled 启用状态。如下图。到这里我们就把前期的工作做完了,如何打开 html 文件呢?在控制台中进入对应的目录中执行:http-server 命令。本节的目录在 ES6-wiki/packages/module/mjs 下。在浏览器打开控制台返回的地址即可,本实例的地址是:http://127.0.0.1:8080/index.html
按照上面的操作,我们已经在 Linux 上成功安装了 JDK 14 ,接下来我们需要配置一个 JAVA_HOME环境变量,来指向 Java 的安装目录,并且将JAVA_HOME的bin目录附加到系统变量的PATH上, 其目的是为了我们在任何目录位置都可以执行 java 命令。Java 的默认安装目录为 /usr/java/jdk-14,编辑启动脚本 ~/.bash_profile,在启动脚本下添加如下两行命令export JAVA_HOME=/usr/java/jdk-14export PATH=$JAVA_HOME/bin:$PATH为了让刚刚在启动脚本添加的环境变量生效,执行 source 命令:source ~/.bash_profile最后,打印一下 PATH 系统变量,查看环境变量是否正确添加:[root@Colorful ~]# echo $PATH/usr/java/jdk-14/bin:/usr/java/jdk-13.0.2/bin:/usr/local/node/8.11.1/bin:/usr/local/node/8.9.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin
本小节针对当下主流环境,分别详细介绍了在 Node 环境和 Docker 环境中安装 Swagger Editor 的步骤,以及在安装时候容易出现的问题,针对 Swagger Editor 所需的压缩文件,考虑到自行下载可能下不动的情况,所以又额外提供了相关资源连接,同学们可以直接下载。在安装 Swagger Editor 时,由于用到了 Node 环境和 Docker 环境,所以需要同学们先了解一下上述环境的基本使用方法,这样才可以随心应手的使用 Swagger Editor。
Kubernetes 是一个最初由 Google 工程师开发和设计的开源容器编排工具。2015 年,Google 将 Kubernetes 项目捐赠给新成立的云原生计算基金会。Kubernetes是目前最流行的开源容器编排解决方案框架,基于 Google 庞大的生态圈及 RedHat(OpenShift)的企业支持。 如果加上 OpenShift(可以看作基于Kubernetes构建的发行版产品),Kubernetes 占有容器调度编排市场的份额高达 9 成,因而Kubernetes 社区也成为了容器编排工具中最大的社区。2.3.1 功能特性跨多台主机进行容器编排;更加充分地利用硬件,最大程度获取运行企业应用所需的资源;有效管控应用部署和更新,并实现自动化操作;挂载和增加存储,用于运行有状态的应用;快速、按需扩展容器化应用及其资源;对服务进行声明式管理,保证所部署的应用始终按照部署的方式运行;利用自动布局、自动重启、自动复制以及自动扩展功能,对应用实施状况检查和自我修复;支持集群联邦功能,用于控制大量节点。2.3.2 Kubernetes 组件Kubernetes官网展示了它的基本结构示意图,如下所示:其中:Master 负责管理整个集群。 Master 协调集群中的所有活动,例如调度应用、维护应用的所需状态、应用扩容以及推出新的更新;Node 是一个虚拟机或者物理机,上面具有用于处理容器操作的容器引擎。它在 Kubernetes 集群中充当工作机器的角色 每个Node都有 Kubelet , 它管理 Node 同时也充当 Node 与 Master 通信的代理;在 Kubernetes 上部署应用时,Master 启动应用容器。 Master 就编排容器在群集的 Node 上运行。 Node 使用 Master 暴露的 Kubernetes API 与 Master 通信。终端用户也可以使用 Kubernetes API 与集群交互。Tips:Kubernetes 最初只支持 docker 作为运行时,为了能够让 Kubernetes 变得更具有可扩展性,在 1.5 版本增加了 容器运行时接口 CRI(the Container Runtime Interface),在随后的演进中,CRI 被抽出来做成了独立的项目。Kubelet 作为 CRI 的客户端,而容器运行时则需要实现 CRI 的服务端。只要某个容器引擎实现了 CRI 约定的接口,就能接入 k8s 作为 Container Runtime。
ECharts 支持以 Canvas、SVG(4.0+)、VML 的形式渲染图表。VML 可以兼容低版本 IE,SVG 使得移动端不再为内存担忧,Canvas 可以轻松应对大数据量和特效的展现。不同的渲染方式提供了更多选择,使得 ECharts 在各种场景下都有更好的表现。除了 PC 和移动端的浏览器,ECharts 还能在 node 上配合 node-canvas 进行高效的服务端渲染(SSR)。从 4.0 开始我们还和微信小程序的团队合作,提供了 ECharts 对小程序的适配!社区热心的贡献者也为我们提供了丰富的其它语言扩展,比如 Python 的 pyecharts,R 语言的 recharts, Julia 的 ECharts.jl 等等。我们希望平台和语言都不会成为大家使用 ECharts 实现可视化的限制!
本节会为大家介绍如何在当下主流操作系统中安装 Swagger Editor 开源 API 配置工具。重点讲解内容:如何基于 Node 环境安装 Swagger Editor ;如何基于 Docker 环境安装 Swagger Editor ;Swagger Editor 安装是否成功的必要性测试。