繁体   English   中英

package.json 中的根目录

[英]Root directory in package.json

我的问题涉及我希望作为 NPM 模块发布的现有库。 该库已在使用中,当前require通过本地文件系统 d。

如何指定模块文件的根目录?

如果我有这样的结构:

.
├── package.json
├── src
|   ├── js
|   └────── lib
|   └───────── my
|   └───────────── thing.js
|   └───────────── that.js

如何指定我的模块的根目录和可访问文件是src/js/lib/my/

我想从外部项目中使用以下内容:

var thing = require('my/thing'),
    that = require('my/that');

我在 package.json 中看到了"files"属性,这是正确的方法吗?

2020 年更新

提示 mainDir 的问题现已关闭。 取而代之的是一个名为exports的新字段,它几乎可以像es import maps 一样用于将文件夹映射到导出别名:

// ./node_modules/es-module-package/package.json
{
  "exports": {
    "./my/": "./src/js/lib/my/"
  }
}
import thing from 'es-module-package/my/thing.js';
// Loads ./node_modules/es-module-package/src/js/lib/my/thing.js

正如下面原始答案中链接的问题中所建议的,可以将根映射到文件夹以import thing from pkg/thing.js访问import thing from pkg/thing.js如下所示:

{
  "type": "module",
  "main": "./dist/index.js",
  "exports": {
    "./": "./src/js/lib/my/"
  }
}

原答案

对于本机解决方案,请参阅此节点问题https://github.com/nodejs/node/issues/14970

功能请求建议 package.json 中 main 旁边的mainDir字段。

投票的人越多,实施的速度就越快/更有可能

正如文档所说:

main 字段是一个模块 ID,它是程序的主要入口点。

所以你的 package.json 文件中会有类似"main": "src/js/lib/my/app.js"

我建议你创建一个app.js文件和module.exports你不同的孩子。 例如:

 module.exports.thing = require('./thing');
 module.exports.that = require('./that');

并像这样使用它们:

var mylib = require('mylib')
  , thing = mylib.thing
  , that = mylib.that;

package.json主要是npm用来安装和管理依赖的文件。

require构造并不关心package.json因此您将无法使用它来颠覆require工作方式,并使其相信包不在require加载方案所期望的位置。

请参阅https://nodejs.org/api/modules.html上的文档和此处的加载方案: https : //nodejs.org/api/modules.html#modules_all_together

您可以使用文档中称为“从全局文件夹加载”的技术并定义NODE_PATH环境变量。

但我建议您坚持使用更标准的方式: - 将模块放在 node_modules 目录中 - 或者在 app.js 或 index.js 所在的同一目录中启动模块层次结构

现在这是一个丑陋的解决方法,它确实污染了你的包的根。 但在乔丹的答案奏效之前,这感觉就像是实现你所要求的方式。

只需使用带斜杠符号的require 为要导出的每个模块在包的根目录中添加一个文件。 此类文件将与要导出的模块具有相同的名称,并且只会重新导出它。

.
├── package.json
├── thing.js       <--
├── that.js        <--
├── src
|   ├── js
|   └────── lib
|   └───────── my
|   └───────────── thing.js
|   └───────────── that.js

例如文件./thing.js将包含:

module.exports = require('./src/js/lib/my/thing');

因此,您可以将其要求为:

const thing = require('mypackage/thing');

同样如关于将mainDir属性添加到package.json错误所述,您可以将源和 package.json 文件临时复制到一个目录中并从那里发布。

另一种可能性是使用 ECMAScript 模块(ES 模块),特别是package.json文件中的包导出字段。

给定具有此配置的package.json文件:

{
  "name": "my",
  "exports": {
    "./": "./src/js/lib/my/"
  }
}

您应该能够从库中导入模块,例如:

import thing from 'my/thing'
import that from 'my/that'

自节点13.0.0起默认启用此功能,但位于--experimental-exports标志12.13.0

请注意,ES 模块规范处于稳定性:1 - 实验阶段,可能会发生变化。 我不知道这在多大程度上与 CommonJS 模块兼容。

只需发布 /install /link 打算成为根的文件夹

根据 npm 方法,实现这一目标的自然方法是发布将成为根目录的文件夹。 有几种方法可以做到这一点,具体取决于您要使用的最终环境:

  1. npm 将 <folder>从包存储库发布到 npm 注册表,然后在安装其他包时将包安装到其他项目中。 在您的情况下,它将是npm publish src/js/lib/my
  2. 如果您只想在本地使用您的包,请在其他项目中使用npm install <folder> 在您的情况下,您转到另一个项目并运行npm install relative/path/to/src/js/lib/my
  3. npm 将您的文件夹本地链接到其他项目中的node_modules ,以防您希望原始包中的更改立即反映在其他项目中。 在您的情况下,您首先cd src/js/lib/my并运行npm link然后转到另一个项目并运行npm link my

先决条件:在上述任何情况下,在发布/安装/链接之前,您必须在my文件夹中至少放置一个适当的package.json文件。 在您的情况下,您必须将 package.json 文件中的包名称定义为"name": "my" 通常,您还需要其他一些文件,例如 README.md 或 LICENSE。

对方法 2 和 3 的备注

当您使用以这种方式安装的软件包时,通常会出现软件包依赖性问题。 为了避免它,首先使用npm pack dist包包,然后从打包的 tarball 中将包安装到目标项目中,即npm install path/to/package-tarball.tgz

自动化示例

您可以使用prepare script自动化发布过程,结合build script 和"private": true字段放在位于包存储库根目录的 package.json 中。 下面是一个将dist文件夹作为包根目录的示例:

  "private": true,
  "scripts": {
    "build": "rm -rf dist && webpack --mode=production && cat ./package.json | grep -v '\"private\":' > dist/package.json",
    "prepare": "npm run build"
  },

这样你就不会发布根文件夹( "private": true )。 当您点击npm publish dist ,自动调用的prepare脚本将触发 dist 文件夹清理( rm -rf dist )、包构建( webpack --mode=production )并将 package.json 复制到没有“private”字段的 dist 文件夹: true ( cat ./package.json | grep -v private > dist/package.json )。

在的WebPack,您可以指定resolve.alias是这样的:

{
  resolve: {
    alias: {
      'my': 'my/src'
    }
  }
}

或者您可以在 package.json 中指定directions选项

{
  directions: {
    'lib': 'src/lib'
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM