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