[英]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.