npm이 특정 폴더를 게시하지만 패키지 루트로 게시하는 방법


91

소스를 빌드하고 패키징하기위한 꿀꺽 꿀꺽 작업이 포함 된 프로젝트가 있으며 dist. 내 목표는 npm 패키지로 게시하지만 내 dist 폴더 만 게시하는 것입니다. NPM 문서는 내가 사용할 수 있다고 말한다 files수출에 파일을 지정하는 태그를. 효과가있다. 그러나 문서는 다음과 같이 말합니다.

어레이의 폴더 이름을 지정하면 해당 폴더 내의 파일도 포함됩니다.

결과는 npm 패키지로, node_modules는 다음과 같습니다.

생성 된 npm 패키지

그러나 패키지의 루트 (해당 dist폴더 제외) 에있는 모든 파일을보고 싶습니다 . 내 index.js파일은 dist폴더 안에 있지만 루트에 있어야합니다. 나는 세트 태그 해봤 files/dist/**/*했지만 작동하지 않았다.

어떻게 할 수 있습니까?

답변:


45

저도 같은 욕망을 가지고 있지만 npm 툴링만으로는 이것을 달성 할 방법이 없다고 생각 합니다. 다른 스크립트 / 도구를 사용하여 패키지를 정렬 할 수 있습니다.

대체 솔루션

현재 내를 복사하고 package.jsondist폴더 다음 실행 npm pack내부 dist폴더에 있습니다. 나는 이것이 본질적으로 우리 패키지의 원하는 배열을 제공한다고 생각합니다.

다음은이 npm 디자인에 대한 몇 가지 관련 자료입니다. Why no Directories.lib in Node .

jspm 이 npm 패키지를 해결할 때 파일을 재정렬하고 directories.lib옵션을 존중한다는 점도 흥미 롭습니다 package.json. jspm 또는 npm / webpack에서 사용할 수있는 공용 라이브러리를 구축하고 싶기 때문에이 모든 것이 저에게 왔습니다.


1
(더 Directories.lib는 ... 왜) 죽은 링크입니다
Shanimal

1
Node의 Directories.lib가 왜 우리 방식대로하지 않으면 고통을 느껴야한다고 말하지 않습니다. 이 모든 작업은이 문제를 해결하기위한 도구가 필요합니다.
Brian Takita

6
이 답변은 구식이라고 생각합니다. 아래 응답에 npm pack따르면, package.json filesmain필드를 .npmignore사용하고 개발자에게 설치 가능한 특정 디렉토리에서 패키지를 만드는 데 필요한 모든 것을 제공합니다.
Jefftopia

1
"publish subdir"패턴을 능률화 / 강제하기위한 스크립트 를 만들었습니다.
micimize

2
누군가 package.json의 npmignore, 파일 및 주요 속성을 사용하여 달성 할 수있는 방법을 솔루션을 게시 할 수 있습니까? 모든 파일을 루트로 옮기고 dist 폴더를 갖고 싶지 않습니다
Angad

17

원본 포스터 (@robsonrosa)와 비슷한 문제가 있습니다. 제 경우에는 dist디렉토리로 컴파일되는 typecript를 사용합니다 . typescript를 루트 디렉터리로 컴파일 할 수 있지만 가장 좋은 해결책은 package.jsondist 디렉터리에 별도의 파일 을 생성하는 것 입니다.
이것은 복사에 대한 @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디렉토리에 컴파일됩니다 SetupPackage.jsdist타이프 라이터로 디렉토리 :

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.
  • 받는 CD의 dist디렉토리와 패키지를 빌드있다.

version.txtpackage.json에서 버전을 가져오고 내 저장소에 태그를 지정하는 쉬운 방법으로 파일을 사용합니다 . 이를 수행하는 수많은 다른 방법이 있거나 버전을 자동으로 증가시킬 수 있습니다. 에서이를 제거 SetupPackage.ts하고 .npmignore당신에게 도움이되지 않습니다.


이 대답은 가장 좋은 대답처럼 보이지만 이론을 제외하고 준비된 해결책이 있습니까?
yumaa

3
@yumaa 구체적인 예를 들어 내 대답을 편집했습니다. 유용하기를 바랍니다.
Eli Algranti

1
약간의 변화로 나를 위해 일했습니다. 현재 SetupPackage.ts에 파일 복사 파일 src이 아닌 디렉토리 dist. 감사합니다 👍
Harinder Singh

15

프로젝트에 git이 있으면 작은 해킹을 사용할 수 있습니다. package.json에 다음 스크립트 추가

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

이제 publishnpm involve 명령 을 실행할 때 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

나는 여기서 그 문제를 해결하려고하지 않았습니다. 코드를 나누고 싶다면 최근에이 프로젝트에 부딪 혔습니다. lernajs.io 정말 좋아 보입니다
Thram

살펴볼 가치가있는 또 다른 도구를 찾았습니다. :) github.com/philcockfield/msync
Thram

예 재료 UI를 사용하고 이것을 사용했습니다. 내 마지막 회사, 괜찮
nick

6

이것은 나를 위해 잘 작동합니다.

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

Tarball은 TMPDIR 디렉터리 내에 생성됩니다.


^이 답변은 과소 평가되었습니다. npm packplus package.json files필드 (또는 .npmignore)는 훌륭하게 작동합니다.
Jefftopia

1

semantic-release를 사용하는 경우 (권장하는 경우) 파일에 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당신에 postbuild스크립트. rjp 도 설치 하십시오.


0

dist폴더 를 게시해야 합니다.

이를 달성하는 자연스러운 방법은 npm 접근 방식에 따라 루트가 될 폴더를 게시하는 것입니다. 작업하려는 최종 환경에 따라 여러 가지 방법이 있습니다.

  1. npm 은 패키지 저장소에서 npm 레지스트리로 <folder>게시 한 다음 다른 패키지를 설치할 때 다른 프로젝트에 패키지를 설치합니다. 귀하의 경우에는 npm publish dist.
  2. 패키지를 로컬로만 사용하려는 경우 npm 은 다른 프로젝트에 <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

여기에 내가 생각하는 가장 깨끗한 접근법이 하나 더 있습니다. 파일을 이동하거나 빌드 및 팩 스크립트에서 경로를 지정할 필요없이 모두 구성 기반입니다.

package.json 기본 파일을 지정하십시오.

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

몇 가지 추가 타이프 스크립트 옵션 :

  • 을 지정합니다 rootDir. 이 디렉토리에는 모든 소스 코드가 있고 그 index안에 파일 이 있어야 합니다 (또는에서 기본으로 사용할 수있는 다른 파일 package.json).
  • 을 지정합니다 outDir. 이것은 tsc 명령이 빌드되는 곳입니다.

tsconfig.json

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

}

이것은 dist에서 lib로 이름을 변경하는 것을 제외하고는 OP가 원래 가지고 있던 것과 동일하지 않습니까?
Bob9630

-1

옵션 1 : 폴더로 이동하여 "npm publish"를 실행합니다. 명령

옵션 2 : npm publish / path / directory 실행


-4

.npmignore파일을 만들고 다음을 추가하기 만하면 됩니다.

*.*
!dist/*

1
OP가 요청한대로 수행합니까? 나는 이것을 작동시킬 수 없었다. 아이디어는 게시 된 패키지에 디렉토리 자체를 포함하지 않고 dist 디렉토리의 내용 만 포함하도록 만드는 것이 었습니다. 이것은 package.json "files"목록으로 이미 수행 할 수있는 dist 디렉토리에없는 것은 포함하지 않도록하기위한 것입니다.
Bob9630
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.