写点什么

深入理解 Deno 是如何借助 PowerShell 进行安装脚本

用户头像
梁龙先森
关注
发布于: 2021 年 02 月 24 日
深入理解Deno是如何借助PowerShell进行安装脚本

Deno Deno Deno...满天飞,趁昨个儿摸鱼安装了把环境,今天回顾下 Deno 安装史,并深入看看它是如何使用 powershell 安装的。

什么是 Deno

如果你熟悉 Node.js,那么 Deno 就像 Node.js 一样,同样属于服务端 JavaScript 运行时。但是它很多方面都得到了改善,比如下面一些功能列表:

  • Deno 基于最新的 JavaScript 语言;

  • Deno 具有覆盖面广泛的标准库;

  • Deno 以 TypeScript 为核心,配以更多独特的方式从而带来了巨大的优势,其中包括一流的 TypeScript 支持(Deno 自动编译 TypeScript 而无需你单独编译);

  • Deno 大力拥抱 ES 模块标准;

  • Deno 没有包管理器;

  • Deno 具有一流的 await 语法支持;

  • Deno 内置测试工具;

  • Deno 旨在尽可能地与浏览器兼容,例如通过提供内置对象 fetch 和全局 window 对象。


了解完 Deno,下面就安装个环境试试。

安装最新版

使用 Shell:

curl -fsSL https://x.deno.js.cn/install.sh | sh
复制代码

使用 PowerShell:

iwr https://x.deno.js.cn/install.ps1 -useb | iex
复制代码

安装某个特定版本

使用 Shell:

curl -fsSL https://x.deno.js.cn/install.sh | sh -s v1.0.0
复制代码

使用 PowerShell:

$v="1.0.0"; iwr https://x.deno.js.cn/install.ps1 -useb | iex
复制代码

环境变量

  • DENO_INSTALL - Deno 的安装目录。默认为 $HOME/.deno。Deno 可执行文件将安装在 $DENO_INSTALL/bin 目录。 安装成功后将对所有用户有效:

使用 Shell (/usr/local):

curl -fsSL https://x.deno.js.cn/install.sh | sudo DENO_INSTALL=/usr/local sh
复制代码

使用 PowerShell (C:\Program Files\deno):

# 使用管理员模式运行:$env:DENO_INSTALL = "C:\Program Files\deno"iwr https://x.deno.js.cn/install.ps1 -useb | iex
复制代码


至此便能顺利完成 Deno 的安装,对应那几行执行的命令是如何执行的,你是否感到好奇呢?下面一起看看那几行脚本都干了什么事情!

PowerShell 脚本分析

我采用的是 PowerShell 命令进行的安装,这里就采用此案例进行解析。

1. 安装命令行分析
iwr https://x.deno.js.cn/install.ps1 -useb | iex
复制代码

执行内容是:通过 iwr 命令,获取https://x.deno.js.cn/install.ps1的内容,并以表达式的方式执行内容。

别名

这里的iwrInvoke-WebRequest的别名 ,用途是获取 http web 请求访问内容,-useb是执行网络请求的参数。iwr命令还存在更强大的功能,比如:添加 header,指定 Method,将获取的 content 输出到指定文件等等。(如感兴趣,可自行学习)


Invoke-WebRequest 语法:

Parameter Set: DefaultInvoke-WebRequest [-Uri] <Uri> [-Body <Object> ] [-Certificate <X509Certificate> ] [-CertificateThumbprint <String> ] [-ContentType <String> ] [-Credential <PSCredential> ] [-DisableKeepAlive] [-Headers <IDictionary> ] [-InFile <String> ] [-MaximumRedirection <Int32> ] [-Method <WebRequestMethod> {Default | Get | Head | Post | Put | Delete | Trace | Options | Merge | Patch} ] [-OutFile <String> ] [-PassThru] [-Proxy <Uri> ] [-ProxyCredential <PSCredential> ] [-ProxyUseDefaultCredentials] [-SessionVariable <String> ] [-TimeoutSec <Int32> ] [-TransferEncoding <String> {chunked | compress | deflate | gzip | identity} ] [-UseBasicParsing] [-UseDefaultCredentials] [-UserAgent <String> ] [-WebSession <WebRequestSession> ] [ <CommonParameters>]
复制代码


当然windows powershell还存在很多可以快速使用的别名,别名引用和使用标准范式是等效的。安装脚本里存在的别名还有:iexInvoke-Expression的别名,表达的是执行表达式。如果你想查看所有的别名,可以在控制台输入命令:alias,输出截图如图下


管道“|”

PowerShell 的管道都是基于对象,这点不同于传统的 Cmd 的管道是基于文本。此安装脚本属于面向对象的管道,每个命令的末尾可以使用新的命令对上个命令的结果做进一步处理,除非管道是以输出命令结束的。


加深管道理解,再看个命令行:

PS> ls | Sort-Object -Descending Name | Select-Object Name,Length,LastWriteTime | ConvertTo-Html | Out-File ls.html
复制代码

命令行执行的内容是:首先列出当前目录下的目录和文件,然后根据文件名降序排列,再投影文件名,文件大小,文件的修改时间,转换成 Html 格式,输出到当前目录的 ls.html。


