0


package.json配置详解

npm 介绍

npm

是随同

Node.js

一起安装的包管理工具,能解决

Node.js

代码部署上的很多问题,常见的使用场景有以下几种:

  • 允许用户从 NPM 服务器下载别人编写的第三方包到本地使用;
  • 许用户从 NPM 服务器下载并安装别人编写的命令行程序到本地使用;
  • 允许用户将自己编写的包或命令行程序上传到 NPM 服务器供别人使用;

在现在的前端世界里,几乎已经离不开

npm

了,其提供的依赖安装、卸载、升级、发布等一条龙服务,使我们在日常的开发效率提升了不少。

npm

制定了一个包规范,所谓规范就是一些格式和约定,比如作为一个

npm

包中根目录必须包含一个

package.json

文件,并约定从

package.json

文件里读取这个包的所有信息,包括它的名字、版本号、它依赖于哪些别的包等;

并且创建一个

node_modules

目录专门用来存放第三方依赖,Node为此提供的支持是内置的

require()

方法默认会到这个目录下去检索模块,而无需手动指定路径。有了这些规范,一个包的开发、依赖安装、发布等都步骤都标准化了,省心省力。

我们接下来就让我们开始学习

npm

之旅吧!!!

packages和modules的区别

一个

packages

是一个文件,在该文件的根目录,必须包含一个

package.json

文件,通过该文件,你可以将包发布到

registry

modules

node_modules

目录下可以被

require()

函数加载的任何文件和目录,这样的称为模块,一个

packages

也是模块,只不过是由多个模块组成的包。

为了可以通过

require()

函数加载到模块,它必须具有以下特征之一:

  • 文件夹中包含 package.json 文件,并且包含一个 main 字段作为入口文件;
  • 一个 JavaScript 文件;

image_c0ee043d.png

在上面的图中

moment.js

是一个

modules

,但不是一个

packages

,在外部引入可以使用。

image_6cbf064f.png

在上面的例子中,在

node_modules

目录下手动创建一个名为

moment

的文件,并且添加一个

package.json

的文件,在文件中添加

main

字段,设置

main.js

作为文件的入口。

在这里,调用

const foo = require("moment");

实际上加载的是

moment

文件夹下的

main.js

文件,所以

foo

函数被正常调用,最终输出

hi

package.json 详解

在前面的内容中我们多次说到

package.json

的文件,那么我们应该怎么创建这个文件呢,

npm

给我们提供了一个命令

npm init

,在终端输入该命令,会有以下问题并要求你输入回答:

image_ece60352.png

最终会在当前路径生成一个

package.json

文件,文件内容有如下代码所示:

{"name":"moment","version":"1.0.0","description":"描述信息","main":"index.js","dependencies":{"moment":"^1.0.0","axios":"^1.2.6"},"devDependencies":{},"scripts":{"test":"node ./index.js"},"repository":{"type":"git","url":"github地址"},"keywords":["react","vue"],"author":"作者","license":"ISC"}

通过

npm init -y

会生成一个默认的

package.json

文件。接下来我们对

package.json

文件中部分常见的字段进行详细的讲解。

name

如果你要发布你的包,

name

字段是你的

package.json

文件中非常重要的字段,在

npm

官网搜索到的包名就是该字段的值,如果不打算发布你的包,则

name

是可选的,

name

的 值遵循以下规则:

  • 必须小于或等于214个字符;
  • 不能以 '.'"_" 、大写字母、中文开头,该字段最终成为 URL、命令行上的参数和文件夹名称的一部分。因此,name 不能包含任何非url安全字符;
  • 不能使用 NOdejs 核心模块相同的名称;
  • 这个名字可能会作为参数传递给 require() 函数,所以它应该很短,但也要合理地描述;
  • 如果你需要发布包,你需要查看 npm 的注册表(registry)是否存在同名包,否则你将无法发布成功,当然你可以通过后期修改;

在实际的开发中,很多项目都不需要发布到

npm

上,所以这个

name

在这里并不是那么重要,不会影响项目正常运作,可以忽略。

version

name

一样,如果要发布你的包,这个字段很重要,如果不需要,这个字段则显得不是那么重要了。

version

必须可以被 node-semver 解析,

node-semver

作为依赖项与

npm

捆绑在一起。

semver

的版本规范是

X.Y.Z

:

  • X 为主版本号(major): 通常在涉及重大功能更新,产生了破坏性变更时会更新此版本号;
  • Y 为次版本号(Minor): 在引入了新功能,但并未产生破坏性变更,依然向下兼容时更新此版本号;
  • Z 为修订号(Patch): 在修复了一些问题,但未产生破坏性变更时会更新此版本号;

除了

X.Y.Z

这样的版本号,还有

premajor | preminor | prepatch | prerelease

这样的版本号,这些属于测试版本,很多时候一些新改动,并不能直接发布到稳定版本上,这是可以发布一个预发布版本,不会影响到稳定版本。

