2019年11月24日
#
https://www.cnblogs.com/zbseoag/p/11736006.html
作者:AsReader
链接:https://www.zhihu.com/question/64845885/answer/1122345134
来源:知乎
https://www.cnblogs.com/chaos-li/p/11970713.html
https://www.jianshu.com/p/7403371162c1
0.前言
本文介绍了如何搭建Shibboleth,实现Shibboleth+Ldap的SSO解决方案
1.什么是Shibboleth
Shibboleth是一个基于标准的,实现组织内部或跨组织的网页单点登录的开源软件包。它允许站点为处于私有保护方式下的受保护的在线资源做出被通知的认证决定。
Shibboleth软件工具广泛使用联合的身份标准,主要是OASIS安全声称标记语言(SAML),来提供一个联合单点登录和属性交换框架。一个用户用他的组织的证书认证,组织(或IdP)传送最少的必要的身份信息给SP实现认证决定。Shibboleth也提供扩展的隐私功能,允许一个用户和他们的主站点来控制释放给每一个应用的属性。
Shibboleth项目作为一个Internet2中间件活动启动于2000年,这年晚些时候该项目和OASIS SAML工作组的工作相联系。Shibboleth1.0 于2003年发布,并快速被全世界的研究和教育机构使用。随着2005年SAML2.0的发布,2006年Shibboleth2.0也发布,SAML标准升级到包含所有的多边,由Shibboleth首创的元数据驱动方法。
Shibboleth作为开源软件开发,在Apache 软件许可证下发布。关于个别部件的更多信息可以在产品页面看到。
2.安装Shibboleth Identity Provider v3.2.1
- 切换成root
sudo su
2.下载Shibboleth Identity Provider v3.2.1
wget http://shibboleth.net/downloads/identity-provider/latest/shibboleth-identity-provider-3.2.1.tar.gz tar -xzvf shibboleth-identity-provider-3.2.1.tar.gz cd shibboleth-identity-provider-3.2.1
3.安装Shibboleth Idenentity Provider:
sh-3.2# ./install.sh Source (Distribution) Directory (press <enter> to accept default): [/Users/zhaoyu.zhaoyu/Applications/shibboleth-identity-provider-3.3.2] Installation Directory: [/opt/shibboleth-idp] Hostname: [localhost.localdomain] testdomain.com SAML EntityID: [https://testdomain.com/idp/shibboleth] Attribute Scope: [localdomain] Backchannel PKCS12 Password: Re-enter password: Cookie Encryption Key Password: Re-enter password: Warning: /opt/shibboleth-idp/bin does not exist. Warning: /opt/shibboleth-idp/dist does not exist. Warning: /opt/shibboleth-idp/doc does not exist. Warning: /opt/shibboleth-idp/system does not exist. Warning: /opt/shibboleth-idp/webapp does not exist. Generating Signing Key, CN = testdomain.com URI = https://testdomain.com/idp/shibboleth ... ...done Creating Encryption Key, CN = testdomain.com URI = https://testdomain.com/idp/shibboleth ... ...done Creating Backchannel keystore, CN = testdomain.com URI = https://testdomain.com/idp/shibboleth ... ...done Creating cookie encryption key files... ...done Rebuilding /opt/shibboleth-idp/war/idp.war ... ...done BUILD SUCCESSFUL Total time: 1 minute 14 seconds
(from now "{idp.home}" == /opt/shibboleth-idp/)
4.导入 JST library (status界面会用到):
cd /opt/shibboleth-idp/edit-webapp/WEB-INF/lib wget https://build.shibboleth.net/nexus/service/local/repositories/thirdparty/content/javax/servlet/jstl/1.2/jstl-1.2.jar cd /opt/shibboleth-idp/bin ./build.sh -Didp.target.dir=/opt/shibboleth-idp
3.安装指引
3.1 安装apache tomcat 8
1.切换成root
sudo su -
2.修改tomcat的%{CATALINA_HOME}/conf/server.xml
将8080端口和8443端口的地方分别改成80和443
<Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="443" />
3.生成证书文件
[chengxu@local]keytool -genkeypair -alias "tomcat" -keyalg "RSA" -keystore "./tomcat.keystore" 输入密钥库口令: 再次输入新口令: 您的名字与姓氏是什么? [Unknown]: cheng 您的组织单位名称是什么? [Unknown]: testdomain.com 您的组织名称是什么? [Unknown]: testdomain.com 您所在的城市或区域名称是什么? [Unknown]: 您所在的省/市/自治区名称是什么? [Unknown]: 该单位的双字母国家/地区代码是什么? [Unknown]: CN=cheng, OU=testdomain.com, O=testdomain.com, L=Unknown, ST=Unknown, C=Unknown是否正确? [否]: 是 输入 <tomcat> 的密钥口令 (如果和密钥库口令相同, 按回车): 再次输入新口令: [chengxu@local]
4.修改tomcat的%{CATALINA_HOME}/conf/server.xml,使支持https协议
<Connector port="443" protocol="org.apache.coyote.http11.Http11Protocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="/Users/chengxu/Shibboleth/tomcat/tomcat.keystore" keystorePass="xxx"/>
5.发布Idp Web Application到Tomcat 8 container
vim %{CATALINA_HOME}/conf/Catalina/localhost/idp.xml
<Context docBase="/opt/shibboleth-idp/war/idp.war" privileged="true" antiResourceLocking="false" swallowOutput="true"/>
4.配置host
vim /etc/host 127.0.0.1 testdomain.com
5.重启tomcat
%{CATALINA_HOME}/bin/catalina.sh stop
%{CATALINA_HOME}/bin/catalina.sh start
6.检测是否服务启动正常
访问https://testdomain/idp/status
或者/opt/shibboleth-idp/bin; ./status.sh
3.2 配置shibboleth连接ldap
编辑修改ldap.properties
vim /opt/shibboleth/conf/ldap.properties idp.authn.LDAP.authenticator = bindSearchAuthenticator idp.authn.LDAP.ldapURL = ldap://ldap.example.it:389 idp.authn.LDAP.useStartTLS = false idp.authn.LDAP.useSSL = false idp.authn.LDAP.baseDN = cn=Users,dc=example,dc=org idp.authn.LDAP.userFilter = (uid={user}) idp.authn.LDAP.bindDN = cn=admin,cn=Users,dc=example,dc=org idp.authn.LDAP.bindDNCredential = ###LDAP ADMIN PASSWORD###
6.修改shibboleth ldap配置
vim /opt/shibboleth/conf/services.xml 把 <value>%{idp.home}/conf/attribute-resolver.xml</value> 改为 <value>%{idp.home}/conf/attribute-resolver-full.xml</value>
vim /opt/shibboleth-idp/conf/attribute-resolver-full.xml 注释掉下列代码,如果已经注释掉了就不动了(有些版本已经注释了) <!-- <dc:StartTLSTrustCredential id="LDAPtoIdPCredential" xsi:type="sec:X509ResourceBacked"> <sec:Certificate>% {idp.attribute.resolver.LDAP.trustCertificates}</sec:Certificate> </dc:StartTLSTrustCredential> -->
重启tomcat
7.获取idp metadata.xml
https://testdomain.com/idp/shibboleth
注意metadata.xml文件中的validUntil属性,如果过期了则修改为未来的某个时间点
4.小结
至此我们完成了Shibboleth与LDAP集成的安装过程
下篇: 实现Shibboleth+Ldap到阿里云的单点登录
来自:https://yq.aliyun.com/articles/350531?tdsourcetag=s_pcqq_aiomsg&do=login&accounttraceid=87b0f203-5d81-4cb7-a986-49615e3962e2&do=login&do=login
在C盘根目录下建立以下批处理文件:
c:
cd C:\Program Files\Microvirt\MEmu
adb start-server
c:
cd C:\Android\Sdk\platform-tools
adb connect 127.0.0.1:21503
cd\
在命令提示符(管理员)下运行它就OK了。
flutter config --android-sdk 自己的android sdk路径Android SDK默认的安装地址为:
C:\Users\Administrator\AppData\Local\Android\SDK
现需要把它搬到 C:\Android\Sdk
操作如下:
1.把C:\Users\Administrator\AppData\Local\Android\SDK剪切复制到C:\Android\Sdk;
2.在FLutter sdk 目录下运行如下命令:
flutter config --android-sdk C:\Android\Sdk
3.在环境变量中把ANDROID_HOME改为C:\Android\Sdk;
重启,这样就OK了。
https://baijiahao.baidu.com/s?id=1630789160989369444&wfr=spider&for=pc
安装后还是无法联网的,需要以下步骤才能联网:
设置--》网络和互联网--》私人DNS -->把自动改为关闭
就能上网了。
===============CentOS 7.6================
1.查看系统时间
查看当前系统时间以及时区
结果是:
Mon Jul 8 09:23:31 UTC 2019
2.更改系统时间时区
timedatectl set-timezone Asia/Shanghai
3.再次查看
结果是:
Mon Jul 8 17:25:28 CST 2019
4.可以重启后查看,防止重启后失效
=======================
https://blog.csdn.net/qq_41855420/article/details/102750895?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
在这个地方,要把服务里的那几个VM启动,否则DHCP无法安装。
⑧、设置黑苹果Catalina 10.15
系统
https://www.jianshu.com/p/d58dab805ca6
keytool -genkey -v -keystore ./key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key
apk 输出在:
C:\Users\Administrator\AndroidStudioProjects\flutter_app\build\app\outputs\apk\release
key.properties
storePassword=123456
keyPassword=123456
keyAlias=key
storeFile=C:/Users/Administrator/AndroidStudioProjects/flutter_app/key.jks
build.gradle
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
def keystorePropertiesFile = rootProject.file("key.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
compileSdkVersion 28
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.flutter_app"
minSdkVersion 16
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
//signingConfig signingConfigs.debug
signingConfig signingConfigs.release
}
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
参见:
https://www.jianshu.com/p/2893f2b52eee
https://www.cnblogs.com/duanzb/p/11188979.html
即是在PATH中增加2个:
C:\Flutter\flutter1.12.13\.pub-cache\bin
C:\Flutter\flutter1.12.13\bin\cache\dart-sdk\bin
打开项目总文件夹运行,不要打开上一级目录运行F:\fluterapp\hellow_horld(项目名)这里打开F:\fluterapp 不要在这里打开
https://blog.csdn.net/qq_31659129/article/details/97244526
解决办法:
修改以下文件
C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\src\win_delay_load_hook.c
增加以下代码,到第一个#include前
#ifndef DELAYIMP_INSECURE_WRITABLE_HOOKS#define DELAYIMP_INSECURE_WRITABLE_HOOKS#endif
参考:
https://github.com/nodejs/node-gyp/issues/949
https://github.com/Automattic/node-canvas/issues/619
————————————————
版权声明:本文为CSDN博主「Amatig」的原创文章,遵循CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cooltigerkin/article/details/51807588
VS2015最高支持14393版本的SDK,之后的从15063起就必须要VS2017,很多人出现VS找不到rc.ex和cl.exe的问题,就是没有安装SDK或安装了VS不支持的SDK版本;这个问题有人在知乎上提问过“如何将独立安装的win10SDK与vs2015建立联系?“
VS2015不完全支持Win10的某些项目编译,比如应用商店应用、1703、1709的驱动程序,但是VS2017太难用了,所以我还是坚持用2015
解决办法:
卸载新版本WinSDK,安装14393版本的SDK
或
卸载VS2015安装VS2017
————————————————
版权声明:本文为CSDN博主「楼顶上的猫」的原创文章,遵循CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_30113467/article/details/100013766
此前我的Ubuntu不是wubi方式安装的,因为听说此方式安装有多种缺陷,于是我选择U盘安装。这时想要卸载Ubuntu了,想到卸载这个也会有些小阻碍,就写下这篇博文表示记录一下Ubuntu的正确卸载方法。
在每次开机时都会有GURB菜单,这表示写入到安装Ubuntu的时候把GURB写入到了MBR,所以卸载Ubuntu前首先需要将MBR重写,去掉Ubuntu的GURB。如果朋友们不进行这一步把Ubuntu强行干掉,会让windows也直接GG。
重写MBR有两种方法:
一、放入Windows的安装盘,进入Windows安装程序,进入恢复控制台,输入命令fixmbr。
二、使用MbrFix工具进行修复。
我选择的是MbrFix,下载地址:http://www.cnitblog.com/Files/CoffeeCat/MbrFix.rar
下载完成后运行命令行,然后进入存放MbrFix.exe的目录下,输入指令MbrFix /drive 0 fixmbr /yes,重启就可以直接进入windows了。
ps:输入命令行提示"function failed.error 5:拒绝访问"如何解决?
找到MbrFix.exe,右击属性,进入兼容性选项卡,勾选"以管理员身份运行此程序",确定退出,然后重新输入指令即可解决。
搞定第一步之后,右键我的电脑进入管理,磁盘管理,如果是自己安装的Ubuntu,应该知道在安装的时候分配了几个分区在此系统上,如果只是双系统,除了Windows下有标注卷名的其余应该都是Ubuntu的分区。右键Ubuntu分区,删除卷,标注蓝条会变成绿条,把几个分区全部删除完成,右键新加卷一步一步完成恢复成为Windows的逻辑分区了。
来自:https://www.cnblogs.com/-Yvan/p/4975326.html
1.把 "Gateway": "/ip4/127.0.0.1/tcp/8080"修改为:"Gateway": "/ip4/0.0.0.0/tcp/8080",这样本机就可以用192.168WEB访问了。
2.把WINDOWS防火墙入站的8080端口打开,这样在局域网就能访问了。
https://blog.csdn.net/qq_25870633/article/details/82027510
在之前的博客中提到解决此问题的方法是进入mysql的命令窗口,执行set global show_compatibility_56=on;
但是该方法只能生效一次,当电脑重启或者mysql服务重启的时候,就得重新再设置一次,下面提供一个永久生效的方法,即不通过上述方法,而是修改mysql的配置文件,找到my.ini的配置文件,在文件的最后添加:show_compatibility_56 = 1 即可。
本人的my.ini的文件路径是:C:\ProgramData\MySQL\MySQL Server 5.7\my.ini
————————————————
版权声明:本文为CSDN博主「让爱远行2015」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011065164/article/details/53393348
cnpm install -g solc@0.4.22
https://remix.ethereum.org/
http://remix.hubwiz.com/
https://ethereum.github.io/
最新内容会更新在主站深入浅出区块链社区
原文链接:Web3与智能合约交互实战
写在前面
在最初学习以太坊的时候,很多人都是自己创建以太坊节点后,使用geth与之交互。这种使用命令行交互的方法虽然让很多程序员感到兴奋(黑客帝国的既视感?),但不可能指望普通用户通过命令行使用Dapp。因此,我们需要一种友好的方式(比如一个web页面)来与智能合约交互,于是问题的答案就是web3.js
。
Web3.js
Web3.js是以太坊官方的Javascript API,可以帮助智能合约开发者使用HTTP或者IPC与本地的或者远程的以太坊节点交互。实际上就是一个库的集合,主要包括下面几个库:
web3-eth
用来与以太坊区块链和智能合约交互web3-shh
用来控制whisper协议与p2p通信以及广播web3-bzz
用来与swarm协议交互web3-utils
包含了一些Dapp开发有用的功能
Web3与geth通信使用的是 JSON-RPC ,这是一种轻量级的RPC(Remote Procedure Call)协议,整个通信的模型可以抽象为下图。
搭建测试链
在开发初期,我们并没有必要使用真实的公链,为了开发效率,一般选择在本地搭建测试链。在本文我们选择的Ganache(在此之前使用的是testrpc,Ganache属于它的升级版),一个图形化测试软件(也有命令行版本),可以一键在本地搭建以太坊区块链测试环境,并且将区块链的状态通过图形界面显示出来,Ganache的运行界面如下图所示。
从图中可以看到Ganache会默认创建10个账户,监听地址是http://127.0.0.1:7545
,可以实时看到Current Block
、Gas Price
、Gas Limit
等信息。
创建智能合约
目前以太坊官方全力支持的智能合约开发环境是Remix IDE,我们在合约编辑页面编写如下代码:
pragma solidity ^0.4.21; contract InfoContract { string fName; uint age; function setInfo(string _fName, uint _age) public { fName = _fName; age = _age; } function getInfo() public constant returns (string, uint) { return (fName, age); } }
代码很简单,就是简单的给name
和age
变量赋值与读取,接下来切换到 run 的 tab 下,将Environment
切换成Web3 Provider
,并输入我们的测试链的地址http://127.0.0.1:7545
,这里对这三个选项做一简单说明:
Javascript VM
:简单的Javascript虚拟机环境,纯粹练习智能合约编写的时候可以选择Injected Web3
:连接到嵌入到页面的Web3,比如连接到MetaMaskWeb3 Provider
:连接到自定义的节点,如私有的测试网络。
如果连接成功,那么在下面的Account
的选项会默认选择 Ganache 创建的第一个账户地址。接下来我们点击Create
就会将我们的智能合约部署到我们的测试网中。接下来 Remix 的页面不要关闭,在后面编写前端代码时还要用到合约的地址以及ABI
信息。
安装Web3
在这之前,先在终端创建我们的项目:
> mkdir info > cd info
接下来使用 node.js 的包管理工具 npm 初始化项目,创建package.json
文件,其中保存了项目需要的相关依赖环境。
> npm init
一路按回车直到项目创建完成。最后,运行下面命令安装web.js:
> npm install web3
注意: 在实际安装过程中我发现web3在安装完成后并没有 /node_modules/web3/dist/we3.min.js
文件,这个问题在 issue#1041中有体现,但官方好像一直没解决。不过可以在这里下载所需的文件,解压后将dist
文件夹的内容拷贝到 /node_modules/web3
路径下。
创建 UI
在项目目录下创建index.html
,在这里我们将创建基础的 UI,功能包括name
和age
的输入框,以及一个按钮,这些将通过 jQuery 实现:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <link rel="stylesheet" type="text/css" href="main.css"> <script src="./node_modules/web3/dist/web3.min.js"></script> </head> <body> <div class="container"> <h1>Info Contract</h1> <h2 id="info"></h2> <label for="name" class="col-lg-2 control-label">Name</label> <input id="name" type="text"> <label for="name" class="col-lg-2 control-label">Age</label> <input id="age" type="text"> <button id="button">Update Info</button> </div> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script> <script> // Our future code here.. </script> </body> </html>
接下来需要编写main.css
文件设定基本的样式:
body { background-color:#F0F0F0; padding: 2em; font-family: 'Raleway','Source Sans Pro', 'Arial'; } .container { width: 50%; margin: 0 auto; } label { display:block; margin-bottom:10px; } input { padding:10px; width: 50%; margin-bottom: 1em; } button { margin: 2em 0; padding: 1em 4em; display:block; } #info { padding:1em; background-color:#fff; margin: 1em 0; }
使用Web3与智能合约交互
UI 创建好之后,在<script>
标签中间编写web.js
的代码与智能合约交互。首先创建web3
实例,并与我们的测试环境连接:
<script> if (typeof web3 !== 'undefined') { web3 = new Web3(web3.currentProvider); } else { // set the provider you want from Web3.providers web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545")); } </script>
这段代码是web3.js Github提供的样例,意思是如果web3
已经被定义,那么就可以直接当作我们的 provider 使用。如果没有定义,则我们手动指定 provider。
这里可能会存在疑问:为什么 web3 会被事先定义呢?实际上,如果你使用类似 MetaMask(一个 Chrome 上的插件,迷你型以太坊钱包)这样的软件,provider 就会被自动植入。
在上面代码的基础上,接下来设置默认的以太坊账户:
web3.eth.defaultAccount = web3.eth.accounts[0];
在上文中我们使用 Ganache 已经创建了 10 个账户了,这里我们选择第一个账户当作默认账户。
接下来需要让我们的web3
知道我们的合约是什么样的,这里需要用到合约的 ABI(Application Binary Interface)。ABI
可以使我们调用合约的函数,并且从合约中获取数据。
在上文中我们已经在 Remix 中创建了我们的合约,这时重新回到 Remix,在 Compile 的 tab 下我们点击Details
出现的页面中我们可以拷贝合约的ABI
,如下图所示。
将其复制到代码中:
var infoContract = web3.eth.contract(PASTE ABI HERE!);
接下来转到 run 的tab,拷贝合约的地址,将其复制到下面的代码中:
var info = InfoContract.at('PASTE CONTRACT ADDRESS HERE');
完成这些我们就可以调用合约中的函数了,下面我们使用 jQuery 与我们的合约进行交互:
info.getInfo(function(error, result){ if(!error) { $("#info").html(result[0]+' ('+result[1]+' years old)'); console.log(result); } else console.error(error); }); $("#button").click(function() { info.setInfo($("#name").val(), $("#age").val()); });
以上的代码就简单地实现了对合约中两个函数的调用,分别读取和显示name
和age
变量。
到此我们就完成了全部的代码,完整代码可以在 InfoContract 中找到。在浏览器中打开index.html
测试效果如下图(输入名字和年龄后刷新)。
本文的作者是盖盖,他的微信公众号: chainlab
参考文献
☛ 深入浅出区块链 - 系统学习区块链,打造最好的区块链技术博客。
https://blog.csdn.net/xiaomu_347/article/details/80729892
GitHub 在开源世界的受欢迎程度自不必多言。再加上前阵子,GitHub 官方又搞了个大新闻:私有仓库改为免费使用,这在原来可是需要真金白银的买的。可见微软收购后,依然没有改变 GitHub 的定位,甚至还更进一步。
花开两朵,各表一枝。我们今天想要聊的并不是 GitHub 多么厉害,而是你怎么能把 GitHub 用得很厉害。
你在 GitHub 上搜索代码时,是怎么样操作的呢?是不是就像这样,直接在搜索框里输入要检索的内容,然后不断在列表里翻页找自己需要的内容?
或者是简单筛选下,在左侧加个语言的过滤项。
再或者改变一下列表的排序方式
这就是「全部」了吗?
一般的系统检索功能,都会有一个「高级搜索」的功能。需要在另外的界面里展开,进行二次搜索之类的。 GitHub 有没有类似的呢?
答案是肯定的。做为一个为万千工程师提供服务的网站,不仅要有,而且还要技术范儿。
如果我们自己开发一个类似的应用,会怎样实现呢?
带着思路,咱们一起来看看,GitHub 是怎样做的。
这里我们假设正要学习 Spring Cloud,要找一个 Spring Cloud 的 Demo 参考练手。
1. 明确搜索仓库标题、仓库描述、README
GitHub 提供了便捷的搜索方式,可以限定只搜索仓库的标题、或者描述、README等。
以Spring Cloud 为例,一般一个仓库,大概是这样的
其中,红色箭头指的两个地方,分别是仓库的名称和描述。咱们可以直接限定关键字只查特定的地方。比如咱们只想查找仓库名称包含 spring cloud 的仓库,可以使用语法
in:name 关键词
如果想查找描述的内容,可以使用这样的方式:
in:descripton 关键词
这里就是搜索上面项目描述的内容。
一般项目,都会有个README文件,如果要查该文件包含特定关键词的话,我想你猜到了
in:readme 关键词
2. 明确搜索 star、fork 数大于多少的
一个项目 star 数的多少,一般代表该项目有受欢迎程度。虽然现在也有垃圾项目刷 star ,但毕竟是少数, star 依然是个不错的衡量标准。
stars:> 数字 关键字。
比如咱们要找 star 数大于 3000 的Spring Cloud 仓库,就可以这样
stars:>3000 spring cloud
如果不加 >= 的话,是要精确找 star 数等于具体数字的,这个一般有点困难。
如果要找在指定数字区间的话,使用
stars: 10..20 关键词
fork 数同理,将上面的 stars 换成fork,其它语法相同
3. 明确搜索仓库大小的
比如你只想看个简单的 Demo,不想找特别复杂的且占用磁盘空间较多的,可以在搜索的时候直接限定仓库的size。
使用方式:
size:>=5000 关键词
这里注意下,这个数字代表K, 5000代表着5M。
4. 明确仓库是否还在更新维护
我们在确认是否要使用一些开源产品,框架的时候,是否继续维护是很重要的一点。如果已经过时没人维护的东西,踩了坑就不好办了。而在 GitHub 上找项目的时候,不再需要每个都点到项目里看看最近 push 的时间,直接在搜索框即可完成。
元旦刚过,比如咱们要找临近年底依然在勤快更新的项目,就可以直接指定更新时间在哪个时间前或后的
通过这样一条搜索pushed:>2019-01-03 spring cloud
咱们就找到了1月3号之后,还在更新的项目。
你是想找指定时间之前或之后创建的仓库也是可以的,把pushed改成created就行。
5. 明确搜索仓库的 LICENSE
咱们经常使用开源软件,一定都知道,开源软件也是分不同的「门派」不同的LICENSE。开源不等于一切免费,不同的许可证要求也大不相同。 2018年就出现了 Facebook 修改 React 的许可协议导致各个公司纷纷修改自己的代码,寻找替换的框架。
例如咱们要找协议是最为宽松的 Apache License 2 的代码,可以这样
license:apache-2.0 spring cloud
其它协议就把 apache-2.0 替换一下即可,比如换成mit之类的。
6. 明确搜索仓库的语言
比如咱们就找 Java 的库, 除了像上面在左侧点击选择之外,还可以在搜索中过滤。像这样:
language:java 关键词
7.明确搜索某个人或组织的仓库
比如咱们想在 GitHub 上找一下某个大神是不是提交了新的功能,就可以指定其名称后搜索,例如咱们看下 Josh Long 有没有提交新的 Spring Cloud 的代码,可以这样使用
user:joshlong
组合使用一下,把 Java 项目过滤出来,多个查询之间「空格」分隔即可。
user:joshlong language:java
找某个组织的代码话,可以这样:
org:spring-cloud
就可以列出具体org 的仓库。
作者:西安北大青鸟
链接:https://www.jianshu.com/p/74ae16db62af
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
https://blog.csdn.net/Hanani_Jia/article/details/77950594源博客地址
首先,我先对GitHub来一个简单的介绍,GitHub有一个很强大的功能就是,你在服务器上边可以创建一个库(稍后会介绍怎么创建),写代码是一件很重的任务,尤其是很多人完成一个很大的项目的时候,就十分的复杂,一群人一起来写某个项目,大家完成的时间,完成的进度都是不相同的,你写一点我写一点,甚至可能你今天写的出现了错误,影响到了我昨天写的代码,最后怎么才能将大家的代码轻松的汇总起来,又怎么在汇总所有人的代码之后发现错误等等一系列问题。这样我们就用到了GitHub这个软件。我们在GitHub服务器上有一个主仓库,这里用来储存你的所有代码,如果不付费的话是所有人都可以看的,如果你不想让别人看到你的代码,可以选择付费仓库。我们创建了主仓库之后,就可以在电脑上创建分支,之后你就可以在电脑上完成自己的代码,写完之后直接同步在电脑的分支,当你认为可以上传的自己的主仓库时,就可以申请更新,当通过审核的时候,你代码就出现在了自己的主仓库中,这样全世界的程序员都可以查看你的代码。全世界现在已经有300万的注册用户,甚至还有一些相当知名的开源项目也在其中公布代码。在GitHub上你可以看到很多计算机领域的精英所分享的自己的代码。这是GitHub的两个主要优点,适合团队协作,以及下载其他优秀者的代码。
今天,GitHub已是:一个拥有143万开发者的社区。其中不乏Linux发明者Torvalds这样的顶级黑客,以及Rails创始人DHH这样的年轻极客。
· 这个星球上最流行的开源托管服务。目前已托管431万git项目,不仅越来越多知名开源项目迁入GitHub,比如Ruby on Rails、jQuery、Ruby、Erlang/OTP;近三年流行的开源库往往在GitHub首发,例如:BootStrap、Node.js、CoffeScript等。alexa全球排名414的网站。
https://github.com/ 这是GitHub的官方网站,在官网上可以注册属于自己的GitHub账号,网上是全英文的,对于英语不好的同学建议使用谷歌浏览器,谷歌浏览器可以翻译网页变为中文使用起来十分方便。
通过简单的步骤之后你就会有一个属于自己的GitHub账号。再简单注册完成之后会需要验证你所输入的邮箱才能正常使用你的GitHub。
在注册完成之后,完成一些简单的设置之后,你需要创建一个属于自己的库
在登陆自己的GitHub账号之后,在网页右上角的小加号是用来创建自己的库的按钮,之后的步骤将网页翻译成中文之后,按提示进行创建自己的库即可。
第一个框是自己为自己的库起一个名字,第二个框是自己对库的一个简单介绍
在创建完成自己的库之后,下面就要让自己的电脑克隆一个自己所创建的库,方面自己电脑上的代码同步到GitHub你所创建的库当中。
为了实现,就需要安装一个软件,Git Bash。
下面我就介绍一下这个软件的安装,以及简单的配置。
git-scm.com 首先进入GitHub官网,下载适合自己电脑的版本
下载完安装包之后运行
在安装过程中直接默认选项即可。
在对git bash进行配置的时候大多数新手都是一头雾水,下面我对配置的每一步就会有详细的记录。代码我也是从网上和学长那边要来的。
我第一次打开软件后看到这个界面也是一脸懵逼的,然后通过查阅了各种各样的资料之后才有了一些思路。
首先要在本地创建一个ssh key 这个的目的就是你现在需要在你电脑上获得一个密匙,就是咱们平时的验证码一样的东西,获取之后,在你的GitHub账号里边输入之后,你的电脑就和你的GitHub账号联系在一起了,这样以后就可以十分方便的通过Git bash 随时上传你的代码。下边介绍一下如果获得这个钥匙,又是如何输入到你的GitHub里边的呢。
很多人第一次打开这个GitHub的时候一脸懵逼,认为这是什么。对于一个新手来说看到这个是没有任何思路,没有任何想法的。
这一栏 开始是你的计算机的名字在我这里就是Hanani @后边的内容是你的计算机型号,很多时候有的人打开之后@后边是乱码,这个时候也不要在意,因为有些电脑型号是中文的,可能在显示的时候出现了问题,不影响你后期的操作。
接下来,就要开始获取属于你自己的密匙。在git bash中所有功能都是通过简单的一些代码来实现的。获取密匙的时候需要输入
$ ssh-keygen -t rsa -C "your_email@youremail.com"
需要输入这个代码,引号内需要改成你在注册GitHub的时候绑定的邮箱账号。之后会有一些简单的让你确认的操作,之后让你会提示操作路径、密码等等,一般情况下就直接按回车一路过就可以。
如果之后你出现了这个界面之后,就说明你的密匙已经成功创建了。现在你就需要去他刚刚显示的存储位置打开它,把其中的内容复制出来。
在.ssh这个文件夹中
之后你会看到这些内容,有的人会在id_rsa后边带有一个pub,之前看网上教程需要找到带pub的文件,因为我在生成后没有带.pub的文件,怀着忐忑的心打开id_rsa后发现这里边的密匙也是可以使用的。打开id_rsa的时候需要用记事本的方式打开。
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDIskXqZF3SSFtACK6zoNGJabikTBC3kig6+4j4dCq1tswhA9YkuJCi0WpRmGYWBQ67dyT2or7RedFZlULLZN3nL6AWlo5V2jRXw4WQxCon2rU1p122wmiTzqYOfsykjwullWV4bYcZU4n77A4/9WwlSqZCpEbcdwV8IMkvwfJUInSWqTvmYMcKTWu8yad5DZ2v7LBWfgsL/Tfx7aEB8UjDNJ6SPw30Yijy+62YrftYGgbuwoiL9hDNGO2LfjgOkglHTBJaZe31uQLLWc5uCzd+7Dgh7RaKMmeuz2Uv7yqm/IEU9jH8cPMR9YRPIhmzg38G2s9ILn27QqW9j1hrFY1V 15229020556@163.com
这就是我所获取的密匙,打开之后很长的一段,不要惊讶,没有问题,这就是你所需要的密匙。
现在你就需要登录到你的GitHub上边添加这个密匙,
打开你GitHub的设置界面,找到SSH and GPG keys这个选项之后,在网页右上角有一个添加新的SSH keys 点击
这里的title 是让你给你的密匙起一个名字,根据个人喜好,什么名字都可以,然后把你在刚刚文件中复制的密匙,填写在下边的大框里。保存即可。
之后你就可以回到你的Git bash上边了
然后输入上边的代码,来检查是否成功绑定。第一次绑定的时候输入上边的代码之后会提示是否continue,在输入yes后如果出现了:You've successfully authenticated, but GitHub does not provide shell access 。那就说明,已经成功连上了GitHub。接下来还需要简单的设置一些东西。
输入上边的代码,name最好和GitHub上边的一样,email是一定要是注册GitHub的那个邮箱地址
这两个的顺序可以颠倒,没有固定的顺序。
下面就要将你的库克隆下来到本地电脑中,方便以后进行上传代码。
在库创建完成之后 会有一个网址出现在网页中。
个人习惯将自己的文件储存在d盘之中,所以你先需要将git bash定位在d盘中
在git bash中输入 cd /D 注意盘名字一定要是大写。如不输入这个语句 不给git bash定位的话,默认的本地文件位置是在c盘中。
输入之后会出现/D说明定位成功。
之后输入
git clone后边的网址就是你创建库成功之后的网址
之后打开我所定位的D盘
可以看到,D盘中已经有以我的库名所创建的文件夹了。
打开这个文件夹,然后在其中创建一个任意格式,任意名称的文件。
之后重新定位git 把书 的位置,定位在你库的文件夹。
之后输入ls语句 ls的作用是查看你目前所定位的文件夹中的文件,现在可以看出来,我刚刚所创建的test文件已经出现了。
然后输入 git add test.txt
之后输入然后git commit -m "cc" 引号内的内容可以随意改动,这个语句的意思是 给你刚刚上传的文件一个备注,方便查找记忆而已
输入之后出现以上情况,然后在输入git push origin master 之后会出现一个
界面,在这里登陆你之前注册的GitHub账号之后点击login。
如果之后出现这种情况的话,就是登陆失败了,这时候你就需要输入你GitHub的账号名称
输入之后会出现这个界面,然后再次输入你的GitHub密码。
出现类似界面,你就可以欢呼了,代表你成功了。
现在打开你的GitHub网站,找到你创建的库
发现今天的格子已经绿了,说明你已经上传了你刚刚所创建的文件。
再之后,你只需要将你的代码,放到库的对应的文件夹中,然后使用 先CD到你库里面,再git add 、git commit -m " " 、最后git push origin master,将你的代码提交就可以了。
同样我感觉网页版的github更适合新手小白,https://blog.csdn.net/hanani_jia/article/details/79855429 这是我写的一篇网页版github的简单操作,需要的可以看一下。
if(!deployed.address) {
^
TypeError: Cannot read property 'address' of undefined
解决办法:调整gas的值就好了。
http://www.360doc.com/content/18/1014/17/16619343_794677023.shtml
https://blog.csdn.net/luoye4321/article/details/82531212
https://blog.csdn.net/weixin_34055787/article/details/89733910
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yezishuang/article/details/91489354
1.Visual Studio 2015 专业版和企业版下载
https://www.cnblogs.com/bwlluck/p/5514424.html
https://www.cnblogs.com/wgscd/p/4671374.html
2.Visual Studio 2013
https://www.cnblogs.com/abeam/p/6781006.html
3.Visual Studio 2017
https://www.cnblogs.com/jian-pan/p/6942635.html
Microsoft Visual Studio Enterprise 2017 企业版
KEY:NJVYC-BMHX2-G77MM-4XJMR-6Q8QF
Microsoft Visual Studio Professional 2017 专业版
KEY:KBJFW-NXHK6-W4WJM-CRMQB-G3CDH
4.Visual Studio 2019
https://www.cnblogs.com/zengxiangzhan/p/vs2015.html
https://visualstudio.microsoft.com/zh-hans/downloads/ (下载地址)
Visual Studio 2019 Enterprise
BF8Y8-GN2QH-T84XB-QVY3B-RC4DF
Visual Studio 2019 Professional
NYWVH-HT4XC-R2WYW-9Y3CM-X4V3Y
https://blog.csdn.net/qq_27317475/article/details/80894593
以前的genesis.json的文件差不多是这样的:
{
"config": {
"chainId": 10,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"alloc" : {},
"coinbase" : "0x0000000000000000000000000000000000000000",
"difficulty" : "0x00000002",
"extraData" : "",
"gasLimit" : "0x2fefd8",
"nonce" : "0x0000000000000042",
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00"
}
用这个创世块的描述文件初始化时,出现错误:
Fatal: Failed to write genesis block: unsupported fork ordering: eip150Block not enabled, but eip155Block enabled at 0
百度吧,没有一个解决办法。
后来用Puppeth命令创建json文件,并做了修改,如下所示:
{
"config": {
"chainId": 666,
"homesteadBlock": 0,
"eip150Block": 0,
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"ethash": {}
},
"nonce": "0x0",
"timestamp": "0x5ddf8f3e",
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x47b760",
"difficulty": "0x00002",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"alloc": { }
},
"number": "0x0",
"gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
初始化:
geth --identity "MyEth" --rpc --rpcport "8545" --rpccorsdomain "*" --datadir gethdata --port "30303" --nodiscover --rpcapi "db,eth,net,personal,web3" --networkid 1999 init genesis.json
控制台:
geth --identity "MyEth" --rpc --rpcport "8545" --rpccorsdomain "*" --datadir gethdata --port "30303" --nodiscover --rpcapi "db,eth,net,personal,web3" --networkid 1999 --dev.period 1 console
建立用户:
>personal.newAccount();
挖矿:
miner.start();
终于顺利挖到了人生第一桶金。
第一步 安装geth
下载地址:https://ethereum.github.io/go-ethereum/downloads/
点击安装勾选development tools
第二步 创建您的帐户
在当前文件夹下创建node1文件夹
创建一个账户(也称为钱包)
Devnet $ geth --datadir node1/ account new
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase: 输入你的密码
Repeat passphrase: 确认你的密码
Address: {08a58f09194e403d02a1928a7bf78646cfc260b0}
第三步 geth命令创建您的Genesis文件
生成的文件是用于初始化区块链的文件。第一个块叫做创世块,是根据genesis.json文件中的参数生成的。
Geth安装后目录下有很多可执行文件如puppeth或bootnode。你可以在Geth github上找到完整的列表。
Puppeth可以创建创世区块的json文件。
开始使用Puppeth:
1、win键 + r 进入cmd命令行,进入到安装geth的文件夹执行 puppeth 然后顺序执行下面操作
2、Please specify a network name to administer (no spaces, please)
> devnet
(这里随便填写一个网络管理名称即可,如有需要后面可以通过--network重新设置)
What would you like to do? (default = stats)
1. Show network stats
2. Configure new genesis
3. Track new remote server
4. Deploy network components
> 2
(这里选择2,回车,配置新的创世区块)
3、Which consensus engine to use? (default = clique)
1. Ethash - proof-of-work
2. Clique - proof-of-authorit
> 1
(这里选择pow共识机制)
4、Which accounts should be pre-funded? (advisable at least one)
> 0x1234567890123456789012345678901234567890
(这个是设置预分配以太坊的账户,建议设置一个有私钥的地址可以后面测试使用,设置好后再按一次回车)
5、Specify your chain/network ID if you want an explicit one (default = random)
> 666
(这里就是链的chainId,可以随意输入也可以不输直接回车默认随机数字)
6、What would you like to do? (default = stats)
- Show network stats
- Manage existing genesis
- Track new remote server
- Deploy network components
> 2
(管理已拥有的创世块)
7、 1. Modify existing fork rules
2. Export genesis configuration
3. Remove genesis configuration
> 2
(选择导出创世配置)
8、Which file to save the genesis into? (default = devnet.json)
> ./genesis.json
(导出的路径及文件名)
OK,到这里创世json文件创建完成了
第四步 geth命令初始化节点
现在我们有了这个genesis.json文件,可以初始化创世块了!
进入到geth安装文件夹下执行
geth --datadir node1/ init genesis.json
第五步 bootnode命令操作
bootnode唯一的目的是帮助节点发现彼此(记住,以太坊区块链是一个对等网络)
初始化 bootnode
bootnode -genkey boot.Key
启动bootnode服务
bootnode -nodekey boot.key -addr:30310
随意使用任何您喜欢的端口,但请避免使用主流端口(例如HTTP)。30303用于公共以太坊网络。
第六步 geth命令启动节点
geth --datadir .\node1\ --syncmode 'full' --port 30311 --rpc --rpcaddr '127.0.0.1' --rpcport 8501 --rpcapi 'personal,db,eth,net,web3,txpool,miner' --bootnodes 'enode://ca88962dbcc8eb0c7587789866f21db68cdf32ad1ea890fe0d9f8fe010f7e9afe2e6a88d5c9d418be61a10b8a31b1e7c55213bb426dab91596ae36bd7d559333@127.0.0.1:30310' --networkid 666
参数解释:
--syncmode 'full' 有助于防止错误丢弃错误的传播块。
--port 是node1的端口
--rpcapi 允许RPC调用的模块
--bootnodes 要连接的bootnode
--networkId genesis.json文件中的chainId
第七步 与您的节点进行交互
通过RPC方式
$ cd devnet
devnet$ geth attach 'http://localhost:8501'
Welcome to the Geth JavaScript console!
instance: Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9
coinbase: 0x87366ef81db496edd0ea2055ca605e8686eec1e6
at block: 945 (Sat, 10 Feb 2018 21:16:14 CET)
modules: eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
使用Geth控制台
>net.version
"1515"
> eth.blockNumber
1910
> eth.coinbase
"0x87366ef81db496edd0ea2055ca605e8686eec1e6"
> eth.sendTransaction({'from':eth.coinbase, 'to':'0x08a58f09194e403d02a1928a7bf78646cfc260b0', 'value':web3.toWei(3, 'ether')})
"0x299a99baa1b39bdee5f02e3c660e19e744f81c2e886b5fc24aa83f92fe100d3f"
>eth.getTransactionReceipt("0x299a99baa1b39bdee5f02e3c660e19e744f81c2e886b5fc24aa83f92fe100d3f")
{
blockHash: "0x212fb593980bd42fcaf3f6d1e6db2dd86d3764df8cac2d90408f481ae7830de8",
blockNumber: 2079,
contractAddress: null,
cumulativeGasUsed: 21000,
from: "0x87366ef81db496edd0ea2055ca605e8686eec1e6",
gasUsed: 21000,
logs: [],
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
status: "0x1",
to: "0x08a58f09194e403d02a1928a7bf78646cfc260b0",
transactionHash: "0x299a99baa1b39bdee5f02e3c660e19e744f81c2e886b5fc24aa83f92fe100d3f",
transactionIndex: 0
}
> exit
(退出)
来自:https://www.haowenbo.com/articles/2019/07/24/1563963176492.html
有了npm 我们能够简单的一段代码就下载我们需要的包,但是包是不断更新的,
所以我们要关注包的版本信息;
现在,假设我们需要 jquery ,但是jquery现在有很多版本,我们如何通过npm查看呢?
要知道,现在的jquery包在npm服务器的上,我们使用下面的命令查看:
第一种方式:使用npm view jquery versions
这种方式可以查看npm服务器上所有的jquery版本信息;
第二种方式:使用npm view jquery version
这种方式只能查看jquery的最新的版本是哪一个;
第三种方式:使用npm info jquery
这种方式和第一种类似,也可以查看jquery所有的版本,
但是能查出更多的关于jquery的信息;
假设现在我们已经成功下载了jquery,过了一段时间,我忘记了下载的jquery的版本信息,
这个时候,我们就需要查看本地下载的jquery版本信息,怎么做呢?
第一种方式:npm ls jquery 即可(查看本地安装的jQuery),下面我的本地没有安装jquery,
所以返回empty的结果;
第二种方式:npm ls jquery -g (查看全局安装的jquery)
总结:上面我们了解了如何通过npm 来查看我们需要的包的版本信息,
既可以查看远端npm 服务器上的,也可以查看本地的;
————————————————
版权声明:本文为CSDN博主「cvper」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cvper/article/details/79543262
1.在你想更改的目录下新建两个文件夹:node_global 和 node_cache
2.启动cmd依次执行以下两条命令
npm config set prefix "XXX\XXX\node_global"
npm config set cache "XXX\XXX\node_cache"
路径均为绝对路径
3.更改环境变量,计算机右击 --> 属性 --> 高级系统设置 --> 环境变量
在下边的系统变量里新建一条记录,变量名为NODE_PATH 值为XXX\XXX\node_global\mode_modules
在上边的环境变量,更改PATH的值为XXX\XXX\node_global\
(路径为刚才第二步中node_global文件夹的绝对路径)
作者:招猫逗狗追兔子
链接:https://www.jianshu.com/p/70ac7d1a3300
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。