特定のフォルダーをパッケージルートとしてnpm公開する方法


91

ソースをビルドしてパッケージ化し、dist。というディレクトリにリリースするためのgulpタスクを含むプロジェクトがあります。私の目標はそれをnpmパッケージとして公開することですが、私のdistフォルダーのみです。NPMのドキュメントでは、私が使用できると言うfilesエクスポートするファイルを指定するタグを。できます。しかし、ドキュメントには次のようにも書かれています。

配列内のフォルダーに名前を付けると、そのフォルダー内のファイルも含まれます

その結果、node_modulesは次のようなnpmパッケージになります。

生成されたnpmパッケージ

しかし、パッケージのルート(そのdistフォルダーなし)にあるすべてのファイルを表示したいと思います。私のindex.jsファイルはdistフォルダ内にありますが、ルートにあるはずです。私はセットタグにしようとしたfilesとして、/dist/**/*それはうまくいきませんでした。

どうすればそれを達成できますか?

回答:


45

私も同じ願望を持っていますが、npmツールだけを使用してこれを達成する方法はないと思います。別のスクリプト/ツールを使用してパッケージを配置できます。

代替ソリューション

現在、自分package.jsondistフォルダにコピーして、フォルダ内で実行しnpm packていdistます。これは本質的に私たちのパッケージの望ましい配置を提供すると思います。

このnpmデザインに関連する読み物は次のとおりです。ノードにDirectories.libがない理由

jspmは、npmパッケージを解決するときに、のdirectories.libオプションを尊重しpackage.json、ファイルを再配置することに注意することも興味深いです。jspmまたはnpm / webpackで使用できる共通のライブラリを構築したいので、これはすべて私のために起こりました。


1
(なぜなしDirectories.lib ...)死んリンクです
Shanimal

1
NodeのDirectories.libが言っていないのはなぜですか。私たちのやり方でやらないと、苦痛を感じるはずです。これはすべて、この問題を回避するためのツールの必要性を生み出します。
ブライアン滝田

6
この答えは時代遅れだと思います。以下の応答が示すようnpm packに、package.jsonfilesmainfields.npmignoreを使用して、特定のインストール可能なディレクトリからパッケージを作成するために必要なすべてのものを開発者に提供します。
ジェフトピア

1
いくつかの作られたスクリプトを合理化するために/「サブディレクトリを公開する」パターン施行
micimize

2
誰かが、package.jsonのnpmignore、files、およびmainプロパティを使用してどのように解決できるかを投稿できますか?私はルートにすべてのファイルを移動するにはしたくないdistのフォルダ持っている
Angad

17

元のポスター(@robsonrosa)と同様の問題があります。私の場合、distディレクトリにコンパイルするtypecriptを使用します。typescriptをルートディレクトリにコンパイルすることはできますが、最善の解決策はpackage.json、distディレクトリに別のファイルを生成することだと思います。
これは、コピーの@scvnc提案に似てpackage.jsonいますが、ひねりがあります。

パッケージ化プロセスの一環として、ルートディレクトリのpackage.jsonメインpackage.jsonファイルに基づいているが、それとは異なるパッケージのを生成する必要があります。

理論的根拠:

  • ルートpackage.jsonファイルは開発ファイルです。パッケージユーザーには役に立たないスクリプトや開発の依存関係が含まれている可能性がありますが、セキュリティ上の懸念が生じる可能性があります。パッケージング手順には、本番環境からその情報を取り除くコードが含まれている場合がありますpackage.json
  • 異なるパッケージファイルを必要とする可能性のある異なる環境にパッケージをデプロイしたい場合があります(たとえば、異なるバージョンまたは依存関係が必要な場合があります)。

---編集---

コメントで解決策を求められました。これが私が使っているコードです。これは例として考えるべきであり、一般的なものではなく、私のプロジェクトに固有のものです。

私のセットアップ:

package.json         - main package.json with dev dependencies and useful scripts.
.npmignore           - files to ignore; copied to 'dist' directory as part of the setup.
/src                 - directory where my typescript code resides.
/src/SetupPackage.ts - bit of code used to setup the package.
/dist                - destination directory for the compiled javascript files.

distディレクトリのみをパッケージ化したいので、ディレクトリはパッケージ内のルートディレクトリである必要があります。

SetupPackage.ts私のsrcディレクトリ内のファイルは、typescriptによってディレクトリSetupPackage.js内にコンパイルされますdist

import fs from "fs";

// DO NOT DELETE THIS FILE
// This file is used by build system to build a clean npm package with the compiled js files in the root of the package.
// It will not be included in the npm package.

