ホームページ  >  記事  >  ウェブフロントエンド  >  Nodejs プロジェクトにおける package.json の共通属性の簡単な分析

Nodejs プロジェクトにおける package.json の共通属性の簡単な分析

青灯夜游
青灯夜游転載
2022-05-20 19:40:093623ブラウズ

この記事では、node プロジェクトの package.json 構成ファイルについて説明し、パッケージ内のいくつかの一般的な構成プロパティ、環境関連プロパティ、依存関係関連プロパティ、およびサードパーティ プロパティについて説明します。 .json. 役に立てば幸いです みんなも助けてください!

Nodejs プロジェクトにおける package.json の共通属性の簡単な分析

npm は、フロントエンド開発者によって広く使用されているパッケージ管理ツールです。プロジェクトでは、package.json を使用して、プロジェクトが依存する npm パッケージの構成を管理します。の上。 package.json は json ファイルです。プロジェクトのパッケージの依存関係を記述することに加えて、「セマンティック バージョニング ルール」を使用してプロジェクトの依存パッケージのバージョンを示すこともできるため、ビルドを他の開発者とより適切に共有して簡単に行うことができます。再利用。 。 この記事は主に、最新の npm およびノー​​ド バージョンと組み合わせた最近の実践から始まり、package.json のいくつかの一般的な構成と、標準化された package.json


1. パッケージの作成方法を紹介します。 .json

1. package.json の概要

Nodejs プロジェクトでは、package.json はそのプロジェクトを管理する構成です。依存関係ファイル。通常、nodejs プロジェクトを初期化するときに次のように渡します。

npm init

そうすると、ディレクトリ内に、node_modules、package.json、package.lock.json の 3 つのディレクトリ/ファイルが生成されます。 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 パッケージは次のようになります。react: "^16.0.0"。実際のインストールでは、バージョンが より高い限り、反応し、package.json が満たされています。これは、同じ package.json ファイルによれば、2 回インストールされたサブ依存関係のバージョンの一貫性が保証できないことを意味します。

パッケージロックファイルは以下の通りで、サブ依存関係 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 で一般的に使用される構成属性について説明します。名前やバージョンなどの属性は次のとおりです。シンプルすぎて一つ一つ紹介していません。この章では、主に script、bin、workspaces のプロパティについて説明します。

2.1 script

npm の script タグを使用してスクリプトを定義し、npm run を指定するとシェルが自動的に作成されます。スクリプト、ここで注意する必要があるのは、npm run によって作成された新しいシェルが、ローカル ディレクトリの 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.2 bin

bin 属性は、実行可能ファイルをグローバル環境にロードするために使用され、bin フィールドを持つ npm パッケージが指定されますグローバルにインストールされている場合は、グローバル環境にロードされ、エイリアスを介してファイルを実行できます。

たとえば、@bytepack/cli の npm パッケージ:

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

@bytepack/cli がグローバルにインストールされると、bytepack を通じて対応するコマンド (

bytepack -v
//显示1.11.0
など) を直接実行できます。

グローバルにインストールされていない場合は、プロジェクトのnode_module/.binディレクトリに自動的に接続されます。前に紹介した script タグで述べたことと一致し、エイリアスとともに直接使用できます。

2.3 ワークスペース

プロジェクトが大きすぎる場合、最近モノリポジトリがますます人気になっています。モノリポジトリに関しては、ワークスペースを参照しないでください。初期の頃は、yarn ワークスペースを使用していました。現在、npm はワークスペースを正式にサポートしています。 ワークスペースは、ローカル ファイル システムの最上位ルート パッケージの下で複数のサブパッケージを管理する方法の問題を解決します。ワークスペース宣言ディレクトリ内のパッケージは、最上位ルート パッケージのノードモジュールにソフトリンクされます。

公式 Web サイトから例を挙げて説明します。

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

my-project という名前の npm パッケージには、ワークスペースによって構成されたディレクトリがあります。

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

そして、my-project という名前の最上位のルート パッケージにはパッケージ/サブパッケージがあります。このとき、npm install を実行すると、ルート パッケージの node_modules にインストールされた npm パッケージは、ローカルの package/a を指します。

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

上記の

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

は、からのパッケージを指します。ローカルの npm パッケージにリンクする、node_modules 内のソフト リンク

三、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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。