可以通过以下命令来查看

npm

包的版本信息,如想要查看的react的:

  • 查看最新版本
npm view react version
  • 查看所有版本
npm view react versions

我们可以通过

child_process

执行该命令以获取某的包的版本,这个方法将在后面的脚手架中用到,具体操作请看以下代码:

const cp =require("child_process");

cp.exec("npm view react version",(err, stdout, stderr)=>{
  console.log(stdout);// 18.2.0});

description

description

字段用来描述这个包,它可以是一个字符串,也可以是中文,在搜索的时候可以看到该包的描述,并且该描述也可以作为搜索的关键词。

例如

react

中的

description

字段的值为

React is a JavaScript library for building user interfaces.

,通过搜索

"React is"

能显示会有以下结果:

image_4deb4f40.png

keywords

keywords

字段在里面放关键字,好的关键词可以帮助开发者在

npm

官网上更好的搜索到此项目,增加曝光率。例如

axios

keywords

如下:

"keywords":["xhr","http","ajax","promise","node"],

homepage

项目主页的链接,通常是项目

github

链接,项目官网或者文档首页,如果是

npm

包,会在这里显示:

image_d1cd442b.png

bugs

bugs

字段表示项目提交问题的地址,该字段是一个字符串也可以是一个对象,最常见的

bugs

github

的issue,例如

react

中的

bugs

是这样的:

"bugs":"https://github.com/facebook/react/issues"

license

license 字段表示项目的开源许可证,你应该为你的包指定一个许可证,方便其他开发者知道如何允许他们使用它,以及你对他施加的任何限制,例如:

"license":"ISC"

repository

repository

字段用于指定代码所在的位置,通常是

github

,如果是

npm

包,则会在包的首页中显示:

image_0d3235ce.png

files

files

字段是一个数组,当需要项目进行

npm

发布时,可以通过

files

字段指定哪些文件需要发布到

registry

来控制

npm

包大小,如果指定的是文件夹,那么该文件夹下面的所有文件都会被提交,例如

react

的配置是这样的,如下代码所示:

"files":["LICENSE","README.md","index.js","cjs/","umd/","jsx-runtime.js","jsx-dev-runtime.js","react.shared-subset.js"]

main和browser

main

字段用来指定包的入口入口文件,在上面的内容就忽略不讲了,如果不设置,则默认使用包的根目录中的

index.js

文件作为入口。

main

字段可以在

browser

环境和

Nodejs

环境都可以使用,如果 使用

browser

字段,则表明只能在浏览器环境下使用,不能用于服务端。

type

type

字段表示在

Node

环境中可以使用的模块化方式,默认是

CommonJs

,另外还可以选择

EsModule

bin

一些包的作者希望包可以作为命令行工具使用,配置好

bin

字段之后,通过

npm install package_name -g

命令可以将脚本添加到执行路径中,之后可以在命令行中直接执行。

bin

字段的主要作用可以看 在终端里输入 npm start 后都发生了啥😮😮😮 这篇文章。

exports

exports

字段可以配置不同环境对应的模块入口文件,并且当他存在时,它的优先级最高,当

package.json

文件中存在

exports

字段,设置的

main

字段会失效,在

react

中的

package.json

文件中的

exports

字段有如下配置:

"exports":{".":{"react-server":"./react.shared-subset.js","default":"./index.js"},"./package.json":"./package.json","./jsx-runtime":"./jsx-runtime.js","./jsx-dev-runtime":"./jsx-dev-runtime.js","./src/*":"./src/*"},

这个配置相当于

weboack

中的

resolve.alies

配置路径别名,请看下面的例子,在

node_modules

文件夹下创建一个

moment

文件,并且添加

package.json

文件让其作为一个

npm

模块,通过

require('moment')

会查找到当前文件夹,并通过

main

字段或者

exports

字段查找当前字段的入口,请看如下代码所示:

"exports":{".":{"require":"./test.js"}

在上面的代码中,使用

require('moment')

则表示会自动导入

moment

包中的

test.js

文件,所以在自己的项目中导入会有以下输出:

// moment包中的 test.js 
function foo(){return'test'}module.exports=foo

const foo =require("moment");

console.log(foo());// test

再在

package.json

中的

exports

字段中添加这行代码:

"./src":{"require":"./src/moment.js"}

当在自己的项目中使用

require('moment/src')

进行导入时,实际上导入的是

moment/src

目录下的

moment.js

文件,默认情况下会

require('moment/src')

会加载

index.js

,因为按照

require

规则会先查找

index.js

,具体示例如下代码所示:

// moment/src/moment.js

function bar(params){return"moment.js";}module.exports= bar;// moment/src/index.js

function bar(params){return"index.js";}module.exports= bar;const bar =require("moment/src");

console.log(bar());// moment.js

在自己的项目中使用

require('moment/src')

最终会输出

moment.js

,如果将

exports

字段删除会输出

index.js

,更多

require

细节可以参考 深入浅出CommonJs 这篇文章。

config

config

字段用于设置

script

字段里的脚本运行时的参数,例如设置

prot

为3000:

"config":{"port":"8080"}

并且在

script

字段下添加

dev

属性,值设置为

nodemon index.js

,终端运行

npm run dev
"scripts":{"dev":"nodemon index.js"},

在执行脚本的时候,我们可以通过

process.env.npm_package_config_port

这个变量访问到

3000
console.log(process.env.npm_package_config_port);// 3000

dependencies

dependencies

字段表示运行依赖,也就是项目中生产环境下需要用到的依赖,例如

react

vue

axios

npm

包,使用

npn install <packagename>

或者

npm install <packagename> --save

时,会被自动插入到该字段中:

"dependencies":{"axios":"^1.2.6","react":"^18.2.0","shelljs":"^0.8.5"},

devDependencies

devDependencies

字段表示开发阶段时需要的依赖包,例如

webpack

eslint

sass

,该依赖用于提升开发速度,和

dependencies

不同的是,该字段只需要在开发阶段中使用,不需要在生产环境中使用,要使依赖安装到

devDependencies

字段上,可以使用

npm install <packagename> --save-dev

或者

npm install <packagename> -D

dependencies扩展

在依赖包中后面的参数就是版本,这些版本信息有以下规则:

  • version: 表示确定的版本号;
  • >version: 大于当前版本;
  • ~version: 表示主版本 X 和次版本 Y 保持不变,修订号 Z 永远安装最新的版本;
  • ^version: 表示主版本 X 保持不变,次版本 Y 和修订号 Z 永远安装最新的版本;
  • 1.2.x: 表示该版本中的 x 可以是任何符合规范的值;
  • *"": 表示匹配任何版本;
  • version1 - version2: 表示 version<= x >= version;
  • version1 || version2: 表示只要其中一个符合即可;
  • latest: 代表最新版本;
  • path/path/path: 提供到包含包的本地目录的路径,本地路径可以使用 npm install 保存,该文件会被保存在 node_modules 目录下,例如,在根目录创建一个 bar 的文件并且在 package.json 中添加以下字段:
"dependencies":{"bar":"file:./bar"},

bar

的文件中创建

index.js

文件,并编写以下代码:

function foo(){return"hi";}module.exports= foo;

通过执行

npm install

会把该文件链接到

node_modules

目录文件下,在根目录中编写以下代码:

const bar =require("bar");

console.log(bar());

执行命令

node .\index.js

,你会发现

hi

会被正常输出了。

private

private

字段可以防止我们意外地将私有库发布到

registry

,只需将

private

字段设置为

true

即可:

"private":true

@ 作用域

已知所有的

npm

包都有一个名字,但是随着用户量的增大,

npm

包的包名就出现了被占用的问题,占用后其他人就不能使用了,当然

npm

也官方不是闲着,他们提供了一个作用域的概念,该作用域遵循包名的通常规则,即

url

安全字符,在包名使用时,在作用域前面添加一个

@

符号,表示这个是一个作用域,在后面加一个斜杠,例如:

@somescope/somepackagename

每个

npm

用户或者组织都有自己的作用域,它可以是你的用户名、自己创建的组织名,只有你可以在你的作用域中添加包,这就意味着你不必担心别人会抢在你前面取你的包名,类似于你的

github

,你可以取任何的仓库名称,只需名称合法且在你自己的仓库中不存在同名仓库。

作用域包通过在

npm install

中引用它的名称(前面加@符号)来安装:

npm install @myorg/mypackage

package.json

中有以下的形式:

"dependencies":{"@myorg/mypackage":"^1.3.0"}

因为作用域包安装在作用域文件夹中,所以在代码中需要它们时,必须包含作用域的名称:

require('@myorg/mypackage')

script

script

字段支持许多内置脚本和它们的预设生命周期事件以及任意脚本,这些你都可以使用

npm run <stage>

来执行,例如当你要执行

npm run dev

命令,具有匹配名称的

Pre

Post

命令也就作为这些命令一起执行,执行顺序为

predev

-

dev

-

postdev

,例如在

package.json

文件中有如下定义:

"scripts":{"dev":"node index.js","predev":"node pre.js","postdev":"node post.js"},

当执行

npm run dev

,会首先执行

pre.js

文件,然后执行

index.js

文件,再最后执行

post.js

文件。

更多关于

scirpt

字段的细节将会在另一篇文章中讲解,敬请期待。

参考文章

  • 书籍: 深入浅出Nodejs;
  • npm官网
  • 字节跳动技术团队

结尾

整个系列会比较长,如果想阅读后续的推文,可以点赞+关注😁😁😁

标签: json npm 前端

本文转载自: https://blog.csdn.net/pipidog008/article/details/128869565
版权归原作者 dovienson 所有, 如有侵权,请联系我们删除。

“package.json配置详解”的评论:

还没有评论