package.json & 它的屬性


Posted by TempuraEngineer on 2022-05-14

package.json是甚麼

package.json是JS、Node專案的JSON。可以透過npm init生成。
裡面記錄了版本、憑證、依賴、指令(script)...等。可以把它視為專案的控制面板。


package.json的各種屬性

  • name
    套件名稱、import名。不可含有大寫、.、_,且有最長為214字母

    Relevant when using named imports within a package. Also used by package managers as the name of the package.

  • version
    套件版本

      // 打版
      npm version [<newversion> | major | minor | patch | premajor | preminor | preminor | prepatch | prerelease | from-git]
    
      // 看套件最新版本號
      npm view vue version --json
    
      // 看套件所有版本號
      npm view vue versions --json
    
  • description
    套件簡介

  • keywords
    一些關鍵字,讀這邊可以粗淺了解套件,可以視npm registry的hashtag

      // 擷取自bootstrap
    
      "keywords": [
        "css",
        "sass",
        "mobile-first",
        "responsive",
        "front-end",
        "framework",
        "web"
      ],
    
  • license
    套件使用證照,通常會走SPDX License identifier這套規則。

    從license屬性可以得知「版權的歸屬」、「是否可修改」、「在甚麼情況可以自由使用」、「作者是否承擔風險」...等。

    例如MIT就是一種常見的開源協議。它標明了「所有權歸屬作者」、「其他開發者可以免費自由使用、修改、發行、販賣,但作者不承擔任何責任」,是個相當寬鬆的協議。

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY

  • scripts
    指令。在script定義的指令可以透過npm run [script name]去執行。npm run 可以查閱package.json中所有的script

  • dependencies & devDependencies
    專案裡裝的套件 & 開發用套件
  • peerDependencies
    (2023/3/3 更新)

    Peer dependencies are a special type of dependency that would only ever come up if you were publishing your own package.

peerDependencies通常會出現在你寫了一個package,並把它用在某個專案

而這個package的依賴foo,也是專案的其中一個依賴,所以為了避免重複安裝就會把foo寫到peerDependencies

    // 避免這種情況

    ├── myProject
    │   └── node_modules
    │       ├── react
    │       ├── react-router-dom
    │       │   └── nodule_modules
    │       │       └── react
    │       └── react-hook-form
    │       │   └── nodule_modules
    │       │       └── react

    // 設定後變成這樣

    ├── myProject
    │   └── node_modules
    │       ├── react
    │       ├── react-router-dom
    │       └── react-hook-form

另外根據node blog - peerDependencies,另一個功用是避免「專案的依賴A」是「專案的依賴B」的依賴時,發生的重複安裝

舉例來說,專案的依賴有「apollo-client」、「apollo-upload-client」,而前者又是後者的依賴

這時有一個因為ApolloLink的type reference的指向不同,導致的type error。除了使用@ts-ignore繞開以外,另一個繞開的方式就是把apollo-client放到peerDependencies

  • exports

定義extry point,功能和main差不多,但是exports比較優先
另外exports可以做條件輸出(Conditional Exports)

// For example, a package that wants to provide different ES module exports for require() and import can be written:

{
  "main": "./main-require.cjs",
  "exports": {
    "import": "./main-module.js",
    "require": "./main-require.cjs"
  },
  "type": "module"
}
  • main
    功能和exports屬性差不多,但exports會比較優先

    The default module when loading the package, if exports is not specified, and in versions of Node.js prior to the introduction of exports.

    The main property of a package.json is a direction to the entry point to the module that the package.json is describing. In a Node.js application, when the module is called via a require statement, the module's exports from the file named in the main property will be returned to the Node.js application.

{
  "main": "./main.js"
}
  • type
    定義套件走CommonJS或ES module規範
module commonjs 沒設type
.js ES module CommonJS CommonJS
.cjs CommonJS CommonJS CommonJS
.mjs ES module ES module ES module

The package type determining whether to load .js files as CommonJS or ES modules.
Files ending with .js are loaded as ES modules when the nearest parent package.json file contains a top-level field "type" with a value of "module".

  • repository & bugs
    source code資訊、issue回報資訊

      // 擷取自bootstrap
    
      "repository": {
        "type": "git",
        "url": "git+https://github.com/twbs/bootstrap.git"
      },
    
      "bugs": {
        "url": "https://github.com/twbs/bootstrap/issues"
      },
    
  • engines
    定義套件使用的lib的版本、開發環境

      // 擷取自tailwind
    
      "engines": {
        "node": ">=12.13.0"
      }
    
  • sideEffects
    定義打包時是否要修剪引入卻未用到的部分,或者要修剪哪些部分。可以是boolean或string[]。
    設為false可避免沒用到的部分,也被打包出去

    Tree shaking is a term commonly used in the JavaScript context for dead-code elimination. It relies on the static structure of ES2015 module syntax, i.e. import and export. The name and concept have been popularized by the ES2015 module bundler rollup.

    The webpack 2 release came with built-in support for ES2015 modules (alias harmony modules) as well as unused module export detection. The new webpack 4 release expands on this capability with a way to provide hints to the compiler via the "sideEffects" package.json property to denote which files in your project are "pure" and therefore safe to prune if unused.

    (以下是上文翻譯)

    Tree shaking是一個常被用於清除以Javascript編寫的永遠不會被執行到的程式碼。它會依賴於ES6模組語法的靜態結構,ex: import, export(之所以說靜態是因為ES module只能做靜態引入,Common JS才能動態引入)

    webpack2內建支援ES6,也有偵測export但卻沒被使用的模組的功能。webpack4釋出後以這那個功能作為基礎擴展出了新功能,可以透過在package.json新增sideEffects屬性來告訴webpack專案中的那些檔案如果沒被用到的話可以修剪,也不會有問題

      // 擷取自vuex
      "sideEffects": false,
    
      // 擷取自bootstrap-vue
    
      "sideEffects": [
        "**/*.css",
        "**/*.scss",
        "**/*.vue",
        "./docs",
        "./types"
      ],
    


📖

Node.js package.json field definitions
configuring npm/package.json
The Basics of Package.json
Understanding the package.json file
作為前端的開源協議知識
Choose an open source license
SPDX License List
npm - peerDependencies
yarn - peerDependencies
node blog - peerDependencies


#npm #package.json #peerDependencies







Related Posts

[ React 筆記 ] input使用useRef存取子元件

[ React 筆記 ] input使用useRef存取子元件

七天學會 swift - 在背景中下載資料並存檔 Day7

七天學會 swift - 在背景中下載資料並存檔 Day7

Vue.js v-model

Vue.js v-model


Comments