>  기사  >  웹 프론트엔드  >  nodejs 프로젝트에서 package.json의 공통 속성에 대한 간략한 분석

nodejs 프로젝트에서 package.json의 공통 속성에 대한 간략한 분석

青灯夜游
青灯夜游앞으로
2022-05-20 19:40:093623검색

이 기사에서는 node 프로젝트의 package.json 구성 파일을 살펴보고 package.json의 몇 가지 일반적인 구성 속성, 환경 관련 속성, 종속성 관련 속성 및 타사 속성에 대해 설명하겠습니다. 모두에게 도움이 될 거예요!

nodejs 프로젝트에서 package.json의 공통 속성에 대한 간략한 분석

npm은 프런트 엔드 개발자가 널리 사용하는 패키지 관리 도구입니다. 프로젝트에서 package.json은 프로젝트가 의존하는 npm 패키지의 구성을 관리하는 데 사용됩니다. package.json은 프로젝트의 패키지 종속성을 설명하는 것 외에도 "의미적 버전 관리 규칙"을 사용하여 프로젝트의 종속 패키지 버전을 표시할 수 있으므로 빌드를 다른 개발자와 쉽게 공유할 수 있습니다. 재사용. 이 기사는 주로 최신 npm 및 node 버전과 결합된 최근 실습에서 시작하여 package.json의 몇 가지 일반적인 구성과 표준화된 package.json을 작성하는 방법을 소개합니다


1. package.json

1 . package.json 소개

nodejs 프로젝트에서 package.json은 종속성을 관리하는 구성 파일입니다. 일반적으로 nodejs 프로젝트를 초기화할 때 다음을 전달합니다.

npm init

그러면 디렉터리에 3이 생성됩니다. 디렉터리/파일, node_modules, package.json 및 package.lock.json. package.json의 내용은 다음과 같습니다.

{
    "name": "Your project name",
    "version": "1.0.0",
    "description": "Your project description",
    "main": "app.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
    },
    "author": "Author name",
    "license": "ISC",
    "dependencies": {
        "dependency1": "^1.4.0",
        "dependency2": "^1.5.2"
    }
}

위에서 볼 수 있듯이 package.json에는 프로젝트 자체의 메타데이터와 프로젝트의 하위 종속성 정보(예: 종속성 등)가 포함되어 있습니다.

2. package-lock.json

npm init 중에 package.json 파일뿐만 아니라 package-lock.json 파일도 생성되는 것을 발견했습니다. 그렇다면 package.json을 지울 때 package-lock.json 파일을 생성해야 하는 이유는 무엇입니까? 기본적으로 package-lock.json 파일은 버전을 잠그기 위한 것입니다. package.json에 지정된 하위 npm 패키지는 다음과 같습니다. 실제 설치에서는 버전이 다음보다 높습니다. 반응, package.json이 요구 사항을 충족합니다. 이는 동일한 package.json 파일에 따라 두 번 설치된 하위 종속성 버전이 일관성을 보장할 수 없음을 의미합니다.

package-lock 파일은 아래와 같으며, 하위 종속성 dependency1에 해당 버전이 자세히 지정되어 있습니다. 잠금 버전 역할을 합니다.

{
    "name": "Your project name",
    "version": "1.0.0",
    "lockfileVersion": 1,
    "requires": true,
    "dependencies": {
        "dependency1": {
            "version": "1.4.0",
            "resolved": 
"https://registry.npmjs.org/dependency1/-/dependency1-1.4.0.tgz",
            "integrity": 
"sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="
        },
        "dependency2": {
            "version": "1.5.2",
            "resolved": 
"https://registry.npmjs.org/dependency2/-/dependency2-1.5.2.tgz",
            "integrity": 
"sha512-WOn21V8AhyE1QqVfPIVxe3tupJacq1xGkPTB4iagT6o+P2cAgEOOwIxMftr4+ZCTI6d551ij9j61DFr0nsP2uQ=="
        }
    }
}

2. package.json의 일반적으로 사용되는 속성

이번 장에서는 package.json에서 일반적으로 사용되는 구성 속성에 대해 설명합니다. 이름, 버전 등과 같은 속성은 너무 간단하므로 하나씩 소개하지 않습니다. 하나. 이 장에서는 주로 스크립트, 빈, 작업 공간 속성을 소개합니다.

2.1 script

npm run이 지정될 때마다 npm run으로 생성된 새 Shell이 ​​자동으로 생성됩니다. 로컬 디렉터리의 node_modules/.bin 하위 디렉터리를 PATH 변수에 추가합니다.

이는 현재 디렉터리의 node_modules/.bin 하위 디렉터리에 있는 모든 스크립트를 경로 추가 없이 스크립트 이름으로 직접 호출할 수 있음을 의미합니다. 예를 들어, 현재 프로젝트의 종속성이 esbuild를 포함하는 경우 esbuild xxx를 직접 작성하면 됩니다.

