如何使用npm进行干净的安装(删除node_modules并重新安装)?

260
有没有办法让npm取消构建node_modules下的所有模块?类似于npm rebuild,它可以删除所有构建产物但不重新构建它们吗?

4
想不到你会问这个问题。我一直按照http://www.mikealrogers.com/posts/nodemodules-in-git.html中的建议将我的node_modules目录提交到git中。当我添加新模块或更新当前模块时,会在git中产生不应出现的构建工件,因此需要清除它们。我在想如果我能先清理它们,整个过程可能会更顺利一些。 - Dave Causey
1
一个快速的提示:现在NPM支持shrinkwrap(参见http://npmjs.org/doc/shrinkwrap.html),你可以锁定所有依赖项的版本(而不仅仅是顶级依赖项)。 - Michelle Tilley
2
没有这个功能对跨平台开发来说很糟糕。我们在 Mac 上进行开发,而在 Linux 上运行 CI,并且每次在 Linux 上构建时都需要删除 node_modules 目录并完全重新安装,这浪费了大量时间。 - JBCP
7
@JBCP,你做错了。你应该在packages.json中安装模块(使用npm --save),并将node_modules目录放在.gitignore中(如果使用了Git)。CI不应该拉取你的node_modules,但应该执行npm install。最后,如果从npm注册表下载太慢,请使用类似sinopia的东西来缓存它。 - Bojan Markovic
1
@BojanMarkovic - 你说得对,这就是我们现在设置项目的方式。我上面的评论是大约一年前的了。有一些项目建议将node_modules提交到Git中,但那绝对是不正确的。 - JBCP
显示剩余3条评论
11个回答

203

你可以直接删除 node_module 文件夹

rm -rf node_modules/

25
这将删除 node_modules 的来源以及编译输出,所以并没有回答这个问题。 - theGecko
我其实很喜欢这个。有时候你只需要删除 node_modules 并重新安装它们。 - Kermit_ice_tea
16
我在package.json中添加了以下代码:"clean": "rm -rf node_modules", "reinstall": "npm run clean && npm install", "rebuild": "npm run clean && npm install && npm run build",看起来工作得很好。 - Lucas
7
针对 Windows 操作系统,要删除 node_modules 目录及其所有子目录和文件,可以使用命令 rd node_modules /s - Ishara Samantha
2
@Lucas,你应该把这个作为答案发布,因为它是最合适的一个。 - Joseph
显示剩余5条评论

172

其实有一个特殊的命令可以完成这项工作

npm ci

它将删除node_modules目录,并根据您的package-lock.json文件安装软件包。

更多信息:https://docs.npmjs.com/cli/ci.html


12
如果你与其他团队成员一起工作,而他们更新了某些依赖项,你应该始终运行 npm ci 而不是仅仅运行 npm i。主要原因是 npm i 也会更新锁定文件,这可能不是你想要的。 - FDisk
OP没有明确指定他们正在建立一个全新的项目,所以当你负责更新依赖项时要小心,因为更新package-lock文件的唯一方法是运行npm i。这有点误导人,因为它被称为“clean install”,但并不一定是这样。最好改名为rebase或其他什么更好。如果你还依赖于将项目版本放在package.json中,那么只有在运行npm i之后,package-lock才会得到更新,尽管这并不是很重要。 - Kris Boyd

96

我将以下内容添加到我的package.json文件中:

"build": "npm build",
"clean": "rm -rf node_modules", 
"reinstall": "npm run clean && npm install", 
"rebuild": "npm run clean && npm install && npm run build",

看起来工作得很好。


2
必须在 package.json 文件中定义 clean - Ciasto piekarz
29
@Ciastopiekarz?这就是我上面所说的答案吗? - Lucas
3
如果你正在使用基于Linux的计算机,可以使用命令'rm -rf node_modules'来删除node_modules文件夹;如果你正在使用Windows系统,可以使用命令'rmdir /s /q node_modules'来删除。 - Mohamed.Abdo
3
要使用这些,您不能调用“npm clean”,因为clean不是npm上接受的名称之一。您需要执行“npm run clean”。 - PCoelho
6
请注意,reinstall 现在是内置命令 npm ci 的别名。 - Silviu Burcea
显示剩余2条评论

28

谢谢你的回答。顺便问一下,你能分享一下你是如何做这个动画的吗? :) - lww
2
@lww https://github.com/vvo/gifify - jeckep

