Чистые модули NPM

152

Есть ли способ заставить npm разобрать все модули в node_modules? Что-то вроде npm rebuild, которое удаляет все артефакты сборки, но не восстанавливает их?

Дэйв Кози
источник
4
Думал ты никогда не спросишь. Я проверял свой каталог node_modules в git, как рекомендовано в mikealrogers.com/posts/nodemodules-in-git.html . Когда я добавляю новый модуль или обновляю текущий, я получаю артефакты сборки в git, которых не должно быть, и мне приходится их очищать. Я думал, если бы я мог сначала очистить их, процесс прошел бы немного более гладко.
Dave Causey
1
Одно небольшое замечание: теперь, когда NPM поддерживает shrinkwrap(см. Npmjs.org/doc/shrinkwrap.html ), вы можете заблокировать версии ВСЕХ ваших зависимостей (вместо только зависимостей верхнего уровня).
Мишель Тилли
2
Отсутствие этой функции тоже плохо для кроссплатформенной разработки. Мы разрабатываем для Mac и запускаем CI в Linux, и нам нужно удалять каталог node_modules и полностью переустанавливать каждый раз, когда мы делаем сборку в Linux, что тратит массу времени.
JBCP
4
@JBCP ты делаешь неправильно. Что вам нужно сделать, так это установить модули packages.json(используя npm --save) и поместить node_modulesкаталог .gitignore(если вы используете git ). CI не должен тянуть ваши node_modules, а выполнять npm install. Наконец, если загрузка из реестра npm занимает слишком много времени, используйте что-то вроде sinopia для его кеширования.
Боян Маркович
1
@BojanMarkovic - Вы правы, так сейчас наши проекты настроены. Мой комментарий выше был написан около года назад. Было (было) несколько проектов, в которых рекомендовалось зафиксировать node_modules в Git, но это определенно неверно.
JBCP 02

Ответы:

164

Вы можете просто удалить каталог node_module

rm -rf node_modules/
Чарльз
источник
15
Это приведет к удалению источника node_modules, а также скомпилированного вывода, поэтому не отвечает на вопрос.
theGecko
Если у вас есть зависимости, связанные с ссылкой npm, он может также удалить источник этих модулей в исходном каталоге, что может быть довольно болезненным ...
cschuff
12
Я добавил это к моему package.json: "clean": "rm -rf node_modules", "reinstall": "npm run clean && npm install", "rebuild": "npm run clean && npm install && npm run build",. Кажется, работает хорошо.
Лукас
5
Для windows> rd node_modules / s
Ishara Samantha
2
@Lucas, ты должен опубликовать этот ответ, так как он самый подходящий
Джозеф
65

Я добавил это в свой 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
cleanдолжен быть определен в package.json!
Ciasto piekarz
21
@Ciastopiekarz? Это мой ответ выше?
Лукас
1
используйте 'rm -rf node_modules' в случае машины на базе Linux, в случае Windows 'rmdir / s / q node_modules'
Mohamed.Abdo
1
Чтобы использовать их, вы не можете называть "npm clean", так как clean не является одним из принятых имен в npm. Вам нужно сделать "npm run clean".
PCoelho
14

На самом деле есть специальная команда для этой работы

npm ci

Он удалит node_modulesкаталог и установит пакеты с учетом вашего package-lock.jsonфайла

Подробнее: https://docs.npmjs.com/cli/ci.html

FDisk
источник
На самом деле, если вы работаете с другими членами команды, и они обновляли некоторые зависимости, вы должны делать это всегда, npm ciа не просто так npm i. Основная причина, по которой npm iтакже обновляется файл блокировки, вероятно, вы не хотите делать.
FDisk
8

Вы можете воспользоваться командой npm cache, которая загружает архив пакета и распаковывает его в каталог кэша npm.

Затем источник можно скопировать.

Используя идеи, почерпнутые из https://groups.google.com/forum/?fromgroups=#!topic/npm-/mwLuZZkHkfU, я придумал следующий сценарий узла. Никаких гарантий, YMMV и т. Д.

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());
theGecko
источник
12
Мне очень странно, что для достижения такой базовой функциональности, которая на самом деле рекомендуется npm, требуется взлом. Что делают все остальные? Просто игнорируйте рекомендацию и пользуйтесь npm install?
VitalyB
5

Одним словом, нет .

Через два, пока нет .

Однако есть открытая проблема с --no-buildфлагом для npm installвыполнения установки без сборки, который можно использовать для выполнения того, о чем вы просите.

См. Этот открытый вопрос .

кубайт
источник
4

Для среды Windows:

"scripts": {
    "clean": "rmdir /s /q node_modules",
    ...
}
Даниэль Де Леон
источник
3

Я добавил несколько строк внутри 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.

Амитеш Сингх
источник