{
  // ...
  "scripts": {
    "build": "esbuild index.js",
  }
}
{
  // ...
  "scripts": {
    "build": "./node_modules/.bin/esbuild index.js" 
  }
}

위의 두 가지 작성 방법은 동일합니다.

2.2 bin

bin 속성은 전역 환경에 실행 파일을 로드하는 데 사용됩니다. bin 필드를 지정하는 npm 패키지는 전역적으로 설치되면 전역 환경에 로드됩니다. 파일을 실행합니다.

예를 들어 @bytepack/cli의 npm 패키지는 다음과 같습니다.

"bin": {
    "bytepack": "./bin/index.js"
 },

@bytepack/cli가 글로벌로 설치되면 bytepack을 통해 해당 명령을 직접 실행할 수 있습니다. 예를 들어

bytepack -v
//显示1.11.0

글로벌로 설치되지 않은 경우에는 node_module/.bin 디렉터리의 프로젝트에 자동으로 연결됩니다. 앞서 소개한 스크립트 태그에서 설명한 것과 일관되게 별칭과 함께 직접 사용할 수 있습니다.

2.3 작업공간

최근 프로젝트 규모가 너무 커지다 보니 모노레포가 인기를 끌고 있습니다. 모노레포에 관해서는 작업 공간을 살펴보는 것을 잊지 마세요. 초기에는 Yarn 작업 공간을 사용했지만 이제 npm은 공식적으로 작업 공간을 지원합니다. Workspaces는 로컬 파일 시스템의 최상위 루트 패키지에서 여러 하위 패키지를 관리하는 방법에 대한 문제를 해결합니다. 작업 영역 선언 디렉터리의 패키지는 최상위 루트 패키지의 node_modules에 소프트 링크됩니다.

​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ ​​​​​​​​​​​​​​​​​​​​​​​​​​:

{
  "name": "my-project",
  "workspaces": [
    "packages/a"
  ]
}

my-project라는 npm 패키지에는 작업 공간으로 구성된 디렉터리가 있습니다.

.
+-- package.json
+-- index.js
`-- packages
   +-- a
   |  `-- package.json

그리고 my-project라는 최상위 루트 패키지에는 패키지/하위 패키지가 있습니다. 이때 npm을 설치하면 루트 패키지의 node_modules에 설치된 npm 패키지 a는 로컬 패키지/a를 가리킵니다.

