• WHAT - package.json 解释


    一、前言

    HOW - 编写并发布一个 npm 包模块(含 CLI 工具包开发) 中我们简单介绍过 package.json 文件,并提供了如下示例:

     {
       // 包的名称
       "name": "changelog-tool",
    
       // 包的版本号
       "version": "0.5.0",
    
       // 这将显示在NPM搜索结果中
       "description": "A CLI tool for manipulating changelogs",
    
       // 这告诉Node这是一个ESM包
       // 当然不是严格需要的,如果我们在每个地方都是使用 .mjs
       "type": "module",
    
       // 如果需要在编码的时候使用此包中的方法(不是 CLI 中),则需要在这里指定导出的模块入口文件
       "main": "index.mjs",
    
       // 将必须的文件才发布到 npm
       "files": {
          "dist",
          "types",
          //...
       }
    
       "scripts": {
         // 运行测试用例
         "test": "node --test",
       },
    
       // 方便更好的在 npmjs.org 上发现此包
       "keywords": [
         "changelog",
         "markdown"
       ],
    
       // 作者信息
       "author": "Evert Pot (https://evertpot.com/)",
    
       // 做任何你想做的事(MIT协议基本没有约束)
       "license": "MIT",
    
       "engine": {
         // 警告尚未升级的用户
         "node": ">16"
       },
    
       "bin": {
         // 指定执行文件,当人们安装这个包时,可以通过 `npx changelog` 执行
         // 如果全局安装了这个包,就会有一个 `changelog` 命令
         "changelog": "./cli.mjs"
       },
       "devDependencies": {
         "@types/node": "^18.11.19",
       }
    }
    

    除了上述几个 Key Fields,一个完整的开源库还应该设置更多属性。今天我们就来主要介绍一下 package.json

    二、介绍

    package.json 文件是 Node.js 项目中的一个关键组件,它包含了项目的元数据,比如项目依赖、脚本、版本等信息。package.json 文件是管理 Node.js 项目的灵活而强大的方式,确保项目的一致性和便于协作。

    下面是一个 package.json 文件的示例以及各个字段的解释。

    2.1 package.json 文件示例

    {
      "name": "example-project",
      "version": "1.0.0",
      "description": "一个展示 package.json 文件的示例项目",
      "main": "index.js",
      "scripts": {
        "start": "node index.js",
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "repository": {
        "type": "git",
        "url": "git+https://github.com/username/example-project.git"
      },
      "keywords": [
        "示例",
        "演示",
        "node"
      ],
      "author": "Your Name ",
      "license": "ISC",
      "bugs": {
        "url": "https://github.com/username/example-project/issues"
      },
      "homepage": "https://github.com/username/example-project#readme",
      "dependencies": {
        "express": "^4.17.1"
      },
      "devDependencies": {
        "nodemon": "^2.0.7"
      }
    }
    

    2.2 关键字段

    1. name: 项目的名称,应为小写字母,可以包含连字符和下划线。
    2. version: 项目的当前版本,遵循语义化版本控制(semver)
    3. description: 项目的简短描述。
    4. main: 应用程序的入口文件(通常是主 JavaScript 文件)。
    5. scripts: 定义一组可以通过 npm run 运行的脚本命令。常见的脚本包括:
      • "start": 通常用于启动应用程序。
      • "test": 用于运行测试。
    6. repository: 关于源代码托管仓库的信息。
    7. keywords: 一个字符串数组,帮助人们在搜索时找到你的项目。
    8. author: 项目作者的名字和联系方式。
    9. license: 项目的许可证。
    10. bugs: 报告问题的地址。
    11. homepage: 项目的主页 URL。
    12. dependencies: 一个对象,指定了项目的运行时依赖及其版本。
    13. devDependencies: 一个对象,指定了项目的开发时依赖,仅在开发过程中需要。

    2.3 常用命令

    • 安装依赖: 运行 npm install 安装 package.json 中列出的所有依赖。
    • 添加依赖: 运行 npm install 添加一个新的依赖,并自动更新 package.json
    • 运行脚本: 运行 npm run 执行 scripts 部分定义的脚本。

    2.4 自定义脚本

    你可以在 scripts 部分定义任何自定义脚本。例如:

    "scripts": {
      "start": "node index.js",
      "test": "echo \"Error: no test specified\" && exit 1",
      "build": "webpack --config webpack.config.js",
      "lint": "eslint ."
    }
    

    这样你就可以运行自定义命令,比如 npm run build 使用 Webpack 打包你的应用程序,或者 npm run lint 使用 ESLint 检查你的代码。

    三、element-plus 完整示例

    业内有名的组件库 element-pluspackage.json 文件:

    {
      "name": "element-plus",
      "version": "2.7.1",
      "description": "A Component Library for Vue 3",
      "keywords": [
        "element-plus",
        "element",
        "component library",
        "ui framework",
        "ui",
        "vue"
      ],
      "homepage": "https://element-plus.org/",
      "bugs": {
        "url": "https://github.com/element-plus/element-plus/issues"
      },
      "license": "MIT",
      "main": "lib/index.js",
      "module": "es/index.mjs",
      "types": "es/index.d.ts",
      "exports": {
        ".": {
          "types": "./es/index.d.ts",
          "import": "./es/index.mjs",
          "require": "./lib/index.js"
        },
        "./global": {
          "types": "./global.d.ts"
        },
        "./es": {
          "types": "./es/index.d.ts",
          "import": "./es/index.mjs"
        },
        "./lib": {
          "types": "./lib/index.d.ts",
          "require": "./lib/index.js"
        },
        "./es/*.mjs": {
          "types": "./es/*.d.ts",
          "import": "./es/*.mjs"
        },
        "./es/*": {
          "types": [
            "./es/*.d.ts",
            "./es/*/index.d.ts"
          ],
          "import": "./es/*.mjs"
        },
        "./lib/*.js": {
          "types": "./lib/*.d.ts",
          "require": "./lib/*.js"
        },
        "./lib/*": {
          "types": [
            "./lib/*.d.ts",
            "./lib/*/index.d.ts"
          ],
          "require": "./lib/*.js"
        },
        "./*": "./*"
      },
      "unpkg": "dist/index.full.js",
      "jsdelivr": "dist/index.full.js",
      "repository": {
        "type": "git",
        "url": "git+https://github.com/element-plus/element-plus.git"
      },
      "publishConfig": {
        "access": "public"
      },
      "style": "dist/index.css",
      "sideEffects": [
        "dist/*",
        "theme-chalk/**/*.css",
        "theme-chalk/src/**/*.scss",
        "es/components/*/style/*",
        "lib/components/*/style/*"
      ],
      "peerDependencies": {
        "vue": "^3.2.0"
      },
      "dependencies": {
        "@ctrl/tinycolor": "^3.4.1",
        "@element-plus/icons-vue": "^2.3.1",
        "@floating-ui/dom": "^1.0.1",
        "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
        "@types/lodash": "^4.14.182",
        "@types/lodash-es": "^4.17.6",
        "@vueuse/core": "^9.1.0",
        "async-validator": "^4.2.5",
        "dayjs": "^1.11.3",
        "escape-html": "^1.0.3",
        "lodash": "^4.17.21",
        "lodash-es": "^4.17.21",
        "lodash-unified": "^1.0.2",
        "memoize-one": "^6.0.0",
        "normalize-wheel-es": "^1.2.0"
      },
      "devDependencies": {
        "@types/node": "*",
        "csstype": "^2.6.20",
        "vue": "^3.2.37",
        "vue-router": "^4.0.16"
      },
      "vetur": {
        "tags": "tags.json",
        "attributes": "attributes.json"
      },
      "web-types": "web-types.json",
      "browserslist": [
        "> 1%",
        "not ie 11",
        "not op_mini all"
      ],
      "gitHead": "b0ce448b4dc7c8981ed73bd2554f4dbbe05d1446"
    }
    

    3.1 main 和 module

    package.json 文件中,mainmodule 字段用于指定项目的入口文件,但它们有不同的用途和作用范围,主要与模块系统的选择有关。

    1. main 字段

    main 字段指定了 Node.js 项目入口文件的路径。它告诉 Node.js 在使用 require() 函数引入模块时应该加载哪个文件。如果没有指定 main 字段,Node.js 默认会寻找项目根目录下的 index.js 文件。

    示例

    {
      "main": "index.js"
    }
    

    在上面的例子中,如果你的项目被其他项目引入,Node.js 会从 index.js 文件开始加载。

    2. module 字段

    module 字段用于指定 ECMAScript 模块(ESM)的入口文件路径。它主要面向现代 JavaScript 环境,如使用 import 语句的前端项目或支持 ESM 的 Node.js 项目。这个字段提供了一个入口点,允许 JavaScript 运行时和打包工具(如 webpack、rollup)以 ESM 格式加载模块。

    示例

    {
      "module": "index.mjs"
    }
    

    在这个例子中,当你的项目被打包工具或支持 ESM 的环境引入时,它会从 index.mjs 文件开始加载。

    3. 综合示例

    一个完整的 package.json 文件可能同时包含 mainmodule 字段,以便兼容 CommonJS 和 ESM 模块系统。

    {
      "name": "example-project",
      "version": "1.0.0",
      "description": "一个展示 package.json 文件的示例项目",
      "main": "index.js",
      "module": "index.mjs",
      "scripts": {
        "start": "node index.js",
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "dependencies": {
        "express": "^4.17.1"
      },
      "devDependencies": {
        "nodemon": "^2.0.7"
      }
    }
    

    通过同时定义 mainmodule 字段,可以确保你的包在不同的模块系统中都能被正确加载和使用。这对于兼容性和灵活性非常重要,尤其是在需要支持多种环境的库或工具中。

    3.2 types

    types 字段(或 typings)用于指定 TypeScript 类型定义文件的路径。它通常用于那些用 JavaScript 编写的包,并且希望提供 TypeScript 类型支持。这个字段指向一个包含 TypeScript 声明的文件,通常是 .d.ts 文件。

    1. 示例

    假设你有一个项目,其中包含一个 TypeScript 类型定义文件 index.d.ts,你的 package.json 文件可以这样配置:

    {
      "name": "example-project",
      "version": "1.0.0",
      "description": "一个展示 package.json 文件的示例项目",
      "main": "index.js",
      "module": "index.mjs",
      "types": "index.d.ts",
      "scripts": {
        "start": "node index.js",
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "dependencies": {
        "express": "^4.17.1"
      },
      "devDependencies": {
        "nodemon": "^2.0.7"
      }
    }
    

    2. TypeScript 类型定义文件的作用

    1. 提供类型支持: 当使用你的库时,TypeScript 编译器可以引用这个类型定义文件,提供类型检查和代码补全。
    2. 提高开发体验: 使用 TypeScript 类型定义文件可以使你的库在 TypeScript 项目中更容易使用,因为开发者可以获得更好的代码提示和类型检查。

    3. 类型定义文件示例

    假设你的项目的主要功能在 index.js 文件中实现,你可以创建一个 index.d.ts 文件来描述这些功能的类型:

    index.js

    function greet(name) {
      return `Hello, ${name}!`;
    }
    module.exports = {
      greet
    };
    

    index.d.ts

    export function greet(name: string): string;
    

    4. 发布带有类型定义的包

    当你发布带有类型定义文件的包时,TypeScript 项目可以直接使用你的类型定义文件,无需额外配置。这使得你的包对使用 TypeScript 的开发者更加友好。

    3.3 styles

    styles 字段(虽然不属于官方的 package.json 规范)有时会出现在某些前端项目中,用于指定项目的主要样式表文件路径。这个字段主要用于与构建工具和打包工具(如 webpack)集成,方便这些工具找到并处理样式文件。

    1. 示例

    假设你有一个项目,其中包含一个主要的 CSS 文件 dist/index.css,你的 package.json 文件可以这样配置:

    {
      "name": "example-project",
      "version": "1.0.0",
      "description": "一个展示 package.json 文件的示例项目",
      "main": "index.js",
      "module": "index.mjs",
      "types": "index.d.ts",
      "styles": "dist/index.css",
      "scripts": {
        "start": "node index.js",
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "dependencies": {
        "express": "^4.17.1"
      },
      "devDependencies": {
        "nodemon": "^2.0.7"
      }
    }
    

    2. 用途

    1. 构建工具集成: 某些构建工具(如 webpack、rollup)或插件可能会读取 styles 字段,以便自动加载和处理样式文件。
    2. 模块化 CSS: 当你的包被其他项目引用时,styles 字段可以帮助开发者快速找到并加载样式文件。

    这在一些组件库提供按需加载能力时常见。

    3.4 peerDependencies

    package.json 文件中,dependenciesdevDependenciespeerDependencies 是用于管理和声明项目所需依赖的三种不同方式。它们的主要区别在于依赖的用途和安装时机。

    1. dependencies

    dependencies 字段列出了项目在生产环境中运行所需的包。换句话说,这些依赖是项目在正常运行时必需的。安装项目时,npm install 会自动安装这些依赖。

    示例
    {
      "dependencies": {
        "express": "^4.17.1",
        "lodash": "^4.17.21"
      }
    }
    

    2. devDependencies

    devDependencies 字段列出了项目在开发阶段所需的包。这些依赖在项目构建、测试或开发时使用,但在生产环境中不需要。安装项目时,如果使用 npm install --productionNODE_ENV=production npm install,则不会安装这些依赖。

    示例
    {
      "devDependencies": {
        "eslint": "^7.32.0",
        "jest": "^27.0.6"
      }
    }
    

    3. peerDependencies

    peerDependencies 字段用来声明项目对某个包的依赖,但是该包应由项目的使用者(即最终用户)来安装。

    这在创建插件或库时特别有用,确保依赖的版本与最终使用项目的版本兼容。例如,一个 React 组件库可能会将 reactreact-dom 声明为 peerDependencies,以确保使用该库的项目使用的是正确版本的 react

    示例
    {
      "peerDependencies": {
        "react": "^17.0.0",
        "react-dom": "^17.0.0"
      }
    }
    
    进一步理解

    peerDependencies 字段的主要作用是声明项目对某些依赖包的兼容性要求,但并不直接安装这些依赖包。它通常用于插件或库,以确保这些插件或库与宿主应用的依赖版本一致。

    理解 peerDependencies 可以通过以下几个方面来更清晰:

    1. 声明依赖的兼容性

    当你的库或插件需要与某个主项目共享依赖时,peerDependencies 可以声明这些共享依赖的版本范围。例如,一个 React 组件库可能需要使用者项目中的 reactreact-dom,但不希望自己安装这些依赖,因为它们应该由使用者项目来管理和安装。

    1. 避免版本冲突

    通过使用 peerDependencies,可以避免安装多个版本的同一个包,从而减少版本冲突的风险。如果每个库都各自安装自己的 react 版本,可能会导致不同版本的 react 互相冲突,从而引发错误。

    假设你在开发一个 React 组件库:

    package.json

    {
      "name": "my-react-library",
      "version": "1.0.0",
      "peerDependencies": {
        "react": "^17.0.0",
        "react-dom": "^17.0.0"
      }
    }
    

    使用者项目中安装你的库时,npm 会发出警告,提示需要安装特定版本的 reactreact-dom

    npm install my-react-library
    

    如果用户项目中没有安装 reactreact-dom,或安装的版本与 peerDependencies 中指定的不兼容,npm 会显示警告信息。

    例如,如果用户的项目中安装了 React 16 而不是 React 17,运行 npm install 时可能会看到这样的警告:

    npm WARN my-react-library@1.0.0 requires a peer of react@^17.0.0 but none is installed. You must install peer dependencies yourself.
    

    用户需要确保其项目中的依赖版本与 peerDependencies 中声明的版本兼容。通常这意味着用户需要更新其项目中的相关依赖版本:

    npm install react@^17.0.0 react-dom@^17.0.0
    

    3.5 exports

    exports 字段是在 Node.js 12 及其以上版本中引入的,用于指定模块的导出路径和条件导出。

    它提供了一种更精细的方式来定义项目中的入口点和模块分发,支持不同的模块系统(如 CommonJS 和 ES Module)以及不同的运行环境(如浏览器和 Node.js)。

    为什么使用 exports

    • 更安全的模块导出:通过限制模块的导出路径,防止用户直接访问内部文件结构。
    • 条件导出:根据运行环境或模块系统提供不同的导出文件。
    • 简化入口点管理:统一管理多入口点。

    exports 字段示例

    假设你的项目结构如下:

    my-package/
    ├── package.json
    ├── index.js
    ├── index.mjs
    └── lib/
        ├── feature.cjs
        ├── feature.mjs
        └── feature.js
    

    你可以在 package.json 中使用 exports 字段来定义不同环境下的导出:

    {
      "name": "my-package",
      "version": "1.0.0",
      "main": "index.js",
      "module": "index.mjs",
      "exports": {
        ".": {
          "require": "./index.js",
          "import": "./index.mjs"
        },
        "./feature": {
          "require": "./lib/feature.cjs",
          "import": "./lib/feature.mjs",
          "default": "./lib/feature.js"
        }
      }
    }
    

    解释

    • ".": 代表包的根路径,定义包的主要入口点。

      • "require": 指定 CommonJS 模块系统下的入口点。
      • "import": 指定 ES Module 模块系统下的入口点。
    • "./feature": 定义 my-package/feature 的导出路径。

      • "require": 使用 CommonJS 模块系统时,导出 ./lib/feature.cjs 文件。
      • "import": 使用 ES Module 模块系统时,导出 ./lib/feature.mjs 文件。
      • "default": 其他情况使用 ./lib/feature.js 文件。

    更多复杂示例

    可以为不同的条件提供更多的导出路径:

    {
      "exports": {
        ".": {
          "browser": {
            "import": "./index.browser.mjs",
            "require": "./index.browser.cjs"
          },
          "node": {
            "import": "./index.node.mjs",
            "require": "./index.node.cjs"
          },
          "default": "./index.js"
        },
        "./feature": {
          "browser": {
            "import": "./lib/feature.browser.mjs",
            "require": "./lib/feature.browser.cjs"
          },
          "node": {
            "import": "./lib/feature.node.mjs",
            "require": "./lib/feature.node.cjs"
          },
          "default": "./lib/feature.js"
        }
      }
    }
    

    使用场景

    • 多模块系统支持:同时支持 CommonJS 和 ES Module。
    • 环境特定导出:为浏览器和 Node.js 环境提供不同的导出文件。
    • 模块拆分:可以根据需要将模块拆分成多个文件,并通过 exports 字段统一管理。

    通过合理使用 exports 字段,可以使你的 Node.js 包在现代 JavaScript 生态系统中更具适应性和灵活性。

    3.6 unpkg 和 jsdelivr

    unpkgjsDelivr 都是用于提供前端资源(如 JavaScript、CSS、图像等)的 CDN(内容分发网络)服务,使得开发者可以方便地在项目中引用这些资源而无需自行托管。

    unpkg

    {
      "unpkg": "dist/umd/package.min.js"
    }
    

    这个字段告诉 unpkg CDN,当有人访问该包时,应该返回 dist/umd/package.min.js 文件。

    unpkg 是一个快速、稳定的 CDN,用于托管 npm 中的开源包。它允许你通过简单地提供包名和版本号来直接引用 npm 包中的文件,而无需安装这些包或手动下载文件。通过 unpkg,你可以在浏览器中直接访问 npm 包中的任何文件。

    例如,如果你想在项目中使用 React,你可以通过以下方式引用 React 的主要文件:

    <script src="https://unpkg.com/react@17/umd/react.production.min.js">script>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js">script>
    

    jsDelivr

    {
      "jsdelivr": "dist/umd/package.min.js"
    }
    

    这个字段告诉 jsDelivr CDN,当有人访问该包时,应该返回 dist/umd/package.min.js 文件。

    jsDelivr 是另一个流行的 CDN,提供了更多的功能和定制选项。它支持各种前端资源,包括 JavaScript 库、CSS 框架、图像、字体等。jsDelivr 的优点之一是它有多个节点,因此可以提供更快的下载速度和更高的可用性。

    与 unpkg 类似,你可以使用 jsDelivr 来直接引用各种开源资源,而无需自行下载和托管。例如,你可以通过以下方式引用 jQuery:

    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js">script>
    

    共同特点

    • 快速可靠:unpkg 和 jsDelivr 都是快速可靠的 CDN 服务,能够提供高性能的前端资源加载。
    • 免费使用:它们都是免费使用的,任何人都可以直接引用它们提供的资源。
    • 支持版本控制:你可以通过指定版本号来确保获取特定版本的资源,这有助于保持你的应用程序的稳定性和一致性。

    如何选择

    • 如果你只需要简单快速地引用 npm 包中的文件,并且不需要太多的定制选项,那么 unpkg 是一个不错的选择。
    • 如果你需要更多的功能和定制选项,或者希望提供更好的性能和可用性,那么可以考虑使用 jsDelivr。

    无论你选择哪个 CDN,它们都可以帮助你更轻松地管理前端资源,加速网站加载速度,并提高开发效率。

    3.7 publishConfig

    publishConfig 字段是 package.json 文件中的一个配置项,用于指定发布 npm 包时的额外设置。

    通过 publishConfig 字段,你可以设置一些发布相关的配置,例如发布时的访问权限、发布时所使用的注册表等。

    示例

    以下是一个典型的 publishConfig 字段的示例:

    {
      "name": "my-package",
      "version": "1.0.0",
      "description": "A sample package",
      "main": "index.js",
      "publishConfig": {
        "access": "public",
        "registry": "https://registry.npmjs.org/"
      }
    }
    

    在这个示例中,publishConfig 字段指定了两个选项:

    • access: 指定了发布时的访问权限。在这个例子中,设置为 "public" 表示发布后的包是公共的,所有人都可以访问。
    • registry: 指定了发布时所使用的 npm 注册表的 URL。在这个例子中,设置为 "https://registry.npmjs.org/" 表示发布到 npm 公共注册表。

    使用场景

    • 发布权限管理: 如果你想发布一个私有的 npm 包,你可以将 access 设置为 "restricted",只允许有权限的用户访问。
    • 自定义注册表: 如果你使用了自定义的 npm 注册表,你可以通过 registry 字段来指定发布时所使用的注册表的 URL。

    注意事项

    • publishConfig 字段通常用于在发布 npm 包时自定义配置,但它并不是必需的。如果你没有特殊的需求,可以不用设置它。
    • 如果你使用的是默认的 npm 公共注册表,并且不需要设置其他发布参数,那么通常不需要额外配置 publishConfig

    理解 publishConfig 字段的用途和配置选项,可以帮助你更好地管理和发布 npm 包。

    3.8 sideEffects

    sideEffects 是一个用于告知 webpack 和其他模块打包工具模块是否有副作用(side effects)的字段,出现在模块的 package.json 文件中。副作用是指模块执行时,不仅仅是导出一个值,而是会执行一些额外的操作,例如修改全局变量、执行某些代码等。

    为什么需要 sideEffects

    对于纯粹的 JavaScript 模块,大部分情况下,模块导入后只是为了获取导出的值,而不会对环境产生任何副作用。然而,一些模块可能会包含副作用,这些副作用可能会影响到整个应用程序的行为,甚至影响到其他模块。在模块打包时,如果可以确定某个模块没有副作用,打包工具就可以进行更多的优化,例如删除未使用的代码、提取公共代码等。而如果某个模块包含了副作用,打包工具则需要谨慎处理,以避免意外行为。

    有关模块包含副作用的内容可以阅读 WHAT - Webpack 详解系列(七)

    Webpack 4 中新增了一个 sideEffects 特性,它允许我们通过配置标识我们的代码是否有副作用,从而提供更大的压缩空间。模块的副作用指的是:模块执行的时候除了导出成员,是否还做了其他的事情。这个特性一般只有我们去开发一个 npm 模块时才会用到。以自定义 npm 项目为例,那此时 Webpack 在打包某个模块之前,会先检查这个模块所属的 package.json 中的 sideEffects 标识,以此来判断这个模块是否有副作用,如果没有副作用的话,这些没用到的模块就不再被打包。

    sideEffects 的取值

    sideEffects 字段的取值可以是以下三种形式之一:

    • false: 表示模块没有副作用。这意味着打包工具可以安全地进行一些额外的优化。
    • true: 表示模块具有副作用。在打包时,打包工具将假定该模块具有副作用,并相应地处理它。
    • 数组: 数组中的每个元素是一个匹配模式,表示具有副作用的文件路径。这些路径可以是文件名、文件夹名,也可以是通配符表达式。

    示例

    以下是一个 sideEffects 字段的示例:

    {
      "name": "my-package",
      "version": "1.0.0",
      "description": "A sample package",
      "main": "index.js",
      "sideEffects": ["*.css", "*.scss", "*.less"]
    }
    

    在这个示例中,sideEffects 字段告知打包工具,在打包时应该考虑所有的 .css.scss.less 文件,因为它们可能包含一些样式文件的副作用。

    使用场景

    • 优化打包: 通过准确地声明模块是否具有副作用,打包工具可以更好地进行代码优化,提高打包性能。
    • 避免意外行为: 对于具有副作用的模块,打包工具可以采取适当的措施,以避免意外行为,例如不删除未使用的代码等。

    注意事项

    • 在很多情况下,你可以放心地将 sideEffects 设置为 false,因为大多数模块都不会有副作用。
    • 如果你不确定模块是否具有副作用,最好是不设置 sideEffects 字段,或者设置为 true,以确保不会因为错误的优化而导致意外行为。

    通过正确地设置 sideEffects 字段,可以帮助你更好地管理和优化你的模块打包过程。

    3.9 browserslist

    browserslist 是一个用于指定项目目标浏览器的字段,出现在项目根目录下的 package.json 文件中。它告知前端工具(例如 Autoprefixer、Babel、PostCSS 等)需要支持哪些浏览器版本,以便自动添加适当的 CSS 前缀或将 JavaScript 代码转换成兼容性更好的形式。

    为什么需要 browserslist

    Web 开发中,不同的浏览器对于一些 CSS 属性和 JavaScript 特性的支持程度有所差异。为了确保项目在不同浏览器中的兼容性,开发者通常需要根据项目需求选择目标浏览器,并进行相应的兼容性处理。

    browserslist 的出现简化了这个过程,使得开发者只需在项目中设置一次目标浏览器列表,然后前端工具就可以根据这个列表自动进行相应的处理,大大提高了开发效率。

    browserslist 的使用

    你可以在 package.json 文件中的 browserslist 字段中指定目标浏览器的列表,也可以通过 .browserslistrc 文件或者 browserslist 配置文件来配置。

    示例 browserslist 配置:

    "browserslist": [
      "last 2 versions",
      "> 1%",
      "IE 11"
    ],
    

    这个配置表示项目的目标浏览器为:

    • 最近两个版本的所有浏览器
    • 浏览器市场份额大于 1% 的浏览器
    • Internet Explorer 11
    "browserslist": [
      "> 1%",
      "not ie 11",
      "not op_mini all"
    ],
    

    这个配置表示项目的目标浏览器为:

    • 浏览器市场份额大于 1% 的浏览器
    • 不包括 Internet Explorer 11
    • 不包括 Opera Mini 浏览器

    使用场景

    • CSS 兼容性处理: Autoprefixer 等工具可以根据 browserslist 配置自动添加 CSS 前缀,以确保样式在目标浏览器中的兼容性。
    • JavaScript 转换: Babel 等工具可以根据 browserslist 配置自动将 ES6+ 的 JavaScript 代码转换成向下兼容的代码,以确保在目标浏览器中的兼容性。

    注意事项

    • 选择目标浏览器: 在选择目标浏览器时,应考虑项目的实际需求和用户群体使用的浏览器情况,避免过度或不必要的兼容性处理。
    • 定期更新配置: 随着浏览器的更新和市场份额的变化,建议定期更新 browserslist 配置,以确保项目始终针对最新的浏览器进行优化。

    通过合理配置 browserslist,可以帮助开发者更轻松地管理项目的浏览器兼容性,提高开发效率。

  • 相关阅读:
    CKKS同态加密方案初步学习
    http和https的区别,以及https涉及到的加密过程
    [mit6.1810] lab Utilities
    PAT甲级 1091 Acute Stroke(30) (Flood Fill)
    Cobalt Strike (CS) 逆向初探
    解析多层级 JSON 如:get(A.B.C)
    深度学习 | Pytorch深度学习实践 (Chapter 1~9)
    Cesium 根据飞机航线计算飞机的Heading(偏航角)、Pitch(俯仰角)、Roll(翻滚角)
    深入理解与应用Keepalive机制
    docker报错问题解决:Error Invalid or corrupt jarfile app.jar
  • 原文地址:https://blog.csdn.net/weixin_58540586/article/details/139297693