function main() {
    const source = fs.readFileSync(__dirname + "/../package.json").toString('utf-8');
    const sourceObj = JSON.parse(source);
    sourceObj.scripts = {};
    sourceObj.devDependencies = {};
    if (sourceObj.main.startsWith("dist/")) {
        sourceObj.main = sourceObj.main.slice(5);
    }
    fs.writeFileSync(__dirname + "/package.json", Buffer.from(JSON.stringify(sourceObj, null, 2), "utf-8") );
    fs.writeFileSync(__dirname + "/version.txt", Buffer.from(sourceObj.version, "utf-8") );

    fs.copyFileSync(__dirname + "/../.npmignore", __dirname + "/.npmignore");
}

main();

このファイル:

  • ルートをコピーしpackage.jsonますが、パッケージで不要なスクリプトと開発者の依存関係を削除します。また、パッケージへのメインエントリポイントを修正します。
  • パッケージのバージョンをpackage.jsonからというファイルに書き込みますversion.txt
  • .npmignoreルートからパッケージをコピーします。

.npmignoreの内容は次のとおりです。

*.map
*.spec.*
SetupPackage.*
version.txt

つまり、ユニットテスト(スペックファイル)とtypescriptマップファイルは、SetupPackage.jsファイルとversion.txtそれが作成するファイルと同様に無視されます。これにより、きれいなパッケージが残ります。

最後に、メインpackage.jsonファイルには、ビルドシステムで使用するための次のスクリプトがあります(shシェルとして使用されることを前提としています)。

"scripts": {
    "compile": "tsc",
    "clean": "rm -rf dist",
    "prebuildpackage": "npm run clean && npm run compile && node dist/SetupPackage.js",
    "buildpackage": "cd dist && npm pack"
  },

パッケージをビルドするために、ビルドシステムはリポジトリのクローンを作成し、npm install実行してから実行npm run buildpackageします。

  • distディレクトリを削除して、クリーンなコンパイルを保証します。
  • typescriptコードをjavascriptにコンパイルします。
  • パッケージングのSetupPackage.js準備distをするファイルを実行します。
  • distディレクトリにcdし、そこでパッケージをビルドします。

version.txtpackage.jsonのバージョンを取得し、リポジトリにタグを付ける簡単な方法としてファイルを使用します。これを行う方法は他にも無数にあります。または、バージョンを自動インクリメントすることもできます。これを削除SetupPackage.tsし、.npmignoreそれはあなたにとって有用ではない場合。


この答えは最良の答えのように見えますが、理論以外の解決策はありますか?
yumaa

3
@yumaa具体的な例で答えを編集しました。お役に立てば幸いです。
EliAlgranti19年

1
いくつかの変更を加えて私のために働いた。現在のSetupPackage.tsファイルは、ファイルsrcdist。ではなくディレクトリにコピーします。おかげ👍
Harinderシン

15

プロジェクトにgitがある場合は、小さなハックを使用できます。次のスクリプトをpackage.jsonに追加します

    "prepublishOnly": "npm run build && cp -r ./lib/* . && rm -rf ./lib",
    "postpublish": "git clean -fd",

publishコマンドnpmを実行すると、が含まれprepublishOnlyます。ファイルをビルドしてlibフォルダーに保存します(ビルドスクリプトはプロジェクトによって異なります)。次のコマンドは、ファイルをルートフォルダーにコピーし、を削除しlibます。公開後、postpublishスクリプトはプロジェクトを前の状態に戻します。


1
私はこのソリューションのファンです!
DanMad

7

.npmignore特に展開にCIを使用している場合は、物を移動したりコピーしたりする代わりに使用し、公開したくないファイルをそこに追加することを強くお勧めします。

https://docs.npmjs.com/misc/developers#keeping-files-out-of-your-package

例:

#tests
test
coverage

#build tools
.travis.yml
.jenkins.yml
.codeclimate.yml

#linters
.jscsrc
.jshintrc
.eslintrc*

#editor settings
.idea
.editorconfig

更新:

コードを同じリポジトリを使用して異なるnpmパッケージに分割したい場合は、最近このプロジェクトに出くわしました:Lernaと本当に良さそうです。

多分あなたは見てみるべきです


9
それでも、ビルドしたファイルをパッケージのルートディレクトリに出力する必要があります。おそらくCIでは許容されます。私がリンクしたIsaacのブログからの投稿を観察し、require('mypackage/foo')代わりにソリューションがどのように可能になるかを教えてくださいrequire('mypackage/dist/foo')
scvnc 2017

私はここでその問題を解決しようとしていませんでした。コードを分割したい場合は、最近このプロジェクトに出くわしました:lernajs.ioそして本当に良さそうです
Thram 2017

見てみる価値のある別のツールを見つけました:)github.com/philcockfield/msync
Thram