至此完整解析了安装脚本命令行,下面看看具体的脚本内容是啥样的。

2. 安装脚本分析

首先看下完整的脚本,我们再分析内部的 PowerShell 语法执行流程。

#!/usr/bin/env pwsh# Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.# TODO(everyone): Keep this script simple and easily auditable.# 自定义变量$ErrorActionPreference = 'Stop'# $v,执行安装脚本指定的版本号if ($v) {  $Version = "${v}"}
if ($args.Length -eq 1) { $Version = $args.Get(0)}# $env:DENO_INSTALL 取环境变量指定的值(安装路径)$DenoInstall = $env:DENO_INSTALL$BinDir = if ($DenoInstall) { "$DenoInstall\bin"} else { "$Home\.deno\bin"}
$DenoZip = "$BinDir\deno.zip"$DenoExe = "$BinDir\deno.exe"$Target = 'x86_64-pc-windows-msvc'
# GitHub requires TLS 1.2[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12# 命令行未指令版本,则默认从请求获取最新版本的值if (!$Version) { $Version = (Invoke-WebRequest 'https://dl.deno.land/release-latest.txt' -UseBasicParsing).Content.Trim()}
$Version = $Version.Replace("v","")# 根据版本情况,取deno脚本的zip文件地址if ($Version -match "1.[0-6]+.[0-9]+") { $DenoUri = "https://cdn.jsdelivr.net/gh/justjavac/deno_releases/$Version/deno-${Target}.zip"} else { $DenoUri = "https://dl.deno.land/release/v${Version}/deno-${Target}.zip"}# 判断$BinDir是否存在,不存在则创建空目录if (!(Test-Path $BinDir)) { New-Item $BinDir -ItemType Directory | Out-Null}# 获取网络请求获取$DenoUri的内容,并输出到$DenoZipInvoke-WebRequest $DenoUri -OutFile $DenoZip -UseBasicParsing# 将DenoZip压缩文件提取到BindDir目录if (Get-Command Expand-Archive -ErrorAction SilentlyContinue) { # Expand-Archive 命令:将压缩文件提取到指定的目录,-Force:不用征求用户意见 Expand-Archive $DenoZip -Destination $BinDir -Force} else { if (Test-Path $DenoExe) { Remove-Item $DenoExe } # Add-Type cmdlet允许您在PowerShell会话中定义Microsoft.NET核心类。 # 然后可以使用New Object cmdlet实例化对象,并像使用任何.NET核心对象一样使用这些对象。 # 如果向PowerShell配置文件中添加add Type命令,则该类在所有PowerShell会话中都可用。 Add-Type -AssemblyName System.IO.Compression.FileSystem [IO.Compression.ZipFile]::ExtractToDirectory($DenoZip, $BinDir)}# 移除zip压缩文件Remove-Item $DenoZip# 当前用户 () 关联的环境变量保留的 Windows 操作系统注册表项$User = [EnvironmentVariableTarget]::User# 获取系统的环境变量Path$Path = [Environment]::GetEnvironmentVariable('Path', $User)# 系统环境变量Path不存在deno/bin,则添加上if (!(";$Path;".ToLower() -like "*;$BinDir;*".ToLower())) { [Environment]::SetEnvironmentVariable('Path', "$Path;$BinDir", $User) $Env:Path += ";$BinDir"}# 控制台输出Write-Output "Deno 安装成功"
复制代码

整体大体流程是这样的:

  1. 执行 Deno 安装脚本

  2. 取安装脚本命令行的版本号 $v ,未配置,则默认从请求获取最新版本号;

  3. 从环境变量 $env:DENO_INSTALL 取 Deno 安装路径,若存在,则使用 $env:DENO_INSTALL\binbin 安装路径 $BinDir ; 若未指定,则使用默认路径:$Home\.deno\bin 。并且当 $BinDir 不存在,则创建空目录。

  4. 根据版本号 $Version 规则,指定 Deno 脚本的下载地址:$DenoUri,从资源地址上可以看出是个 zip 压缩文件。

  5. 执行 Invoke-WebRequest 命令,将 $DenoUri 的请求内容输出到位置:$DenoZip

  6. $DenoZip 压缩文件提取到$BinDir,并删除 $DenoZip 压缩文件

  7. 取当前用户关联的环境变量保留的 Windows 操作系统注册表项,并获取变量 Path 所包含的所有值;判断 $BinDir 是否注册到 Path ,未注册,则自动注册。

  8. 控制台输出:Deno 安装成功,

最后,验证下是否安装成功,控制台输入命令并执行:deno help

总结

至此学习了 Deno 的安装流程,以及 PowerShell 是如何进行脚本安装,这里涉及大量的 PowerShell 语法,文章里面只是简单说明,若存在不准确的地方,欢迎指正。后续时间安排上,将安排波 PowerShell 基本编程入门学习文章。

发布于: 2021 年 02 月 24 日阅读数: 273
用户头像

梁龙先森

关注

脚踏V8引擎的无情写作机器 2018.03.17 加入

还未添加个人简介

评论 (1 条评论)

发布
用户头像
学习
2021 年 02 月 28 日 11:55
回复
没有更多了
深入理解Deno是如何借助PowerShell进行安装脚本