package.json中的根目录


68

我的问题与我想作为NPM模块发布的现有库有关。该库已在使用中,目前已require通过本地文件系统下载。

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

如果我有一个像这样的结构:

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

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

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

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

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

Answers:


24

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

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

原始答案

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

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

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


不幸的是,该问题已关闭。
trusktr

虽然文档与node有关12.14.0,但不幸的是,它尚不起作用??我使用节点13.5.0
杰里·格林

exports很棒,尽管它最近才登陆。显然在12.16.0没有--experimental-exports标志的节点中;参考:github.com/nodejs/node/pull/31691github.com/nodejs/node/pull/29867。TypeScript支持仍在进行中。参考:github.com/microsoft/TypeScript/issues/33079
brillout

8

正如文档所说:

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

因此"main": "src/js/lib/my/app.js",您的package.json文件中将包含类似内容。

我建议您创建一个app.js文件和module.exports您的其他孩子。例如:

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

并像这样使用它们:

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

7
我的程序包是一个已经存在的库,我无法更改其结构。我只需要NPMify我的图书馆。
Drahcir 2015年

3
为什么添加条目package.json而不更改lib,而是添加index.js?这应该是公认的答案。
Stijn de Witt

4

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所在的同一目录中启动模块层次结构


2
这是我要发布
Drahcir 2015年

4

现在,这是一个丑陋的解决方法,它确实污染了程序包的根。但是,直到约旦的答案奏效,这才是实现您所要问的方式。

只需在要使用导出的每个模块的软件包根目录中添加一个文件,就可以使用带有斜杠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');

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


3

另一种可能性是使用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模块兼容的程度。


0

只需发布/ install / link打算用作根目录的文件夹

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

  1. npm发布<文件夹>软件包回购中的到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

自动化实例

您可以使用preparescript自动化发布过程,结合build脚本和"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),程序包build(webpack --mode=production)以及将package.json的副本复制到dist文件夹中而没有字段“ private”:true(cat ./package.json | grep -v private > dist/package.json)。


-1

在webpack中,您可以这样指定resolve.alias

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

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

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

1
请在互联网上的文档中找到可用的网站。我从未见过方向或任何参考。
mibbit

@mibbit谷歌搜索有帮助。第一个结果是webpack docs:Resolve。绝对惊人的答案。在第三次尝试解决此问题后,终于遇到了这个问题!:)
Domi

package.json文档中不存在任何说明
Daniel San

我不知道directions来自哪里,但是现在我们有了exportsnodejs.org/api/esm.html#esm_package_exports
编码器
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.