当前位置:首页 > 实时新闻 > 正文

package.json文件

摘要: package.json文件最佳答案53678位专家为你答疑解惑package.json文件--JavaScript标准参考教程...

package.json文件

最佳答案 53678位专家为你答疑解惑

package.json文件 -- JavaScript 标准参考教程

package.json文件概述

每个项目的根目录下面,一般都有一个package.json文件,定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)。npm install命令根据这个配置文件,自动下载所需的模块,也就是配置项目所需的运行和开发环境。

下面是一个最简单的package.json文件,只定义两项元数据:项目名称和项目版本。

{"name" : "xxx","version" : "0.0.0",}

上面代码说明,package.json文件内部就是一个JSON对象,该对象的每一个成员就是当前项目的一项设置。比如name就是项目名称,version是版本(遵守“大版本.次要版本.小版本”的格式)。

下面是一个更完整的package.json文件。

{    "name": "Hello World",    "version": "0.0.1",    "author": "张三",    "description": "第一个node.js程序",    "keywords":["node.js","javascript"],    "repository": {        "type": "git",        "url": "https://path/to/url"    },    "license":"MIT",    "engines": {"node": "0.10.x"},    "bugs":{"url":"http://path/to/bug","email":"bug@example.com"},    "contributors":[{"name":"李四","email":"lisi@example.com"}],    "scripts": {        "start": "node index.js"    },    "dependencies": {        "express": "latest",        "mongoose": "~3.8.3",        "handlebars-runtime": "~1.0.12",        "express3-handlebars": "~0.5.0",        "MD5": "~1.2.0"    },    "devDependencies": {        "bower": "~1.2.8",        "grunt": "~0.4.1",        "grunt-contrib-concat": "~0.3.0",        "grunt-contrib-jshint": "~0.7.2",        "grunt-contrib-uglify": "~0.2.7",        "grunt-contrib-clean": "~0.5.0",        "browserify": "2.36.1",        "grunt-browserify": "~1.3.0",    }}

下面详细解释package.json文件的各个字段。

scripts字段

scripts指定了运行脚本命令的npm命令行缩写,比如start指定了运行npm run start时,所要执行的命令。

下面的设置指定了npm run preinstall、npm run postinstall、npm run start、npm run test时,所要执行的命令。

"scripts": {"preinstall": "echo here it comes!","postinstall": "echo there it goes!","start": "node index.js","test": "tap test/*.js"}
dependencies字段,devDependencies字段

dependencies字段指定了项目运行所依赖的模块,devDependencies指定项目开发所需要的模块。

它们都指向一个对象。该对象的各个成员,分别由模块名和对应的版本要求组成,表示依赖的模块及其版本范围。

{  "devDependencies": {    "browserify": "~13.0.0",    "karma-browserify": "~5.0.1"  }}

对应的版本可以加上各种限定,主要有以下几种:

指定版本:比如1.2.2,遵循“大版本.次要版本.小版本”的格式规定,安装时只安装指定版本。

波浪号(tilde)+指定版本:比如~1.2.2,表示安装1.2.x的最新版本(不低于1.2.2),但是不安装1.3.x,也就是说安装时不改变大版本号和次要版本号。

插入号(caret)+指定版本:比如?1.2.2,表示安装1.x.x的最新版本(不低于1.2.2),但是不安装2.x.x,也就是说安装时不改变大版本号。需要注意的是,如果大版本号为0,则插入号的行为与波浪号相同,这是因为此时处于开发阶段,即使是次要版本号变动,也可能带来程序的不兼容。

latest:安装最新版本。

package.json文件可以手工编写,也可以使用npm init命令自动生成。

$ npm init

这个命令采用互动方式,要求用户回答一些问题,然后在当前目录生成一个基本的package.json文件。所有问题之中,只有项目名称(name)和项目版本(version)是必填的,其他都是选填的。

有了package.json文件,直接使用npm install命令,就会在当前目录中安装所需要的模块。

$ npm install

如果一个模块不在package.json文件之中,可以单独安装这个模块,并使用相应的参数,将其写入package.json文件之中。

$ npm install express --save$ npm install express --save-dev

上面代码表示单独安装express模块,--save参数表示将该模块写入dependencies属性,--save-dev表示将该模块写入devDependencies属性。

peerDependencies

有时,你的项目和所依赖的模块,都会同时依赖另一个模块,但是所依赖的版本不一样。比如,你的项目依赖A模块和B模块的1.0版,而A模块本身又依赖B模块的2.0版。

大多数情况下,这不构成问题,B模块的两个版本可以并存,同时运行。但是,有一种情况,会出现问题,就是这种依赖关系将暴露给用户。

最典型的场景就是插件,比如A模块是B模块的插件。用户安装的B模块是1.0版本,但是A插件只能和2.0版本的B模块一起使用。这时,用户要是将1.0版本的B的实例传给A,就会出现问题。因此,需要一种机制,在模板安装的时候提醒用户,如果A和B一起安装,那么B必须是2.0模块。

peerDependencies字段,就是用来供插件指定其所需要的主工具的版本。

{"name": "chai-as-promised","peerDependencies": {"chai": "1.x"}}

上面代码指定,安装chai-as-promised模块时,主程序chai必须一起安装,而且chai的版本必须是1.x。如果你的项目指定的依赖是chai的2.0版本,就会报错。

注意,从npm 3.0版开始,peerDependencies不再会默认安装了。

bin字段

bin项用来指定各个内部命令对应的可执行文件的位置。

"bin": {"someTool": "./bin/someTool.js"}

上面代码指定,someTool 命令对应的可执行文件为 bin 子目录下的 someTool.js。Npm会寻找这个文件,在node_modules/.bin/目录下建立符号链接。在上面的例子中,someTool.js会建立符号链接npm_modules/.bin/someTool。由于node_modules/.bin/目录会在运行时加入系统的PATH变量,因此在运行npm时,就可以不带路径,直接通过命令来调用这些脚本。

因此,像下面这样的写法可以采用简写。

scripts: {start: './node_modules/someTool/someTool.js build'}// 简写为scripts: {start: 'someTool build'}

所有node_modules/.bin/目录下的命令,都可以用npm run [命令]的格式运行。在命令行下,键入npm run,然后按tab键,就会显示所有可以使用的命令。

main字段

main字段指定了加载的入口文件,require('moduleName')就会加载这个文件。这个字段的默认值是模块根目录下面的index.js。

config字段

config字段用于向环境变量输出值。

下面是一个package.json文件。

{"name" : "foo","config" : { "port" : "8080" },"scripts" : { "start" : "node server.js" }}

然后,在server.js脚本就可以引用config字段的值。

http.createServer(...).listen(process.env.npm_package_config_port)

用户可以改变这个值。

$ npm config set foo:port 80
其他browser字段

browser指定该模板供浏览器使用的版本。Browserify这样的浏览器打包工具,通过它就知道该打包那个文件。

"browser": {"tipso": "./node_modules/tipso/src/tipso.js"},
engines字段

engines指明了该项目所需要的node.js版本。

man字段

man用来指定当前模块的man文档的位置。

"man" :[ "./doc/calc.1" ]
preferGlobal字段

preferGlobal的值是布尔值,表示当用户不将该模块安装为全局模块时(即不用–global参数),要不要显示警告,表示该模块的本意就是安装为全局模块。

style字段

style指定供浏览器使用时,样式文件所在的位置。样式文件打包工具parcelify,通过它知道样式文件的打包位置。

"style": ["./node_modules/tipso/src/tipso.css"]

手把手教你重新认识 package.json「干货」

作者:前端小黑

转发链接:https://juejin.im/post/5ebcd8b1e51d454dc20dd8a0

前言

在每个项目的根目录下面,一般都会有一个 package.json 文件,其定义了运行项目所需要的各种依赖和项目的配置信息(如名称、版本、许可证等元数据)。大多数人对 package.json 文件的了解,仅停留在: 项目名称、项目构建版本、许可证的定义; 依赖定义(包括 dependencies 字段,devDependencies 字段); 使用scripts字段指定运行脚本命令的 npm 命令行缩写。其实,package.json 的作用远不止于此,我们可以通过新增配置项实现更强大的功能,下面将带你重新认识 package.json。

由简入繁,丰富项目的 package.json

简单版的 package.json

