我的问题涉及我希望作为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');
我在package.json中看到了"files"
属性,这是正确的方法吗?
答案 0 :(得分:9)
对于本机解决方案,请参阅此节点问题https://github.com/nodejs/node/issues/14970
功能请求会在main。旁边的package.json中显示一个mainDir
字段。
投票的人越多,实施的速度越快/越有可能
答案 1 :(得分:6)
正如doc所说:
主要字段是模块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;
答案 2 :(得分:2)
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所在的同一目录中启动模块层次结构
答案 3 :(得分:2)
另一种可能性是使用ECMAScript模块(ES模块),尤其是 package.json 文件中的package exports字段。
使用此配置给出 package.json 文件:
{
"name": "my",
"exports": {
"./": "./src/js/lib/my/"
}
}
您应该能够从库中导入模块,例如:
import thing from 'my/thing'
import that from 'my/that'
此功能默认从节点13.0.0
开始启用,但位于--experimental-exports
的{{1}}标志后面。
请注意,ES模块规范处于Stability:1 - Experimental阶段,可能会随时更改。我不知道这与CommonJS模块兼容的程度。
答案 4 :(得分:1)
现在这是一个丑陋的解决方法,它确实会污染你的软件包的根目录。但是在Jordan's answer起作用之前,这就像实现你所要求的那样。
只需使用 require with slash 表示法为要导出的每个模块在软件包的根目录中添加一个文件。这样的文件将与正在导出的模块具有相同的名称,它只是重新导出它。
.
├── 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');
同样如bug about adding mainDir
property into package.json
中所述,您可以暂时将源和package.json文件复制到一个目录中并从那里发布。
答案 5 :(得分:0)
根据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。
自动化示例
您可以使用prepare
script,结合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
),程序包构建(webpack --mode=production
)并将package.json复制到dist文件夹没有字段“私人”:true(cat ./package.json | grep -v private > dist/package.json
)。
答案 6 :(得分:-1)
在webpack中,您可以像这样指定resolve.alias
:
{
resolve: {
alias: {
'my': 'my/src'
}
}
}
或者您可以在package.json
中指定directions
选项
{
directions: {
'lib': 'src/lib'
}
}