.
+-- node_modules
|  `-- packages/a -> ../packages/a
+-- package-lock.json
+-- package.json
`-- packages
   +-- a
   |   `-- package.json

-- packages/a -> ../packages/a

는 node_modules a에서 로컬 npm 패키지 Soft로의 링크를 나타냅니다. 체인

三、package.json环境相关属性

    常见的环境,基本上分为浏览器browser和node环境两大类,接下来我们来看看package.json中,跟环境相关的配置属性。环境的定义可以简单理解如下:

  • browser环境:比如存在一些只有在浏览器中才会存在的全局变量等,比如window,Document等
  • node环境: npm包的源文件中存在只有在node环境中才会有的一些变量和内置包,内置函数等。

3.1 type

    js的模块化规范包含了commonjs、CMD、UMD、AMD和ES module等,最早先在node中支持的仅仅是commonjs字段,但是从node13.2.0开始后,node正式支持了ES module规范,在package.json中可以通过type字段来声明npm包遵循的模块化规范。

//package.json
{
   name: "some package",
   type: "module"||"commonjs" 
}

需要注意的是:

  • 不指定type的时候,type的默认值是commonjs,不过建议npm包都指定一下type

  • 当type字段指定值为module则采用ESModule规范

  • 当type字段指定时,目录下的所有.js后缀结尾的文件,都遵循type所指定的模块化规范

  • 除了type可以指定模块化规范外,通过文件的后缀来指定文件所遵循的模块化规范,以.mjs结尾的文件就是使用的ESModule规范,以.cjs结尾的遵循的是commonjs规范

3.2 main & module & browser

    除了type外,package.json中还有main,module和browser 3个字段来定义npm包的入口文件。

  • main : 定义了 npm 包的入口文件,browser 环境和 node 环境均可使用
  • module : 定义 npm 包的 ESM 规范的入口文件,browser 环境和 node - 环境均可使用
  • browser : 定义 npm 包在 browser 环境下的入口文件

我们来看一下这3个字段的使用场景,以及同时存在这3个字段时的优先级。我们假设有一个npm包为demo1,

----- dist
   |-- index.browser.js
   |-- index.browser.mjs
   |-- index.js
   |-- index.mjs

其package.json中同时指定了main,module和browser这3个字段,

  "main": "dist/index.js",  // main 
  "module": "dist/index.mjs", // module

  // browser 可定义成和 main/module 字段一一对应的映射对象,也可以直接定义为字符串
  "browser": {
    "./dist/index.js": "./dist/index.browser.js", // browser+cjs
    "./dist/index.mjs": "./dist/index.browser.mjs"  // browser+mjs
  },

  // "browser": "./dist/index.browser.js" // browser

默认构建和使用,比如我们在项目中引用这个npm包:

import demo from 'demo'

通过构建工具构建上述代码后,模块的加载循序为:

browser+mjs > module > browser+cjs > main

这个加载顺序是大部分构建工具默认的加载顺序,比如webapck、esbuild等等。可以通过相应的配置修改这个加载顺序,不过大部分场景,我们还是会遵循默认的加载顺序。

3.3 exports

    如果在package.json中定义了exports字段,那么这个字段所定义的内容就是该npm包的真实和全部的导出,优先级会高于main和file等字段。

举例来说:

{
  "name": "pkg",
  "exports": {
    ".": "./main.mjs",
    "./foo": "./foo.js"
  }
}
import { something } from "pkg"; // from "pkg/main.mjs"
const { something } = require("pkg/foo"); // require("pkg/foo.js")

从上述的例子来看,exports可以定义不同path的导出。如果存在exports后,以前正常生效的file目录到处会失效,比如require('pkg/package.json'),因为在exports中没有指定,就会报错。

    exports还有一个最大的特点,就是条件引用,比如我们可以根据不同的引用方式或者模块化类型,来指定npm包引用不同的入口文件。

// package.json
{ 
  "name":"pkg",
  "main": "./main-require.cjs",
  "exports": {
    "import": "./main-module.js",
    "require": "./main-require.cjs"
  },
  "type": "module"
}

上述的例子中,如果我们通过

const p = require('pkg')

引用的就是"./main-require.cjs"。

如果通过:

import p from 'pkg'

引用的就是"./main-module.js"

最后需要注意的是 :如果存在exports属性,exports属性不仅优先级高于main,同时也高于module和browser字段。

三、package.json依赖相关属性

    package.json中跟依赖相关的配置属性包含了dependencies、devDependencies、peerDependencies和peerDependenciesMeta等。

   dependencies是项目的依赖,而devDependencies是开发所需要的模块,所以我们可以在开发过程中需要的安装上去,来提高我们的开发效率。这里需要注意的时,在自己的项目中尽量的规范使用,形如webpack、babel等是开发依赖,而不是项目本身的依赖,不要放在dependencies中。

   dependencies除了dependencies和devDependencies,本文重点介绍的是peerDependencies和peerDependenciesMeta。

3.1 peerDependencies

peerDependencies是package.json中的依赖项,可以解决核心库被下载多次,以及统一核心库版本的问题。

//package/pkg
----- node_modules
   |-- npm-a -> 依赖了react,react-dom
   |-- npm-b -> 依赖了react,react-dom
   |-- index.js

比如上述的例子中如果子npm包a,b都以来了react和react-dom,此时如果我们在子npm包a,b的package.json中声明了PeerDependicies后,相应的依赖就不会重新安装。

需要注意的有两点:

  • 对于子npm包a,在npm7中,如果单独安装子npm a,其peerDependicies中的包,会被安装下来。但是npm7之前是不会的。
  • 请规范和详细的指定PeerDependicies的配置,笔者在看到有些react组件库,不在PeerDependicies中指定react和react-dom,或者将react和react-dom放到了dependicies中,这两种不规范的指定都会存在一些问题。
  • 其二,正确的指定PeerDependicies中npm包的版本,react-focus-lock@2.8.1,peerDependicies指定的是:"react": "^16.8.0 || ^17.0.0 || ^18.0.0",但实际上,这个react-focus-lock并不支持18.x的react

3.2 peerDependenciesMeta

    看到“Meta”就有元数据的意思,这里的peerDependenciesMeta就是详细修饰了peerDependicies,比如在react-redux这个npm包中的package.json中有这么一段:

 "peerDependencies": {
    "react": "^16.8.3 || ^17 || ^18"
  },
 "peerDependenciesMeta": {
    "react-dom": {
      "optional": true
    },
    "react-native": {
      "optional": true
    }
  }

这里指定了"react-dom","react-native"在peerDependenciesMeta中,且为可选项,因此如果项目中检测没有安装"react-dom"和"react-native"都不会报错。

    值得注意的是,通过peerDependenciesMeta我们确实是取消了限制,但是这里经常存在非A即B的场景,比如上述例子中,我们需要的是“react-dom”和"react-native"需要安装一个,但是实际上通过上述的声明,我们实现不了这种提示。

四、package.json三方属性

    package.json中也存在很多三方属性,比如tsc中使用的types、构建工具中使用的sideEffects,git中使用的husky,eslint使用的eslintIgnore,这些扩展的配置,针对特定的开发工具是有意义的这里不一一举例。

更多node相关知识,请访问:nodejs 教程

위 내용은 nodejs 프로젝트에서 package.json의 공통 속성에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제