当我们新建一个名称为 my-test 的项目时,使用 yarn init -y 或 npm init -y 命令后,在项目目录下会新增一个 package.json文件,内容如下:
{  "name": "my-test", # 项目名称  "version": "1.0.0", # 项目版本(格式:大版本.次要版本.小版本)  "description": "", # 项目描述  "main": "index.js", # 入口文件  "scripts": { # 指定运行脚本命令的 npm 命令行缩写    "test": "echo \"Error: no test specified\" && exit 1"  },  "keywords": [], # 关键词  "author": "", # 作者  "license": "ISC" # 许可证}复制代码
可以看到,package.json 文件的内容是一个 JSON 对象,对象的每一个成员就是当前项目的一项配置。

安装项目依赖(dependencies & devDependencies)

dependencies字段指定了项目运行所依赖的模块(生产环境使用),如 antd、 react、 moment等插件库: 它们是我们生产环境所使用的,所以要放在 dependencies 中,如果未将项目必须依赖的插件库安装到 dependencies,打包后的项目就可能报错,无法运行。devDependencies 字段指定了项目开发所需要的模块(开发环境使用),如 webpack、typescript、babel等: 在代码打包提交线上时,我们并不需要这些工具,所以我们将它放入 devDependencies 中。如果一个模块不在 package.json 文件之中,我们可以单独安装这个模块,并使用相应的参数,将其写入 dependencies 字段/ devDependencies 字段中:
# 使用 npmnpm install <package...> --save # 写入 dependencies 属性npm install <package...> --save-dev # 写入 devDependencies 属性# 使用 yarnyarn add <package...> # 写入 dependencies 属性yarn add <package...> --dev # 写入 devDependencies 属性复制代码
有了 package.json 文件,开发直接使用 npm install / yarn install 命令,就会在当前目录中自动安装所需要的模块,安装完成项目所需的运行和开发环境就配置好了。

简化终端命令(scripts)

scripts 字段是 package.json 中的一种元数据功能,它接受一个对象,对象的属性为可以通过 npm run 运行的脚本,值为实际运行的命令(通常是终端命令),如:
"scripts": {  "start": "node index.js"},复制代码
将终端命令放入 scripts 字段,既可以记录它们又可以实现轻松重用。

定义项目入口(main)

main 字段是 package.json 中的另一种元数据功能,它可以用来指定加载的入口文件。假如你的项目是一个 npm 包,当用户安装你的包后,require('my-module') 返回的是 main 字段中所列出文件的 module.exports 属性。当不指定main 字段时,默认值是模块根目录下面的index.js 文件。

指定项目 node 版本(engines)

有时候,新拉一个项目的时候,由于和其他开发使用的 node 版本不同,导致会出现很多奇奇怪怪的问题(如某些依赖安装报错、依赖安装完项目跑步起来等)。为了实现项目开箱即用的伟大理想,这时候可以使用 package.json 的 engines 字段来指定项目 node 版本:
"engines": {   "node": ">=8.16.0"},复制代码
该字段也可以指定适用的 npm 版本:
"engines": {   "npm": ">=6.9.0" },复制代码
需要注意的是,engines属性仅起到一个说明的作用,当用户版本不符合指定值时也不影响依赖的安装。

自定义命令(bin)

用过 vue-cli,create-react-app等脚手架的朋友们,不知道你们有没有好奇过,为什么安装这些脚手架后,就可以使用类似 vue create/create-react-app之类的命令,其实这和 package.json 中的 bin 字段有关。bin 字段用来指定各个内部命令对应的可执行文件的位置。当package.json 提供了 bin 字段后,即相当于做了一个命令名和本地文件名的映射。当用户安装带有 bin 字段的包时, 如果是全局安装,npm 将会使用符号链接把这些文件链接到/usr/local/node_modules/.bin/; 如果是本地安装,会链接到./node_modules/.bin/。举个 ,如果要使用 my-app-cli 作为命令时,可以配置以下 bin 字段:
"bin": {  "my-app-cli": "./bin/cli.js"}复制代码
上面代码指定,my-app-cli 命令对应的可执行文件为 bin 子目录下的 cli.js,因此在安装了 my-app-cli 包的项目中,就可以很方便地利用 npm执行脚本:
"scripts": {  start: 'node node_modules/.bin/my-app-cli'}复制代码

咦,怎么看起来和 vue create/create-react-app之类的命令不太像?原因: 当需要 node 环境时就需要加上 node 前缀 如果加上 node 前缀,就需要指定 my-app-cli 的路径 -> node_modules/.bin,否则 node my-app-cli会去查找当前路径下的 my-app-cli.js,这样肯定是不对。若要实现像 vue create/create-react-app之类的命令一样简便的方式,则可以在上文提到的 bin 子目录下可执行文件cli.js 中的第一行写入以下命令:

#!/usr/bin/env node复制代码
这行命令的作用是告诉系统用 node 解析,这样命令就可以简写成 my-app-cli 了。

React 项目相关

设置应用根路径(homepage)

当我们使用 create-react-app 脚手架搭建的 React 项目,默认是使用内置的 webpack 配置,当package.json 中不配置 homepage 属性时,build 打包之后的文件资源应用路径默认是 /,如下图:一般来说,我们打包的静态资源会部署在 CDN 上,为了让我们的应用知道去哪里加载资源,则需要我们设置一个根路径,这时可以通过 package.json 中的 homepage 字段设置应用的根路径。当我们设置了 homepage 属性后:
{  "homepage": "https://xxxx.cdn/my-project",}复制代码
打包后的资源路径就会加上 homepage 的地址:

开发环境解决跨域问题(proxy)

在做前后端分离的项目的时候,调用接口时则会遇到跨域的问题,当在开发环境中时,可以通过配置 package.json 中的 proxy 来解决跨域问题,配置如下:
{  "proxy": "http://localhost:4000"  // 配置你要请求的服务器地址}复制代码
注意,当 create-react-app 的版本高于 2.0 版本的时候在 package.json 中只能配置 string 类型,这意味着如果要使用 package.json 来解决跨域问题,则只能代理一个服务器地址。如果要代理多个服务器地址时,则需要安装 http-proxy-middleware ,在 src 目录下新建 setupProxy.js :
const proxy=require("http-proxy-middleware"); module.exports=function(app) {  app.use(    proxy("/base", {      target: "http://localhost:4000",      changeOrigin: true    })  );  app.use(    proxy("/fans", {      target: "http://localhost:5000",      changeOrigin: true    })  );};复制代码

根据开发环境采用不同的全局变量值(自定义字段)

假设有这么一个组件,当组件被点击时,在开发环境时是跳转测试环境的 sentry 地址,在正式环境时则跳转正式环境的 sentry 地址。首先,通过配置前面提到的 scripts 字段,实现环境变量(NODE_ENV)的设置:
"scripts": {  "start": "NODE_ENV=development node scripts/start.js",  "build": "NODE_ENV=production node scripts/build.js",},复制代码
项目启动起来后,在代码中我们可以通过 process.env.NODE_ENV 访问到 NODE_ENV 的值。

方案一

我们可以在组件中写类似以下的判断代码,根据不同环境给 sentryUrl 设置不同的值:
let sentryUrl;if (process.env.NODE_ENV==='development') {    sentryUrl='test-sentry.xxx.com';} else {    sentryUrl='sentry.xxx.com';}复制代码
这么做好像没毛病,但是深入一想,如果有多个组件,要根据不同的环境使用不同的服务(多种服务)地址,如果按照上面的写法,项目中将存在许多重复的判断代码,且当服务地址发生变化时,包含这些服务地址的组件都需要相应的做改动,这样明显是不合理的。

方案二

解决方案:相关服务的地址配置在 package.json中,同时修改项目的 webpack 配置。注:修改项目的 webpack 配置需要 eject 项目的 webpack 配置(更多细节可阅读 :react + typescript 项目的定制化过程)。在项目根目录下使用 yarn eject 成功 eject 出配置后,可以发现项目目录的变化如下:如果需要定制化项目,一般就是在 config 目录下对默认的 webpack 配置进行修改,在这里我们需要关注 config/path.js 和 config/env.js 两个文件: env.js 的主要目的在于读取 env 配置文件并将 env 的配置信息给到全局变量 process.env ; path.js 的主要目的在于为项目提供各种路径,包括构建路径、 public 路径等。由于本文的重点不是学习 webpack 配置,这里仅介绍如何实现【根据开发环境采用不同的全局变量值】的功能。首先,需要在 package.json 中配置以下内容:
"scripts": {  "start": "NODE_ENV=development node scripts/start.js",  "build": "NODE_ENV=production node scripts/build.js",},"sentryPath": {  "dev": "https://test-sentry.xxx.com",  "prod": "https://sentry.xxx.com" }复制代码
然后,修改 path.js 文件,内容如下:
// 重写 getPublicUrl 方法const getPublicUrl=(appPackageJson, pathName)=> {  let path;  switch (process.env.DEPLOY_ENV) {    case 'development':      path=require(appPackageJson)[pathName].dev;      break;    case 'production':      path=require(appPackageJson)[pathName].prod;      break;    default:      path=envPublicUrl || require(appPackageJson).homepage;  }  return path;}// 新增 getSentryPath 方法const getSentryPath=(appPackageJson)=> {  return getPublicUrl(appPackageJson, 'sentryPath');}// config after eject: we're in ./config/module.exports={  ...,  sentryUrl: getSentryPath(resolveApp('package.json')), // 新增};复制代码
最后,修改 env.js 文件,内容如下:
// 修改 getClientEnvironment 方法function getClientEnvironment(publicUrl) {  const raw=Object.keys(process.env)    .filter(key=> REACT_APP.test(key))    .reduce(      (env, key)=> {        ...      },      {        NODE_ENV: process.env.NODE_ENV || 'development',        PUBLIC_URL: publicUrl,        SENTRY_URL: paths.sentryUrl // 新增      }    );  const stringified={    ...  };  return { raw, stringified };}复制代码
通过上面的配置,我们就可以在组件中通过 process.env.SENTRY_URL 获取到 sentry 服务的地址了,虽然看起来比方案一繁琐,但是这种收益是长期的,如要新增一个 sonarqube 服务,同理实现即可,通过使用 package.json 也可以清楚的看到当前服务在不同环境下使用的地址。

总结

本文介绍了 package.json 的多种常见的配置字段及作用,并通过例子加深大家对 package.json这些字段的理解。除了一些常用字段,还介绍了在React 项目中 package.json 文件能实现的一些功能进行介绍。

以上内容如有遗漏错误,欢迎留言 ??指出,一起进步

如果觉得本文对你有帮助,留下你宝贵的

推荐React 和TypeScript学习相关文章

React

《React Hook + TypeScript 手把手教你打造类型安全的应用》

《在 React 中自动复制文本到剪贴板「实践」》

《「干货满满」从零实现 react-redux》

《深入详解大佬用33行代码实现了React》

《让你的 React 组件性能跑得再快一点「实践」》

《React源码分析与实现(三):实践 DOM Diff》

《React源码分析与实现(一):组件的初始化与渲染「实践篇」》

《React源码分析与实现(二):状态、属性更新->setState「实践篇」》

《细说React 核心设计中的闪光点》

《手把手教你10个案例理解React hooks的渲染逻辑「实践」》

《React-Redux 100行代码简易版探究原理》

《手把手深入教你5个技巧编写更好的React代码【实践】》

《React 函数式组件性能优化知识点指南汇总》

《13个精选的React JS框架》

《深入浅出画图讲解React Diff原理【实践】》

《【React深入】React事件机制》

《Vue 3.0 Beta 和React 开发者分别杠上了》

《手把手深入Redux react-redux中间件设计及原理(上)【实践】》

《手把手深入Redux react-redux中间件设计及原理(下)【实践】》

《前端框架用vue还是react?清晰对比两者差异》

《为了学好 React Hooks, 我解析了 Vue Composition API》

《【React 高级进阶】探索 store 设计、从零实现 react-redux》

《写React Hooks前必读》

《深入浅出掌握React 与 React Native这两个框架》

《可靠React组件设计的7个准则之SRP》

《React Router v6 新特性及迁移指南》

《用React Hooks做一个搜索栏》

《你需要的 React + TypeScript 50 条规范和经验》

《手把手教你绕开React useEffect的陷阱》

《浅析 React / Vue 跨端渲染原理与实现》

《React 开发必须知道的 34 个技巧【近1W字】》

《三张图详细解说React组件的生命周期》

《手把手教你深入浅出实现Vue3 & React Hooks新UI Modal弹窗》

《手把手教你搭建一个React TS 项目模板》

《全平台(Vue/React/微信小程序)任意角度旋图片裁剪组件》

《40行代码把Vue3的响应式集成进React做状态管理》

《手把手教你深入浅出React 迷惑的问题点【完整版】》

TypeScript

TypeScript 3.9正式发布:平均编译时长从26秒缩短至10秒「尝鲜」

深入TypeScript难点梳理讲解

Vue3.0之前你必须知道的TypeScript实战技巧

未来可期的TypeScript

Vue3.0关于TypeScript实践

你需要的 React + TypeScript 50 条规范和经验

TypeScript详细解说【思维导图】

Vue3.0 尝鲜 Hook TypeScript 取代 Vuex【项目实践】

TypeScript详细概括【思维导图】

「新消息」基于JavaScript/TypeScript 编程环境Deno1.0 即将发布

一张页面引起的项目架构思考(Rax+Typescript+hooks)

深入浅出Vue3 跟着尤雨溪学 TypeScript 之 Ref 【实践】

作者:前端小黑转发链接:https://juejin.im/post/5ebcd8b1e51d454dc20dd8a0

发表评论