yarn 离线安装

1,934 阅读4分钟

前言

最近由于运维那边经常出现npm包下载不下来,典型的就是pngquant-bin,pngquant 由于前端这边都是翻墙出去,所以平时根本不出来,但是运维那边不能翻墙,或者翻墙出去有时候在客户那边安装也不是很方便,所以想搞个离线安装。

尝试1

刚开始想这直接把node_modules直接放到git上,然后到时候直接拉下来直接用就可以来。

结果理想很丰满,可是现实很残酷,当测试的时候,拉下来的代码,运行的时候,提示好多的包找不到,解决了两三个包,实在不耐烦了。 然后直接npm install,没有提示错误,但是运行还是失败,这种方法确实不可行,放弃。

尝试2

后来想尝试下npm离线安装的其他方法,找了下npm包,看到很多推荐npmbox,于是去看了下,可是npmbox已经很明确了表示不支持npm@5,其他的npm offline包,看了都是几个或者几十个star,看着也没啥意思,看着也不想用。 最后决定这种也放弃。

尝试3

既然不想用npm包,于是找了下有没有其他的方法,于是找到了一个命令 npm install --global-style,这个命令看起来不错,他妈的用起来简直是弱智, 当只有一个包的时候,好好的什么事也没有,可是包一多起来,各种问题就来了, 首先 安装,如果全部依赖包都下下来,少的十几个,多个几百个都不止,安装的时候,不能一个个安装,太难受了。后来想了下,能不能把下来的依赖,一个个包装成tgz包,然后下载,试了一两个,好像可以,可是包多了之后,不能一个个压缩吧,于是写了个脚本

#!/bin/bash

for element in `ls $1`
do
  echo "8999"
  dir_or_file=$1"/"$element
  echo "$dir_or_file"
  if [ -d $dir_or_file ];
  then
    echo "dir == $element"
    tar cvf "$dir_or_file.tgz" $dir_or_file
  else
      echo "file == 00000"
  fi
done

把node_modules下所有一级目录,全部打包成tgz包,复制到别的目录,可是想离线安装的时候,直接提示都找不到,感觉这个没有多大的前途,放弃!

尝试4

因为在搜索的时候,感觉npm离线安装的资料比较少,看到yarn离线安装的资料都不少,于是想了试试。 因为原来的项目都是npm,切换起来也不是很费劲,可是切过来,不知道运气不好还是人品太差,用yarn 安装包的时候,妈的,动不动就卡着,然后一转就转半天,等不耐烦了,重装还是这样。 实在忍不住了,干脆把翻墙开成全局,妈的,终于速度刷刷的起来了,安装起来超快。

yarn的离线安装原理很简单,其实就是设置一下离线在线的包地址,然后在离线下载的时候,去离线在线的包地址去下载安装。 比较好的文档还是官方的文档 yarnpkg.com/blog/2016/1…

这里的设置也很简单,没什么好说的,不过这里提示一下,文档里边的离线安装的命令是错的,正确的是yarn install --offlline 但是根据这里的设置设置完之后,悲剧的事情就又来了。 当执行的时候,yarn install --offlline 报错如下图

image.png

可以看到是在这里出错了 error : Command failed. Exit code: 1 Command: node lib/install.js 于是到文件里边去看下,文件比较短,可以看下

'use strict';
const binBuild = require('bin-build');
const logalot = require('logalot');
const bin = require('.');

bin.run(['--version'], err => {
	if (err) {
		logalot.warn(err.message);
		logalot.warn('pngquant pre-build test failed');
		logalot.info('compiling from source');

		const libpng = process.platform === 'darwin' ? 'libpng' : 'libpng-dev';

		binBuild.url('http://pngquant.org/pngquant-2.10.1-src.tar.gz', [
			'rm ./INSTALL',
			`./configure --prefix="${bin.dest()}"`,
			`make install BINPREFIX="${bin.dest()}"`
		])
			.then(() => {
				logalot.success('pngquant built successfully');
			})
			.catch(err => {
				err.message = `pngquant failed to build, make sure that ${libpng} is installed`;
				logalot.error(err.stack);

				// eslint-disable-next-line unicorn/no-process-exit
				process.exit(1);
			});
	}

	logalot.success('pngquant pre-build test passed successfully');
});

刚开始的时候,没仔细看文件内容,看到这里动态的去请求tar包,比如这里http://pngquant.org/pngquant-2.10.1-src.tar.gz就感觉他妈的很绝望,本来是离线下载了,你他妈的再去动态去请求,老子玩个鸟。 当时就感觉很绝望,这怎么搞嘛, 于是这里就去google狂搜各种yarn offline(这里想起了以前看过的一本书<跃迁>,里边说搜索提高了人类搜索的能力,可是感觉现在什么问题都可以搜到的时候,总是放弃了自己的很多思考的空间,现在遇到什么问题,就想到了去网上搜下,可是自己的思考呢,如果没有思考的搜索有什么用呢,还是得先思考,找到问题的根本之后,再去搜索,而不是没有思考的搜索)。 搜索一圈,没找到什么有用的信息,感觉很乱。 没办法了,只能重新回来继续看刚才的地方。 看了下/Users/zsj/work/tip/node_modules/image-webpack-loader/node_modules/pngquant-bin/lib/install.js这里的文件,逻辑比较简单,最重要的是bin是啥,根据目录找到/Users/zsj/work/tip/node_modules/image-webpack-loader/node_modules/pngquant-bin/lib/index.js

'use strict';
const path = require('path');
const BinWrapper = require('bin-wrapper');
const pkg = require('../package.json');

const url = `https://raw.github.com/imagemin/pngquant-bin/v${pkg.version}/vendor/`;

module.exports = new BinWrapper()
	.src(`${url}macos/pngquant`, 'darwin')
	.src(`${url}linux/x86/pngquant`, 'linux', 'x86')
	.src(`${url}linux/x64/pngquant`, 'linux', 'x64')
	.src(`${url}freebsd/x64/pngquant`, 'freebsd', 'x64')
	.src(`${url}win/pngquant.exe`, 'win32')
	.dest(path.resolve(__dirname, '../vendor'))
	.use(process.platform === 'win32' ? 'pngquant.exe' : 'pngquant');

这里的逻辑更简单,其实就是下载下来pngquant,然后放到vendor里边,根据平台的类型,是不是win32,使用不同的命令。 现在再回到/Users/zsj/work/tip/node_modules/image-webpack-loader/node_modules/pngquant-bin/lib/install.js,可以看到这里

bin.run(['--version'], err => {})

判断逻辑就是看下你的系统里边有没有了pngquant --version 或者是pngquant.exe --version,如果不存在,然后就去下载,然后编译,把pngquant 命令打入到系统中去,如果下载失败就提示,就是我们在前面看到的错误 pngquant failed to build, make sure that ${libpng} is installed

到了这里就比较清楚了,这个pngquant-bin并不是非得去下载pngquant包,而是在检测到你的系统里边没有pngquant --version的时候,再去下载,这就对离线下载提供了可能,可以提前安装下pngquant,等到检测的时候,就不会再去下载也就不会退出了。 测试 去下载安装pngquant 可以看到

image.png
关闭网络
image.png

然后执行 yarn install --offline 执行成功

image.png

然后基本上就可以离线安装了,但是到liunx上测试的时候,还提示了少了gifsicle,原理是一样的,这个可能和平台一样。

ps: 没有思考的搜索