【问题标题】:root directory for node module节点模块的根目录
【发布时间】:2016-05-18 20:25:23
【问题描述】:

我有一个非常标准的节点模块,它使用 babel 来转换我们的代码,然后将其输出到“lib”文件夹。 package.json 将“main”指向“lib/index.js”,这样人们就可以require('my-module')

但是,如果我有一个子目录(例如 my-module/server),那么当他们使用 my-module 时,他们必须执行 require('my-module/lib/server')。我见过人们将构建后的步骤将 package.json 复制到 lib 中,但这对我来说感觉很笨拙和错误。 npm 中是否有任何方法可以指定一个主 目录,从而我的模块的任何 require() 都将从该目录开始?然后我可以让用户在没有 lib 部分的情况下执行 require('my-module/server') ...

【问题讨论】:

  • 我认为 require("my-module").server 更习惯,然后明确地让 my-module.js 导出服务器。
  • 问题在于 webpack 将在包中包含(或尝试包含)服务器代码。至少在 2.0 出现摇树之前...
  • 在这种情况下,我会说将 my-module 分解为子组件并执行 require("my-module-server") 更习惯,它依赖于类似 require("my -模块通用”)。那么“my-module”将是一个超级包,包含方便起见的所有内容,但可以单独包含单独的包。两者都不是您正在寻找的,但两者都是解决问题的常用方法。
  • 是的,你可能是对的。 :) 只是希望更简单的东西
  • 这个问题还没有答案吗?有什么问题。我不想建立一个索引文件,因为最基本的要求必须做require('my-module').main。我认为要求您需要的子部分要干净得多。

标签: node.js npm babeljs package.json


【解决方案1】:

我认为最好的解决方案是将 index.js 和所有子模块作为主模块,这样你就可以执行require('your-module').server 之类的操作

【讨论】:

  • 这种方法的问题是webpack会在bundle中包含'.server'
【解决方案2】:

很难看不到您的文件夹结构,但您可以:

  • 使用module.exports =导出babel输出
  • 将其他文件符号链接到目录中

package.json

{ "main": "lib" }

lib/index.js

module.exports = require('./path-to-transpiled-code.js');

// Now also export all the other stuff in this folder dynamically

fs.readdirSync(DIRECTORY_TO_EXPORT, function (err, files) {
  if (err) { throw err; }
  files.forEach(function (file) {
    if (file !== 'index.js') {
      fs.symlinkSync(path.join(__dirname, file), path.join(DIRECTORY_TO_EXPORT, file));
    }
  })
});

【讨论】:

    【解决方案3】:

    如果我的问题是正确的,那么您唯一需要做的就是在 package.json 中指出您的模块主路径。

    {
       "main": lib/index.js 
    }
    

    其中 index.js 是您模块的主文件。 有关更多信息,请查看 npm 文档here

    【讨论】:

      【解决方案4】:

      假设您有一个包my-module,并且在您的内部有一个子文件夹my-submodule。 您的 my-module/package.json 文件将包含以下行:

      {
          ...,
          "main": "lib/index.js",
          ...
      }
      

      这将允许您的包裹被该行要求

      var myMod = require('my-module');
      

      要允许对子模块使用相同的语法,您所要做的就是将 package.json 文件放在您的子模块文件夹中。它应包含以下内容:

      {
          "main": "lib/index.js"
      }
      

      之后,你可以使用简单的 require 语法:

      var mySubMod = require("my-module/my-submodule");
      

      【讨论】:

        【解决方案5】:

        您有多种选择来实现您的目标。

        全部导出到lib/index.js

        在您的主模块的入口点,您可以导出您想从您的模块中公开的所有内容。

        • + 完全控制公共 API 的一部分以及被视为“私有”的部分
        • + 非常适合 ES2015 模块规范
        • - 不满足您通过带有服务器模块路径的直接 require() 调用来要求组件 (server) 的要求

        示例:

        'use strict'
        
        // this is whatever is the primary export of your module - be it a
        // function, object or anything else which can have other properties
        // assigned to it
        const main = require('./main')
        const server = require('./server')
        
        module.exports = main
        module.exports.server = server
        // ...
        

        用法:

        'use strict'
        
        const mymodule = require('my-module')
        const server = require('my-module').server
        const { server } = require('my-module')
        
        import { server } from 'my-module'
        

        为你的根目录中的组件创建入口文件

        您可以在模块的根文件夹中为您希望作为公共 API 的一部分公开的每个组件创建单独的文件。

        • + 满足您能够通过特定路径获取组件的要求
        • - 结构稍微复杂,每个公共组件都需要额外的文件
        • - 不能很好地与 ES2015 模块配合使用(您必须使用组件的完整路径,并且不能使用解构语法)

        示例文件夹结构:

        my-module
        ├── lib
        │   ├── index.js
        │   └── server.js
        └── server.js
        

        my-module/server.js 文件只会指向实际的实现:

        'use strict'
        
        module.exports = require('./lib/server')
        

        一般说明

        应该注意的是,虽然技术上可行,但依赖于消费者的完整模块路径并不是最佳选择,因为文件夹和文件结构现在成为 API 的一部分,因此移动文件突然变成了一个重大变化。每当我发现自己需要以这种方式要求一个模块的组件时,我就会把它当作我在搞乱该模块的内部结构,并且我应该期望我的代码在该模块的补丁版本升级时能够收支平衡。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-07-04
          • 1970-01-01
          • 2015-09-13
          • 1970-01-01
          • 2016-11-12
          • 1970-01-01
          • 1970-01-01
          • 2023-03-20
          相关资源
          最近更新 更多