首页 > 解决方案 > 无论我尝试什么,npm 都不会忽略我的 TypeScript 源代码文件

问题描述

我有一个用 TypeScript 编写的开源项目,它被编译为 JavaScript,然后通过npm publish.

我一直无法从 npm 包中排除TypeScript 源代码,而且还有其他*.ts文件似乎是随机包含的(但我们将在这里只关注一个文件)。

我没有包含 TypeScript 源文件的问题,但这只是在包中添加了用户永远不需要的额外字节。

我可以用非常小的设置重现问题

包.json

{
    "name": "example",
    "version": "1.0.0",
    "main": "readme.js"
}

我尝试了一个非常激进的忽略列表:

.npmignore

**/*
*.ts
**
*
*.*
readme.ts

创建一些源代码文件

touch readme.ts
touch readme.js

现在,如果我尝试生成一个 npm 包,它将包含该readme.ts文件。

$ npm pack
npm notice
npm notice package: example@1.0.0
npm notice === Tarball Contents ===
npm notice 0   readme.js
npm notice 76B package.json
npm notice 0   readme.ts
npm notice === Tarball Details ===
npm notice name:          example
npm notice version:       1.0.0
npm notice filename:      example-1.0.0.tgz
npm notice package size:  195 B
npm notice unpacked size: 76 B
npm notice shasum:        a1ee7cc6b7b0d1e2eccf870e95d7df38c5dcb609
npm notice integrity:     sha512-ppNEfKEvT9DEP[...]+d16IWbrj7OdA==
npm notice total files:   3
npm notice
example-1.0.0.tgz

那么为什么包括readme.ts呢?

我排除了所有文件,并且文件中只readme.js引用了package.json

$ npm --version
6.13.1

标签: typescriptnpmglobnpm-publish

解决方案


简短回答:命名的文件readme.*(例如readme.fooreadme.quux等)将包含在 npm 中,无论您如何尝试在.npmignore文件中否定它。


NPM的测试文件:

在 npm 对npm-cli的一项名为“无条件包含某些文件”的测试中,#511它们包括对名为readme.randomext.

通过观察这个测试,我们可以得出结论,任何命名readme.*的文件都将包含在 tarball ( .tgz) 文件中,即使它可能在.npmignore文件中指定。

以下是上述 NPM 测试文件的摘录,名为pack-files-and-ignores.js

test('certain files included unconditionally', function (t) {
  var fixture = new Tacks(
    Dir({
      'package.json': File({
        name: 'npm-test-files',
        version: '1.2.5'
      }),
      '.npmignore': File(
        'package.json',
        'README',
        'Readme',
        'readme.md',
        'readme.randomext',   // <----
        'changelog',
        'CHAngelog',
        'ChangeLOG.txt',
        'history',
        'HistorY',
        'HistorY.md',
        'license',
        'licence',
        'LICENSE',
        'LICENCE'
      ),
      'README': File(''),
      'Readme': File(''),
      'readme.md': File(''),
      'readme.randomext': File(''),     // <----
      'changelog': File(''),
      'CHAngelog': File(''),
      'ChangeLOG.txt': File(''),
      'history': File(''),
      'HistorY': File(''),
      'HistorY.md': File(''),
      'license': File(''),
      'licence': File(''),
      'LICENSE': File(''),
      'LICENCE': File('')
    })
  )
  withFixture(t, fixture, function (done) {
    t.ok(fileExists('package.json'), 'package.json included')
    t.ok(fileExists('README'), 'README included')
    t.ok(fileExists('Readme'), 'Readme included')
    t.ok(fileExists('readme.md'), 'readme.md included')
    t.ok(fileExists('readme.randomext'), 'readme.randomext included')    // <----
    t.ok(fileExists('changelog'), 'changelog included')
    t.ok(fileExists('CHAngelog'), 'CHAngelog included')
    t.ok(fileExists('ChangeLOG.txt'), 'ChangeLOG.txt included')
    t.ok(fileExists('license'), 'license included')
    t.ok(fileExists('licence'), 'licence included')
    t.ok(fileExists('LICENSE'), 'LICENSE included')
    t.ok(fileExists('LICENCE'), 'LICENCE included')
    done()
  })
})

解决方法:

如果您可以考虑一些解决方法,例如:

  1. 最简单的方法是将文件重命名为 eg read-me.ts,然后read-me.ts在您的.npmignore文件中指定。但是,正如您*.ts当前在您的文件中指定的那样,您.npmignore实际上也没有必要另外指定read-me.ts

  2. 或者,如果这不可能,请考虑:

    • 将脚本添加到package.jsonpostpack的脚本部分。例如:

      "scripts": {
        "postpack": "node ./fix-it.js",
        ...
      },
      
    • 然后fix-it.js利用node-tar包:

      1. 解压缩 tarball ( .tgz)。
      2. 删除不需要的文件,即readme.ts.
      3. 重新打包以创建一个新的 tarball ( .tgz)。
    • 发布你的包的步骤就变成了:

      1. npm pack

        postpack脚本随后将自动生成.tgz没有不需要的文件的新文件。

      2. npm publish ./path/to/mypackage.tgz


推荐阅读