Czyste moduły NPM

144

Czy istnieje sposób, aby npm zdekompilować wszystkie moduły w node_modules? Coś jak odbudowa npm, która usuwa wszystkie artefakty budowy, ale ich nie odbudowuje?

Dave Causey
źródło
4
Myślałem, że nigdy nie zapytasz. Sprawdzałem mój katalog node_modules w git zgodnie z zaleceniami mikealrogers.com/posts/nodemodules-in-git.html . Kiedy dodam nowy moduł lub zaktualizuję obecny, otrzymuję artefakty kompilacji w git, których nie powinno tam być i muszę je wyczyścić. Myślałem, że gdybym mógł je najpierw wyczyścić, proces przebiegałby trochę sprawniej.
Dave Causey,
1
Jedna krótka uwaga: teraz, gdy obsługuje NPM shrinkwrap(patrz npmjs.org/doc/shrinkwrap.html ), możesz zablokować wersje WSZYSTKICH swoich zależności (zamiast tylko tych najwyższego poziomu).
Michelle Tilley,
2
Brak tej funkcji jest również do bani w przypadku programowania międzyplatformowego. Tworzymy na Macu i uruchamiamy CI w Linuksie i musimy usunąć katalog node_modules i całkowicie przeinstalować za każdym razem, gdy robimy kompilację w systemie Linux, co marnuje mnóstwo czasu.
JBCP,
4
@JBCP, robisz to źle. To, co powinieneś zrobić, to zainstalować moduły w packages.json(używając npm --save) i umieścić node_moduleskatalog .gitignore(jeśli używasz git ). CI nie powinien ściągać twoich node_modules, ale wykonać npm install. Wreszcie, jeśli pobieranie z rejestru npm trwa zbyt długo, użyj czegoś takiego jak sinopia, aby go buforować.
Bojan Markovic
1
@BojanMarkovic - Masz rację, tak są teraz konfigurowane nasze projekty. Mój komentarz powyżej pochodzi sprzed około roku. Istnieje (było) kilka projektów, które zalecały wprowadzanie modułów node_modules do Gita, ale zdecydowanie nie jest to poprawne.
JBCP,

Odpowiedzi:

160

Możesz po prostu usunąć katalog node_module

rm -rf node_modules/
Charles
źródło
14
Spowoduje to usunięcie źródła node_modules, a także skompilowanych danych wyjściowych, więc nie odpowiada na pytanie.
theGecko
Jeśli masz zależności połączone z linkiem npm, równie dobrze możesz usunąć źródła tych modułów w ich katalogu źródłowym, co może być dość bolesne ...
cschuff
12
Dodałem to do mojego package.json: "clean": "rm -rf node_modules", "reinstall": "npm run clean && npm install", "rebuild": "npm run clean && npm install && npm run build",. Wydaje się, że działa dobrze.
Lucas
5
Dla Windows> rd node_modules / s
Ishara Samantha
2
@Lucas, powinieneś opublikować tę odpowiedź, ponieważ jest ona najbardziej odpowiednia
Joseph
57

Dodałem to do mojego pliku 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",

Wydaje się, że działa dobrze.

Lucas
źródło
2
cleanmusi być zdefiniowane w pliku package.json!
Ciasto piekarz
20
@Ciastopiekarz? Tak mówi moja odpowiedź powyżej?
Lucas
użyj 'rm -rf node_modules' w przypadku maszyny opartej na Linuksie, w przypadku Windows 'rmdir / s / q node_modules'
Mohamed
Aby z nich skorzystać, nie możesz wywołać "npm clean", ponieważ clean nie jest jedną z akceptowanych nazw na npm. Musisz wykonać "npm run clean".
PCoelho
8

Możesz skorzystać z polecenia „npm cache”, które pobiera paczkę z pakietami i rozpakowuje je do katalogu npm cache.

Następnie można skopiować źródło.

Korzystając z pomysłów zebranych z https://groups.google.com/forum/?fromgroups=#!topic/npm-/mwLuZZkHkfU opracowałem następujący skrypt węzła. Brak gwarancji, YMMV itp.

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
źródło
12
Wydaje mi się bardzo dziwne, że taka podstawowa funkcjonalność, która jest faktycznie zalecana przez npm, wymaga hackowania. Co robią wszyscy inni? Po prostu zignoruj ​​zalecenie i użyj npm install?
VitalyB
5

Jednym słowem nie .

Za dwie, jeszcze nie .

Istnieje jednak otwarta kwestia dotycząca pliku --no-build flagą umożliwiającą npm installwykonanie instalacji bez budowania, której można użyć do zrobienia tego, o co prosisz.

Zobacz ten otwarty problem .

kubit
źródło
4

W środowisku Windows:

"scripts": {
    "clean": "rmdir /s /q node_modules",
    ...
}
Daniel De León
źródło
3

Dodałem kilka wierszy do pliku 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",
  ...
}

Jeśli cleantylko chcesz, możesz tego użyć rimraf node_modules.

Amitesh Singh
źródło
0

W rzeczywistości istnieje specjalne polecenie do tej pracy

npm ci

Usunie node_moduleskatalog i zainstaluje pakiety z uwzględnieniem twojego package-lock.jsonpliku

Więcej informacji: https://docs.npmjs.com/cli/ci.html

FDisk
źródło