NPM módulos limpios

144

¿Hay alguna manera de hacer que npm descomprima todos los módulos en node_modules? ¿Algo como npm rebuild que elimina todos los artefactos de construcción pero no los reconstruye?

Dave Causey
fuente
44
Pensé que nunca preguntarias. He estado revisando mi directorio node_modules en git como se recomienda en mikealrogers.com/posts/nodemodules-in-git.html . Cuando agrego un nuevo módulo o actualizo uno actual, termino con artefactos de compilación en git que no deberían estar allí y tengo que limpiarlos. Estaba pensando que si pudiera limpiarlos primero, el proceso sería un poco más fácil.
Dave Causey
1
Una nota rápida: ahora que NPM admite shrinkwrap(consulte npmjs.org/doc/shrinkwrap.html ), puede bloquear las versiones de TODAS sus dependencias (en lugar de solo las de nivel superior).
Michelle Tilley
2
No tener esta característica también es una mierda para el desarrollo multiplataforma. Desarrollamos en Mac y ejecutamos CI en Linux, y necesitamos eliminar el directorio node_modules y volver a instalarlo cada vez que hacemos una compilación en Linux, lo que desperdicia un montón de tiempo.
JBCP
44
@JBCP lo estás haciendo mal. Lo que debería hacer es instalar módulos en packages.json(usando npm --save) y poner el node_modulesdirectorio en .gitignore(si usa git ). CI no debe extraer sus node_modules, sino ejecutarlos npm install. Finalmente, si la descarga del registro npm toma demasiado tiempo, use algo como sinopia para almacenarlo en caché.
Bojan Markovic
1
@BojanMarkovic - Tienes razón, así es como se configuran nuestros proyectos ahora. Mi comentario anterior fue de hace aproximadamente un año. Hay (fueron) algunos proyectos que recomendaron comprometer node_modules en Git, pero eso definitivamente no es correcto.
JBCP

Respuestas:

160

Simplemente puede eliminar el directorio node_module

rm -rf node_modules/
Charles
fuente
14
Esto eliminaría la fuente de node_modules, así como la salida compilada, por lo que no responde la pregunta.
theGecko
Si ha vinculado con dependencias enlace NPM que bien podría eliminar estos módulos fuente en ella del directorio de origen que puede ser bastante doloroso ...
cschuff
12
He añadido esto a mi package.json: "clean": "rm -rf node_modules", "reinstall": "npm run clean && npm install", "rebuild": "npm run clean && npm install && npm run build",. Parece funcionar bien.
Lucas
55
Para windows> rd node_modules / s
Ishara Samantha
2
@Lucas deberías publicar esto y una respuesta ya que es la más adecuada
Joseph
57

Agregué esto a mi 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",

Parece funcionar bien.

Lucas
fuente
2
cleantiene que ser definido en el paquete.json!
Ciasto piekarz
20
@Ciastopiekarz? Eso es lo que dice mi respuesta arriba?
Lucas
use 'rm -rf node_modules' en el caso de una máquina basada en Linux, en caso de windows 'rmdir / s / q node_modules'
Mohamed.Abdo
Para usarlos no se puede llamar "npm clean" ya que clean no es uno de los nombres aceptados en npm. Debe hacer "npm run clean".
PCoelho
8

Puede aprovechar el comando 'npm cache' que descarga el paquete tarball y lo descomprime en el directorio npm cache.

La fuente se puede copiar en.

Utilizando ideas obtenidas de https://groups.google.com/forum/?fromgroups=#!topic/npm-/mwLuZZkHkfU se me ocurrió el siguiente script de nodo. Sin garantías, YMMV, etcétera.

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
fuente
12
Me resulta muy extraño que una funcionalidad tan básica, que en realidad es recomendada por npm, requiera un truco para lograrlo. ¿Qué hacen todos los demás? ¿Ignorar la recomendación y usar npm install?
VitalyB
5

En una palabra no .

En dos, todavía no .

Sin embargo, hay un problema abierto para que una --no-buildbandera npm installrealice una instalación sin construir, que podría usarse para hacer lo que está pidiendo.

Ver este tema abierto .

qubyte
fuente
4

Para el entorno de Windows:

"scripts": {
    "clean": "rmdir /s /q node_modules",
    ...
}
Daniel De León
fuente
3

He agregado algunas líneas dentro de 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",
  ...
}

Si cleansolo quieres, puedes usar esto rimraf node_modules.

Amitesh Singh
fuente
0

En realidad hay un comando especial para este trabajo

npm ci

Eliminará el node_modulesdirectorio e instalará paquetes con respecto a su package-lock.jsonarchivo

Más información: https://docs.npmjs.com/cli/ci.html

FDisk
fuente