Node.js v18.7.0 文档


目录

package 包模块#

中英对照

介绍#

中英对照

包是由 package.json 文件描述的文件夹树。 包由包含 package.json 文件的文件夹和所有子文件夹组成,直到包含另一个 package.json 文件的下一个文件夹或名为 node_modules 的文件夹。

确定模块系统#

中英对照

当作为初始输入传入、或者当被 import 语句或 import() 表达式引用时,Node.js 会将以下视为ES 模块

      模块加载器#

      中英对照

      Node.js 有两个系统用于解析说明符和加载模块。

          package.json 和文件扩展名#

          中英对照

          在包中,package.json "type" 字段定义了 Node.js 应该如何解释 .js 文件。 如果 package.json 文件没有 "type" 字段,则 .js 文件将被视为 CommonJS

          
          

          
          

            --input-type 标志#

            中英对照

            作为参数传给 --eval(或 -e),或通过 STDIN 管道传输到 node 的字符串,在设置 --input-type=module 标志时被视为 ES 模块

            
            

            确定包管理器#

            中英对照

            虽然所有 Node.js 项目在发布后都可以由所有包管理器安装,但他们的开发团队通常需要使用特定的包管理器。 为了使这个过程更容易,Node.js 附带了一个名为 Corepack 的工具,旨在使所有包管理器在您的环境中透明可用,只要您安装了 Node.js

            包的入口#

            中英对照

            在包的 package.json 文件中,两个字段可以定义包的入口点:"main""exports"。 这两个字段都适用于 ES 模块和 CommonJS 模块入口点。

            
            

            
            

            
            

            主入口的导出#

            中英对照

            当编写新包时,建议使用 "exports" 字段:

            
            

            
            

            子路径的导出#

            中英对照

            当使用 "exports" 字段时,可以通过将主入口点视为 "." 子路径来定义自定义子路径以及主入口点:

            
            

            
            

            
            
            Extensions in subpaths#

            中英对照

            包作者应在其导出中提供扩展 (import 'pkg/subpath.js') 或无扩展 (import 'pkg/subpath') 子路径。 这确保每个导出的模块只有一个子路径,以便所有依赖项导入相同的一致说明符,使消费者清楚地了解包合同并简化包子路径的完成。

            导出的语法糖#

            中英对照

            如果 "." 导出是唯一的导出,则 "exports" 字段为这种情况提供了语法糖,即直接的 "exports" 字段值。

            
            

            
            

            子路径的导入#

            中英对照

            除了 "exports" 字段之外,还有一个包 "imports" 字段用于创建仅适用于包本身的导入说明符的私有映射。

            
            

            子路径的模式#

            中英对照

            对于具有少量导出或导入的包,我们建议显式地列出每个导出子路径条目。 但是对于具有大量子路径的包,这可能会导致 package.json 膨胀和维护问题。

            
            

            
            

            
            
            
            

            条件导出#

            中英对照

            条件导出提供了一种根据特定条件映射到不同路径的方法。 CommonJS 和 ES 模块导入都支持它们。

            
            

              
              

              嵌套的条件#

              中英对照

              除了直接映射,Node.js 还支持嵌套条件对象。

              
              

              处理用户条件#

              中英对照

              运行 Node.js 时,可以使用 --conditions 标志添加自定义用户条件:

              
              

              社区条件定义#

              中英对照

              除了在 Node.js 核心中实现的 "import""require""node""node-addons""default" 条件之外的条件字符串默认被忽略。

                  使用名称来引用包#

                  中英对照

                  在一个包中,包的 package.json "exports" 字段中定义的值可以通过包的名称引用。 例如,假设 package.json 是:

                  
                  

                  
                  

                  
                  

                  
                  

                  
                  
                  
                  
                  
                  
                  
                  

                  双 CommonJS/ES 模块包#

                  中英对照

                  在 Node.js 中引入对 ES 模块的支持之前,包作者的一种常见模式是在他们的包中包含 CommonJS 和 ES 模块 JavaScript 源代码,其中 package.json "main" 指定了 CommonJS 入口点,而 package.json "module" 指定了 ES模块入口点。 这使 Node.js 能够运行 CommonJS 入口点,而构建工具(例如捆绑器)使用 ES 模块入口点,因为 Node.js 忽略(并且仍然忽略)顶层 "module" 字段。

                  双包的危害#

                  中英对照

                  当应用程序使用提供 CommonJS 和 ES 模块源的包时,如果包的两个版本都被加载,则存在某些错误的风险。 此潜力来自于 const pkgInstance = require('pkg') 创建的 pkgInstanceimport pkgInstance from 'pkg' 创建的 pkgInstance(或像 'pkg/module' 这样的替代主路径)不同的事实。 这是“双包风险”,同一包的两个版本可以在同一个运行时环境中加载。 虽然应用程序或包不太可能有意直接加载两个版本,但应用程序加载一个版本而应用程序的依赖项加载另一个版本是很常见的。 这种危险可能发生,因为 Node.js 支持混合 CommonJS 和 ES 模块,并可能导致意外行为。

                  在避免或最小化危害的同时编写双包#

                  中英对照

                  首先,当一个包同时包含 CommonJS 和 ES 模块源并且这两个源都通过单独的主入口点或导出路径提供以在 Node.js 中使用时,就会发生上一节中描述的危险。 一个包可能被写成任何版本的 Node.js 只接收 CommonJS 源,并且包可能包含的任何单独的 ES 模块源仅用于其他环境,例如浏览器。 这样的包可以被任何版本的 Node.js 使用,因为 import 可以引用 CommonJS 文件;但它不会提供使用 ES 模块语法的任何优点。

                    方法1:使用 ES 模块封装器#

                    中英对照

                    在 CommonJS 中编写包或将 ES 模块源代码转换为 CommonJS,并创建定义命名导出的 ES 模块封装文件。 使用条件导出, import 使用 ES 模块封装器,require 使用 CommonJS 入口点。

                    
                    

                    
                    
                    
                    

                    
                    

                      
                      
                      方法2:隔离状态#

                      中英对照

                      package.json 文件可以直接定义单独的 CommonJS 和 ES 模块入口点:

                      
                      

                          
                          

                          Node.js package.json 字段定义#

                          中英对照

                          本节描述了 Node.js 运行时使用的字段。 其他工具(例如 npm)使用 Node.js 忽略且未在此处记录的其他字段。

                            "name"#

                            中英对照

                              
                              

                              "name" 字段定义了你的包名。 发布到 npm 仓库需要满足特定要求的名称。

                              "main"#

                              中英对照

                                
                                

                                当通过 node_modules 查找按名称导入时,则 "main" 字段定义了包的入口点。 其值为路径。

                                
                                

                                "packageManager"#

                                中英对照

                                  
                                  

                                  "packageManager" 字段定义了在处理当前项目时预期使用的包管理器。 它可以设置为任何支持的包管理器,并确保您的团队使用完全相同的包管理器版本,而无需安装 Node.js 以外的任何其他东西。

                                  "type"#

                                  中英对照

                                    "type" 字段定义了 Node.js 用于所有 .js 文件的模块格式,这些 .js 文件将该 package.json 文件作为其最近的父文件。

                                    
                                    
                                    
                                    

                                    
                                    

                                    "exports"#

                                    中英对照

                                      
                                      

                                      "exports" 字段允许定义包的入口点,当通过 node_modules 查找或自引用加载到其自身的名称的名称导入时。 Node.js 12+ 支持它作为 "main" 的替代方案,它可以支持定义子路径导出条件导出,同时封装内部未导出的模块。

                                      "imports"#

                                      中英对照

                                        
                                        

                                        导入字段中的条目必须是以 # 开头的字符串。

                                        返回顶部