通常使用脚手架构建,并搭配打包/打包less、代码编译器、代码检查及格式化的工具。
一、理解 package.json
name 项目名称
- name 和 version 字段,是 package.json 必填的。
- 名称和版本一起构成一个标识符,该标识符被认为是完全唯一的。对包的更改应该与对版本的更改一起进行。
规则:
- 必须小于等于214个字符,不能以.或_开头,不能有大写字母,
- 因为名称最终成为URL、命令行参数和文件夹名称的一部分,因此不能包含任何非URL安全字符。
建议:
- 不要使用与核心节点模块相同的名称。
- 不要在名称中加js或node。如果需要可以使用engines来指定运行环境。
- 该名称可能会作为参数传递给 require(),因此它应该是简短的,但也需要具有合理的描述性。
version 语义化版本
version:一般的格式是x.x.x, 并且需要遵循语义化版本 (semver, Semantic Versioning) 规则。版本必须可由 node-semver 解析,它与 npm 作为依赖项捆绑在一起
语义化版本格式:主版本号.次版本号.修订号,递增规则如下:
- major 主版本号:当你做了不兼容的 API 修改,
- minor 次版本号:当你做了向下兼容的功能性新增,
- patch 修订号:当你做了向下兼容的问题修正。
先行版本号及版本编译信息可以加到“主版本号.次版本号.修订号”的后面,作为延伸。
版本范围是一组比较器,它们指定满足范围的版本。比较器由运算符和版本组成。
原始比较器
- < 小于
- <= 小于或等于
大于
= 大于或等于
- = 相等。 如果未指定运算符,则假定相等,因此此运算符是可选的,但可以包含。
高级范围语法
高级范围语法以确定的方式对原始比较器进行脱糖。
高级范围可以以与使用空白或 || 的原始比较器相同的方式组合。
连字符范围 X.Y.Z - A.B.C
1.2.3 - 2.3.4
:= >=1.2.3 <=2.3.4
1.2 - 2.3.4
:= >=1.2.0 <=2.3.4
1.2.3 - 2.3
:= >=1.2.3 <2.4.0-0
1.2.3 - 2
:= >=1.2.3 <3.0.0-0
X 范围 1.2.x 1.X 1.2.
X、x 或 中的任何一个都可以用来“代替”[major, minor, patch] 元组中的一个数值。
`:=
>=0.0.0(任何非预发布版本都满足,除非指定了 includePrerelease,在这种情况下任何版本都满足)<br />
1.x:=
>=1.0.0 <2.0.0-0`(匹配主要版本)1.2.x
:= >=1.2.0 <1.3.0-0
(匹配主要和次要版本)
部分版本范围被视为 X-Range,因此特殊字符实际上是可选的。""
:= *
:= >=0.0.0
1
:= 1.x.x
:= >=1.0.0 <2.0.0-0
1.2
:= 1.2.x
:= >=1.2.0 <1.3.0-0
波浪号范围 ~1.2.3 ~1.2 ~1
表示大约相当于某版本
如果在比较器上指定了次要版本,则允许补丁级别的更改。 如果没有,则允许进行次要级别的更改。~1.2.3
:= >=1.2.3 <1.(2+1).0
:= >=1.2.3 <1.3.0-0
~1.2
:= >=1.2.0 <1.(2+1).0
:= >=1.2.0 <1.3.0-0
(与 1.2.x 相同)~1
:= >=1.0.0 <(1+1).0.0
:= >=1.0.0 <2.0.0-0
(与 1.x 相同)~0
:= >=0.0.0 <(0+1).0.0
:= >=0.0.0 <1.0.0-0
(与 0.x 相同)~1.2.3-beta.2
:= >=1.2.3-beta.2 <1.3.0-0
请注意,如果 1.2.3 版本大于或等于 beta.2,则允许预发布。 因此,允许使用 1.2.3-beta.4,但不允许使用 1.2.4-beta.2,因为它是不同 [major, minor, patch] 元组的预发布。
插入符范围 ^1.2.3 ^0.2.5 ^0.0.4
表示与某版本兼容
允许不修改 [major, minor, patch] 元组中最左边的非零元素的更改。换言之,这允许对 1.0.0 及更高版本进行补丁和次要更新,对 0.X >=0.1.0 版本进行补丁更新,对 0.0.X 版本不进行更新。
许多作者将 0.x 版本视为 x 是主要的“重大变化”指标:
当作者可能在 0.2.4 和 0.3.0 版本之间进行重大更改时,插入符范围是理想的,这是一种常见的做法。但是,它假定 0.2.4 和 0.2.5 之间不会有重大变化。根据普遍观察到的实践,它允许被假定为附加(但非破坏性)的更改。
^1.2.3
:= >=1.2.3 <2.0.0-0
^0.2.3
:= >=0.2.3 <0.3.0-0
^0.0.3
:= >=0.0.3 <0.0.4-0
main 入口点(模块ID)
- 若您的包名为 foo,且用户安装了它,然后执行了 require(“foo”),那么您的主模块的导出对象将被返回。
- 这应该是相对于包文件夹根目录的模块 ID。
main字段指定了加载的入口文件,require导入的时候就会加载这个文件。默认值是模块根目录下面的index.js
bin 可执行文件位置
- 许多软件包都有一个或多个可执行文件,他们希望将它们安装到 PATH 中。
- 要使用它,请在 package.json 中提供一个 bin 字段,它是命令名称到本地文件名的映射。安装时,npm 会将该文件符号链接到 prefix/bin 用于全局安装,或 ./node_modules/.bin/ 用于本地安装。
bin项用来指定每个内部命令对应的可执行文件的位置。
在模块以依赖的方式被安装,如果存在bin选项。在node_modules/.bin/生成对应的文件,
Npm会寻找这个文件,在node_modules/.bin/目录下建立符号链接。由于node_modules/.bin/目录会在运行时加入系统的PATH变量,因此在运行npm时,就可以不带路径,直接通过命令来调用这些脚本
所有node_modules/.bin/目录下的命令,都可以用npm run [命令]的格式运行。在命令行下,键入npm run,然后按tab键,就会显示所有可以使用的命令。
scripts 脚本
scripts指定了运行脚本命令的npm命令行缩写,比如start指定了运行npm run start时,所要执行的命令。
"scripts": {
"start": "node ./start.js"
}
复制代码
使用scripts字段可以快速的执行shell命令,可以理解为alias。
scripts可以直接使用node_modules中安装的模块,这区别于直接运行需要使用npx命令。
"scripts": {
"build": "webpack"
}
// npm run build
// npx webpack
config 配置
config字段用于添加命令行的环境变量。
{
"name" : "yindong",
"config" : { "port" : "8080" },
"scripts" : { "start" : "node server.js" }
}
然后,在server.js脚本就可以引用config字段的值。
console.log(process.env.npm_package_config_port); // 8080
用户可以通过npm config set来修改这个值。
npm config set yindong:port 8000
dependencies 依赖
项目运行所依赖的模块。安装依赖的时候使用—save 参数表示将该模块写入dependencies属性。
对象由各自的模块名和对应的版本要求组成,表示依赖的模块及其版本范围。
devDependencies 开发依赖
项目开发所需要的模块。安装依赖的时候使用—save-dev 或 -D 参数表示将该模块写入devDependencies属性。
对象由各自的模块名和对应的版本要求组成,表示依赖的模块及其版本范围。
"devDependencies": {
"standard-version": "^7.0.0",
"less": "2.x",
}
常见版本范围:
- 固定版本: 比如5.38.1,安装时只安装指定版本。
- 波浪号: 比如~5.38.1, 表示安装5.38.x的最新版本(不低于5.38.1),但是不安装5.39.x,也就是说安装时不改变主版本号和次要版本号。
- 插入号: 比如ˆ5.38.1, ,表示安装5.x.x的最新版本(不低于5.38.1),但是不安装6.x.x,也就是说安装时不改变主版本号。
- latest: 安装最新版本。
需要注意的是,如果大版本号为0,则插入号的行为与波浪号相同,这是因为此时处于开发阶段,即使是次要版本号变动,也可能带来程序的不兼容。
proxy 代理字段
Creat React App 的代理设置
Creat React App 的代理设置依赖库 react-scripts
。package.json 中代理字段用于告诉开发服务器将任何未知请求代理到开发中的 API 服务器
"proxy": "http://localhost:4000"
这样,当您在开发中 fetch(‘/api/todos’) 时,开发服务器将识别出它不是静态资产,并将您的请求代理到 [http://localhost:4000/api/todos](http://localhost:4000/api/todos)
作为后备。
方便地,这避免了开发中的 CORS 问题和错误消息:
Fetch API cannot load http://localhost:4000/api/todos.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:3000' is therefore not allowed access.
If an opaque response serves your needs,
set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
- 代理仅在开发中有效,您可以确保 /api/todos 之类的 URL 指向生产中的正确内容。 您不必使用 /api 前缀。 任何没有 text/html 接受标头的无法识别的请求都将被重定向到指定的代理。
- 代理选项支持 HTTP、HTTPS 和 WebSocket 连接。
如果代理选项对您来说不够灵活,您也可以:
自己配置代理:
安装 http-proxy-middleware 代理中间件,直接访问 Express 应用程序实例并连接您自己的代理中间件
$ npm install http-proxy-middleware --save
$ # or
$ yarn add http-proxy-middleware
接下来,创建 src/setupProxy.js 并将以下内容放入其中,可以根据需要注册代理了 ```javascript const { createProxyMiddleware } = require(‘http-proxy-middleware’);
module.exports = function(app) { app.use( ‘/api’, createProxyMiddleware({ target: ‘http://localhost:5000‘, // target host changeOrigin: true, // needed for virtual hosted sites }) ); };
- 在你的服务器上启用 CORS(这里是如何为 Express 做的)。
```javascript
// express 示例
app.use(function(req, res, next) {
// update to match the domain you will make the request from
res.header("Access-Control-Allow-Origin", "YOUR-DOMAIN.TLD");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
二、理解跨域代理
开发环境跨域代理
Vue Cli 的代理设置
vue.config.js 中 devServer 类似 webpack-dev-server 的选项,其中的 devServer.proxy 字段可以是一个指向开发环境 API 服务器的字符串:
module.exports = {
devServer: {
proxy: 'http://localhost:4000'
}
}
这会告诉开发服务器将任何未知请求 (没有匹配到静态文件的请求) 代理到http://localhost:4000。
如果你想要更多的代理控制行为,也可以使用一个 path: options 成对的对象。完整的选项可以查阅 http-proxy-middleware 。
module.exports = {
devServer: {
proxy: {
'/api': {
target: '<url>', // target host
ws: true, // proxy websockets
changeOrigin: true // needed for virtual hosted sites
},
'/foo': {
target: '<other_url>'
}
}
}
}
注意:
- 代理只对 devServer 配置中的端口请求生效;axios 中 baseURL 如果被配置过,此时proxy代理不生效
- 对于 pageRewrite : 前端请求代理时添加 api 标记,若接口本身无 api 开头前缀则需将请求 path 前缀重写为 ‘’ 或 ‘/‘,详情参考
'/api/': {
// 要代理的地址
target: 'http://localhost:8100',
// 配置了这个可以从 http 代理到 https
// 依赖 origin 的功能可能需要这个,比如 cookie
changeOrigin: true,
// 前端请求代理时添加 api 开头标记
// 若后端接口本身无 api 开头则需将 api 开头的 path 重写为 '' 或 '/'
pathRewrite: { '^/api': '' },
},
生产环境跨域代理
代理:通常用于在多个服务器之间分配负载,无缝显示来自不同网站的内容,或通过 HTTP 以外的协议将处理请求传递给应用程序服务器。
正向代理:为了向服务器获取数据,客户端要向代理服务器发送一个请求,并指定目标服务器,代理服务器将目标服务器返回的数据转交给客户端。正向代理代理的是客户端
反向代理:客户端对代理是无感知的,将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,返回给客户端。此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。反向代理代理服务器
上线后,通过 nginx 配置反向代理。通过不同的协议将请求从 NGINX 传递到代理服务器,修改发送到代理服务器的客户端请求标头,以及配置来自代理服务器的响应的缓冲。
# Upstream模块实现负载均衡
upstream mysvr {
server localhost:10001;
server localhost:10002;
server 192.168.10.121:3333 backup; #热备
}
server {
listen 5566; # 提供服务的端口,默认80
server_name localhost; # 提供服务的域名主机名
location ~*^.+$ { #请求的url过滤,~*为不区分大小写。
root html; # 站点的根目录,相当于Nginx的安装目录
index index.html index.htm; # 默认的首页文件,多个用空格分开
proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表
deny 127.0.0.1; #拒绝的ip
allow 172.18.5.54; #允许的ip
}
}
通过该配置,访问nginx地址 http://localhost:5566
的请求会被转发到 mysvr 服务地址。实际使用中,可将请求转发到本机另一个服务器上,也可以根据访问的路径跳转到不同端口的服务中
proxy_pass 传递请求给代理服务器
要将请求传递给 HTTP 代理服务器,需要在 location 内指定 proxy_pass 指令:
location /some/path/ {
proxy_pass http://www.example.com/link/;
}
此地址可以指定为域名或 IP 地址,可能包含端口。
- proxy_pass 指令也可指向一组命名的服务器。 在这种情况下,请求根据指定的方法在组中的服务器之间分发
- proxy_pass后面的url加/,表示绝对根路径;如果没有/,表示相对路径,把匹配的路径部分也给代理走。
proxy_set_header 传递请求标头
默认情况下,NGINX 会重新定义代理请求中的两个 header 字段,“Host”设置为 $proxy_host 变量,“Connection”设置为关闭。并消除值为空字符串的 header 字段。
要更改这些设置以及修改其他标头字段,请使用 proxy_set_header 指令,该指令可在某个位置、更高位置、特定的服务器上下文或 http 块中指定。要防止标头字段被传递到代理服务器,请将其设置为空字符串:
location /some/path/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Accept-Encoding "";
proxy_pass http://localhost:8000;
}
proxy_bind 选择传出 IP 地址
如果您的代理服务器有多个网络接口,有时您可能需要选择一个特定的源 IP 地址来连接到代理服务器或上游。 如果 NGINX 后面的代理服务器配置为接受来自特定 IP 网络或 IP 地址范围的连接,这可能很有用。
指定 proxy_bind 指令和必要网络接口的 IP 地址:
location /app1/ {
proxy_bind 127.0.0.1;
proxy_pass http://example.com/app1/;
}
location /app2/ {
proxy_bind 127.0.0.2;
proxy_pass http://example.com/app2/;
}