ええ、マテリアルUIはそれを使用し、私はこれを使用しました。私の最後の会社、私はそれが大丈夫だとわかりました
ニック

6

これは私にとってはうまくいきます。

cd TMPDIR; npm pack/path/to/package.json

TarballはTMPDIRディレクトリ内に作成されます。


^この回答は過小評価されています。npm packさらに、package.jsonfilesフィールド(または.npmignore)は素晴らしく機能します。
ジェフトピア

1

セマンティックリリースを使用している(そして私がお勧めする)pkgRoot場合は、.releaserc.jsonファイルにオプションを追加します。

{
  "pkgRoot": "dist",
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    "@semantic-release/npm",
    [
      "@semantic-release/exec",
      {
        "prepareCmd": "npx rjp package.json version nextRelease.version"
      }
    ],
    [
      "@semantic-release/git",
      {
        "assets": ["package.json"]
      }
    ],

  ],
}

それで問題は解決します。distフォルダにpackage.jsonファイルが含まれていることを確認してください。スクリプトにを追加することで、これcpを簡単に行うことができますpostbuildrjpもインストールする


0

distフォルダを公​​開する必要があります

npmのアプローチによれば、これを実現する自然な方法は、ルートとなるフォルダーを公開することです。これを行うにはいくつかの方法がありますが、使用する最終的な環境によって異なります。

  1. npmはパッケージリポジトリからnpmレジストリに<folder>公開し、他のパッケージをインストールするときに他のプロジェクトにパッケージをインストールします。あなたの場合はそうなるでしょうnpm publish dist
  2. パッケージをローカルでのみ使用する場合は、npm install <folder>を他のプロジェクトにインストールします。あなたの場合、あなたは他のプロジェクトに行き、実行しますnpm install relative/path/to/dist
  3. npmnode_modulesは、元のパッケージの変更を他のプロジェクトに即座に反映させたい場合に備えて、フォルダーをローカルで別のプロジェクトのフォルダーにリンクします。あなたの場合、最初cd distに実行npm linkしてから、他のプロジェクトに移動して実行しnpm link robsonrosa-ui-alertます。

前提条件:上記のいずれの場合でも、公開/インストール/リンクの前に、dist少なくとも適切なpackage.jsonファイルをフォルダーに配置する必要があります。あなたの場合、package.jsonファイルでパッケージ名をとして定義する必要があります"name": "robsonrosa-ui-alert"。通常、README.mdやLICENSEなどの他のファイルも必要になります。

方法2と3への注意

通常、この方法でインストールされたパッケージを使用すると、パッケージの依存関係に問題が発生します。これを回避するには、最初にパッケージをパックしてnpm pack distから、パックされたtarballからターゲットプロジェクトにパッケージをインストールしますnpm install path/to/package-tarball.tgz

自動化の例

prepareスクリプトをスクリプトと組み合わせて使用すると、公開プロセスを自動化できbuildます。さらに、"private": trueパッケージリポジトリのルートディレクトリにあるpackage.jsonにフィールドを配置して、パッケージルートフォルダーが誤って公開されないようにパッケージを保護できます。次に例を示します。

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

この方法では、ルートフォルダーを公開せずdist、公開プロセス内でパッケージがビルドされ、package.jsonがフォルダーに自動的にコピーされます。


-1

これが私が最もクリーンだと思うもう1つのアプローチです。ビルドおよびパックスクリプトでファイルを移動したりパスを指定したりすることなく、すべて構成ベースです。

package.json メインファイルを指定します。

{
    "main": "lib/index.js",
}

いくつかの追加のtypescriptオプション:

  • を指定しrootDirます。このディレクトリにはすべてのソースコードが含まれ、その中にindexファイル(またはでメインとして使用できる他のファイル)が含まれている必要がありますpackage.json
  • を指定しoutDirます。これはあなたのtscコマンドが構築される場所です

tsconfig.json

{
    "compilerOptions": {
        "rootDir": "src",
        "outDir": "lib",
    },
    ...

}

これは、名前をdistからlibに変更することを除いて、OPが最初に持っていたものと同じではありませんか?
Bob96 3019

-1

オプション1:フォルダーに移動し、「npmpublish」を実行します。コマンド

オプション2:npm publish / path / directoryを実行します


-4

.npmignoreファイルを作成し、それに以下を追加するだけです:

*.*
!dist/*

1
これはOPが要求したとおりに機能しますか?これを機能させることができませんでした。公開されたパッケージに、ディレクトリ自体を含めずに、distディレクトリの内容のみを含めるようにするというアイデアでした。これは、package.jsonの「ファイル」リストですでに実行できるdistディレクトリにないものを含めないようにするためです。
Bob96 3019
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.