Чистые модули 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


На самом деле, если вы работаете с другими членами команды, и они обновляли некоторые зависимости, вы должны делать это всегда, 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());

12
Мне очень странно, что для достижения такой базовой функциональности, которая на самом деле рекомендуется npm, требуется взлом. Что делают все остальные? Просто игнорируйте рекомендацию и пользуйтесь npm install?
VitalyB


5

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

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

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

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



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.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.