简体   繁体   中英

Clean package.json before packing

Let's say you have a npm project with the following package.json :

{
  "name": "XXX",
  "version": "YYY",
  "license": "ZZZ",
  "scripts": {
    "scriptA": "...",
    "scriptB": "...",
    "preinstall": "...",
    "postinstall": "..."
  },
  "devDependencies": {
    "depA": "vA",
    "depB": "vB"
  },
  "dependencies": {
    "depC": "vC",
    "depD": "vD"
  }
}

When packing/publishing your package, you don't need the scripts or devDependencies keys. But more dangerously, the preinstall and postinstall scripts could trigger weird/unwanted actions when people install your package as a dependency.

So how do you clean your package.json , ie remove the keys that you don't need?

I'm currently using npm 3.10. If I use the npm pack command, according to the npm documentation it will simply pack the current package if no arguments are provided (therefore taking the raw package.json from disk) and there is no options I can provide to clean it up.

I can of course write my own scripts that would zip the package and generate my own package.json . Is it the way to go?

Using npm itself, this does not seem possible. As of npm 3.10, npm publish or npm pack will indeed just include a pure copy of your package.json in your tgz.

The solution is therefore to generate its own packaged file to have full control over the included package.json .

Basic example

Note: this is using the shell and synchronous method from npm fs

const fs = require('fs');
const os = require('os');

const shell = require('shelljs');
const targz = require('tar.gz');

// create temp directory
const tempDirectory = fs.mkdtempSync(`${os.tmpdir()}/your-project-tarball-`);
const packageDirectory = `${tempDirectory}/package`;

// create subfolder package
fs.mkdirSync(packageDirectory);

// read existing package.json
const packageJSON = require('./package.json');

// copy all necessary files
// https://docs.npmjs.com/files/package.json#files
shell.cp('-R', packageJSON.files, packageDirectory);
shell.cp('-R', ['README.md', 'CHANGELOG.md', 'LICENSE'], packageDirectory);

// create your own package.json or modify it here
Reflect.deleteProperty(packageJSON, 'scripts');
fs.writeFileSync(`${packageDirectory}/package.json`, JSON.stringify(packageJSON, null, 2));

// create tgz and put it in dist folder
targz().compress(packageDirectory, 'your-package.tgz');

Real life example with Lodash

This is for example what the lodash lib does in version 4.17.2. Their original package.json looks like (cf https://github.com/lodash/lodash/blob/4.17.2/package.json ):

{
  "name": "lodash",
  "version": "4.17.2",
  "license": "MIT",
  "private": true,
  "main": "lodash.js",
  "engines": { "node": ">=4.0.0" },
  "scripts": {
    "build": "npm run build:main && npm run build:fp",
    "build:fp": "node lib/fp/build-dist.js",
    "build:fp-modules": "node lib/fp/build-modules.js",
    "build:main": "node lib/main/build-dist.js",
    "build:main-modules": "node lib/main/build-modules.js",
    "doc": "node lib/main/build-doc github && npm run test:doc",
    "doc:fp": "node lib/fp/build-doc",
    "doc:site": "node lib/main/build-doc site",
    "doc:sitehtml": "optional-dev-dependency marky-markdown@^9.0.1 && npm run doc:site && node lib/main/build-site",
    "pretest": "npm run build",
    "style": "npm run style:main && npm run style:fp && npm run style:perf && npm run style:test",
    "style:fp": "jscs fp/*.js lib/**/*.js",
    "style:main": "jscs lodash.js",
    "style:perf": "jscs perf/*.js perf/**/*.js",
    "style:test": "jscs test/*.js test/**/*.js",
    "test": "npm run test:main && npm run test:fp",
    "test:doc": "markdown-doctest doc/*.md",
    "test:fp": "node test/test-fp",
    "test:main": "node test/test",
    "validate": "npm run style && npm run test"
  },
  "devDependencies": {
    "async": "^2.1.2",
    "benchmark": "^2.1.2",
    "chalk": "^1.1.3",
    "cheerio": "^0.22.0",
    "codecov.io": "~0.1.6",
    "coveralls": "^2.11.15",
    "curl-amd": "~0.8.12",
    "docdown": "~0.7.1",
    "dojo": "^1.11.2",
    "ecstatic": "^2.1.0",
    "fs-extra": "~1.0.0",
    "glob": "^7.1.1",
    "istanbul": "0.4.5",
    "jquery": "^3.1.1",
    "jscs": "^3.0.7",
    "lodash": "4.17.1",
    "lodash-doc-globals": "^0.1.1",
    "markdown-doctest": "^0.9.0",
    "optional-dev-dependency": "^2.0.0",
    "platform": "^1.3.3",
    "qunit-extras": "^3.0.0",
    "qunitjs": "^2.0.1",
    "request": "^2.78.0",
    "requirejs": "^2.3.2",
    "sauce-tunnel": "^2.5.0",
    "uglify-js": "2.7.4",
    "webpack": "^1.13.3"
  },
  "greenkeeper": {
    "ignore": [
      "lodash"
    ]
  }
}

But the published package.json looks like (cf https://unpkg.com/lodash@4.17.2/package.json )

{
  "name": "lodash",
  "version": "4.17.2",
  "description": "Lodash modular utilities.",
  "keywords": "modules, stdlib, util",
  "homepage": "https://lodash.com/",
  "repository": "lodash/lodash",
  "icon": "https://lodash.com/icon.svg",
  "license": "MIT",
  "main": "lodash.js",
  "author": "John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)",
  "contributors": [
    "John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)",
    "Mathias Bynens <mathias@qiwi.be> (https://mathiasbynens.be/)"
  ],
  "scripts": { "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" }
}

where you can see the scripts and devDependencies keys for example are not there anymore. This is done using a JavaScript Template package.jst as long as a nodejs script Lodash CLI

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM