[英]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"
属性,这是正确的方法吗?
提示 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 模块兼容。
根据 npm 方法,实现这一目标的自然方法是发布将成为根目录的文件夹。 有几种方法可以做到这一点,具体取决于您要使用的最终环境:
npm publish src/js/lib/my
。npm install relative/path/to/src/js/lib/my
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.