9

npm ci 可以适用于这种情况,但前提是你的 package.jsonpackage-lock.json 文件是同步的。如果你在其中一个文件上进行了处理以快速解决冲突,或者通过移除某些目录/符号链接来更新目录级别,则两个文件可能不会始终保持同步。以下是一个全面的答案。

  1. 编辑 package.json,添加所需内容并移除不需要的内容。
  2. 使用以下命令生成 package-lock.jsonnpm install --package-lock-only
  3. 运行 npm ci。这应该会删除所有构件,并且不会重建它们。

对于任何运行此命令失败的人,请尝试使用 npm ci --legacy-peer-deps - undefined

9
你可以使用“npm cache”命令,它会下载软件包tarball并将其解压缩到npm缓存目录中。
然后可以复制源代码。
使用从https://groups.google.com/forum/?fromgroups=#!topic/npm-/mwLuZZkHkfU获取的想法,我编写了以下Node脚本。无任何担保,结果可能因人而异等等。
var fs = require('fs'),
path = require('path'),
exec = require('child_process').exec,
util = require('util');

var packageFileName = 'package.json';
var modulesDirName = 'node_modules';
var cacheDirectory = process.cwd();
var npmCacheAddMask = 'npm cache add %s@%s; echo %s';
var sourceDirMask = '%s/%s/%s/package';
var targetDirMask = '%s/node_modules/%s';

function deleteFolder(folder) {
    if (fs.existsSync(folder)) {
        var files = fs.readdirSync(folder);
        files.forEach(function(file) {
            file = folder + "/" + file;
            if (fs.lstatSync(file).isDirectory()) {
                deleteFolder(file);
            } else {
                fs.unlinkSync(file);
            }
        });
        fs.rmdirSync(folder);
    }
}

function downloadSource(folder) {
    var packageFile = path.join(folder, packageFileName);
    if (fs.existsSync(packageFile)) {
        var data = fs.readFileSync(packageFile);
        var package = JSON.parse(data);

        function getVersion(data) {
            var version = data.match(/-([^-]+)\.tgz/);
            return version[1];
        }

        var callback = function(error, stdout, stderr) {
            var dependency = stdout.trim();
            var version = getVersion(stderr);
            var sourceDir = util.format(sourceDirMask, cacheDirectory, dependency, version);
            var targetDir = util.format(targetDirMask, folder, dependency);
            var modulesDir = folder + '/' + modulesDirName;

            if (!fs.existsSync(modulesDir)) {
                fs.mkdirSync(modulesDir);
            }

            fs.renameSync(sourceDir, targetDir);
            deleteFolder(cacheDirectory + '/' + dependency);
            downloadSource(targetDir);
        };

        for (dependency in package.dependencies) {
            var version = package.dependencies[dependency];
            exec(util.format(npmCacheAddMask, dependency, version, dependency), callback);
        }
    }
}

if (!fs.existsSync(path.join(process.cwd(), packageFileName))) {
    console.log(util.format("Unable to find file '%s'.", packageFileName));
    process.exit();
}

deleteFolder(path.join(process.cwd(), modulesDirName));
process.env.npm_config_cache = cacheDirectory;
downloadSource(process.cwd());

12
我觉得很奇怪,一个如此基本且npm推荐的功能需要使用hack才能实现。其他人都是怎么做的?是忽略推荐直接使用“npm install”吗? - VitalyB

6

总之,不行。

但是,目前还没有。

不过,有一个敞开的问题是为npm install提供--no-build标志来执行无需构建的安装,这可以用于实现您所要求的功能。

请参见此敞开的问题


5

针对Windows环境:

"scripts": {
    "clean": "rmdir /s /q node_modules",
    ...
}

5

我在package.json文件中添加了几行代码:

"scripts": {
  ...
  "clean": "rmdir /s /q node_modules",
  "reinstall": "npm run clean && npm install",
  "rebuild": "npm run clean && npm install && rmdir /s /q dist && npm run build --prod",
  ...
}

如果您只想要“清理(clean)”,可以使用这个命令:rimraf node_modules


对于Mac或Linux用户: "clean": "rm -rf node_modules", - claudius

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接