Skip to content

Commit

Permalink
新镜像,镜像网络获取
Browse files Browse the repository at this point in the history
  • Loading branch information
gucong3000 committed May 21, 2023
1 parent 6c0345d commit 23547d0
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 79 deletions.
28 changes: 25 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
mirror-config-china
===========

[![NPM version](https://img.shields.io/npm/v/mirror-config-china.svg?style=flat-square)](https://www.npmjs.com/package/mirror-config-china)
[![Travis](https://img.shields.io/travis/gucong3000/mirror-config-china.svg?&label=Linux)](https://travis-ci.org/gucong3000/mirror-config-china)
[![AppVeyor](https://img.shields.io/appveyor/ci/gucong3000/mirror-config-china.svg?&label=Windows)](https://ci.appveyor.com/project/gucong3000/mirror-config-china)
[![NPM version](https://img.shields.io/npm/v/mirror-config-china)](https://www.npmjs.com/package/mirror-config-china)
[![Linux](https://img.shields.io/github/actions/workflow/status/gucong3000/mirror-config-china/node.yml?&label=Linux)](https://github.com/gucong3000/mirror-config-china/actions)
[![Windows](https://img.shields.io/github/actions/workflow/status/gucong3000/mirror-config-china/node_win.yml?&label=Windows)](https://github.com/gucong3000/mirror-config-china/actions)
[![codecov](https://img.shields.io/codecov/c/github/gucong3000/mirror-config-china.svg)](https://codecov.io/gh/gucong3000/mirror-config-china)
[![David](https://img.shields.io/david/gucong3000/mirror-config-china.svg)](https://david-dm.org/gucong3000/mirror-config-china)

Expand Down Expand Up @@ -32,6 +32,10 @@ registry.npmjs.com 镜像URL
### `--bin-mirrors-prefix=https://cdn.npmmirror.com/binaries`
npmmirror.com/mirrors 镜像URL,会覆盖下文中的`{bin-mirrors}`

### `--http-proxy=https://my.proxy.com`
### `--https-proxy=https://my.proxy.com`
代理配置,默认从操作系统设置中读取

### `--nodejs-org-mirror={bin-mirrors}/node` (别名: `--disturl`)
nodejs.org/dist 镜像URL

Expand Down Expand Up @@ -64,6 +68,24 @@ github.com/npm/npm/releases 镜像URL
- [windows-build-tools](https://www.npmjs.com/package/windows-build-tools)
- [@swc/core](https://www.npmjs.com/package/@swc/core)

注:未能全部列出

## 环境变量自动设置

Windows 下会写入注册表:`HKLM/SYSTEM/CurrentControlSet/Control/Session Manager/Environment`

其他系统会写入文件:`/etc/profile.d/node.sh`

自动将当前的代理设置写入`https_proxy``http_proxy`

[Homebrew](https://brew.sh/index_zh-cn)`HOMEBREW_BOTTLE_DOMAIN` 写入国内源(清华)

Node.js IO.js 的国内版本下载地址镜像写入`NODEJS_ORG_MIRROR``IOJS_ORG_MIRROR` 等几个环境变量

PATH 环境变量中加入`node_modules/.bin`这个路径,方便调用 mocha、eslint 等命令行工具

(Windows 下 Path 为`node_modules\\.bin;%Path%` )

## 为项目生成镜像配置文件

```
Expand Down
158 changes: 93 additions & 65 deletions lib/config.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,60 @@

const reg = require('./reg');
/*
const prebuild = require('binary-mirror-config').china;
const got = require('got');
Promise.all(
Object.keys(prebuild).map(pkgName => {
if (pkgName === 'ENVS') {
return;
}
return got('https://registry.npmjs.com/' + pkgName, {
json: true
}).then(
res => res.body.versions[res.body['dist-tags'].latest]
).then(pkg => {
try {
return pkg.binary.module_name;
} catch (ex) {
return pkgName.replace(/-/g, '_');
}
}).then(moduleName => {
Object.keys(prebuild[pkgName]).forEach(key => {
if (/[A_Z]/.test(key)) {
return;
}
const value = prebuild[pkgName][key];
if (typeof value === 'string') {
npmrc[moduleName + '_binary_' + key + '_mirror'] = value;
}
});
});
})
).then(() => {
console.log(npmrc);
});
*/
function getConf (argv) {
const assert = require('assert');

let mirrors;

function getMirror () {
mirrors = mirrors || binaryMirrorConfig();
return mirrors;
}
async function binaryMirrorConfig () {
const controller = new AbortController();
const pkg = await Promise.any(
[
'npm.elemecdn.com',
'fastly.jsdelivr.net/npm',
'cdn.jsdelivr.net/npm',
].map(async host => {
const res = await fetch(
`https://${host}/binary-mirror-config/package.json`,
{ signal: controller.signal },
);
assert.ok(res.ok);
return res.json();
}),
).catch(() => require('binary-mirror-config/package.json')).catch(() => {});
controller.abort();
return pkg?.mirrors?.china;
}

function getBinPrefix (mirrors) {
return mirrors && Object.keys(mirrors).map(
pkg => mirrors[pkg],
).map(
pkg => pkg.remote_path && pkg.host,
).filter(Boolean).reduce(
(result, host) => result.length < host.length ? result : host,
);
}

async function getConf (argv) {
const isWin = process.platform === 'win32';
const npmrc = {
'registry': 'https://registry.npmmirror.com',
'corepack-npm-registry': 'https://registry.npmmirror.com',

'disturl': '{bin-mirrors}/node',

/* eslint no-template-curly-in-string: "off" */
'better-sqlite3-binary-host': '{bin-mirrors}/better-sqlite3',
'canvas-binary-host-mirror': '{bin-mirrors}/node-canvas-prebuilt/v{version}',
'canvas-prebuilt-binary-host-mirror': '{bin-mirrors}/node-canvas-prebuilt/v{version}',
'chromedriver-cdnurl': '{bin-mirrors}/chromedriver',
'couchbase-binary-host-mirror': '{bin-mirrors}/couchbase/v{version}',
'cypress-download-path-template': '{bin-mirrors}/cypress/${version}/${platform}-${arch}/cypress.zip',
'debug-binary-host-mirror': '{bin-mirrors}/node-inspector',
'electron-builder-binaries-mirror': '{bin-mirrors}/electron-builder-binaries/',
'electron-mirror': '{bin-mirrors}/electron/',
'flow-bin-binary-host-mirror': '{bin-mirrors}/flow/v',
'fse-binary-host-mirror': '{bin-mirrors}/fsevents',
Expand All @@ -50,28 +63,38 @@ function getConf (argv) {
'gl-binary-host-mirror': '{bin-mirrors}/gl/v{version}',
'grpc-node-binary-host-mirror': '{bin-mirrors}',
'hackrf-binary-host-mirror': '{bin-mirrors}/hackrf/v{version}',
'keytar-binary-host': '{bin-mirrors}/keytar',
'leveldown-binary-host-mirror': '{bin-mirrors}/leveldown/v{version}',
'leveldown-hyper-binary-host-mirror': '{bin-mirrors}/leveldown-hyper/v{version}',
'mknod-binary-host-mirror': '{bin-mirrors}/mknod/v{version}',
'node-sqlite3-binary-host-mirror': '{bin-mirrors}',
'node-tk5-binary-host-mirror': '{bin-mirrors}/node-tk5/v{version}',
'nodegit-binary-host-mirror': '{bin-mirrors}/nodegit/v{version}/',
'nwjs-urlbase': '{bin-mirrors}/nwjs/v',
'operadriver-cdnurl': '{bin-mirrors}/operadriver',
'phantomjs-cdnurl': '{bin-mirrors}/phantomjs',
'playwright-download-host': '{bin-mirrors}/playwright',
'profiler-binary-host-mirror': '{bin-mirrors}/node-inspector/',
'puppeteer-download-host': '{bin-mirrors}',
// https://github.com/puppeteer/puppeteer/commit/9758cae029f90908c4b5340561d9c51c26aa2f21
'puppeteer-download-base-url': '{bin-mirrors}/chrome-for-testing',
'python-mirror': '{bin-mirrors}/python',
'rabin-binary-host-mirror': '{bin-mirrors}/rabin/v{version}',
're2-download-mirror': '{bin-mirrors}/node-re2',
'robotjs-binary-host': '{bin-mirrors}/robotjs',
'sass-binary-site': '{bin-mirrors}/node-sass',
'saucectl-install-binary-mirror': '{bin-mirrors}/saucectl',
'sentrycli-cdnurl': '{bin-mirrors}/sentry-cli',
'sharp-binary-host': '{bin-mirrors}/sharp',
'sharp-libvips-binary-host': '{bin-mirrors}/sharp-libvips',
'sodium-prebuilt-binary-host-mirror': '{bin-mirrors}/sodium-prebuilt/v{version}',
'sqlite3-binary-site': '{bin-mirrors}/sqlite3',
'swc-binary-site': '{bin-mirrors}/node-swc',
'utf-8-validate-binary-host-mirror': '{bin-mirrors}/utf-8-validate/v{version}',
'utp-native-binary-host-mirror': '{bin-mirrors}/utp-native/v{version}',
'zmq-prebuilt-binary-host-mirror': '{bin-mirrors}/zmq-prebuilt/v{version}',
'canvas-binary-host-mirror': '{bin-mirrors}/node-canvas-prebuilt/v{version}',
'canvas-prebuilt-binary-host-mirror': '{bin-mirrors}/node-canvas-prebuilt/v{version}',
'swc_binary_site': '{bin-mirrors}/node-swc',
};
const mirrors = await getMirror();
npmrc.registry = mirrors?.ENVS.COREPACK_NPM_REGISTRY || npmrc.registry;

const env = {
https_proxy: null,
Expand All @@ -90,16 +113,23 @@ function getConf (argv) {
env.PATH = 'node_modules/.bin:$PATH';
if (process.platform === 'darwin') {
// https://brew.sh/index_zh-cn
env.HOMEBREW_BOTTLE_DOMAIN = '{ali-mirrors}/homebrew/homebrew-bottles';
env.HOMEBREW_BOTTLE_DOMAIN = 'https://mirrors.tuna.tsinghua.edu.cn/homebrew/homebrew-bottles';
}
}

const opts = {
binMirrorsPrefix: 'https://cdn.npmmirror.com/binaries',
binMirrorsPrefix: getBinPrefix(mirrors) || 'https://cdn.npmmirror.com/binaries',
npmrc: npmrc,
env: env,
};

for (const key in mirrors?.ENVS) {
const value = mirrors.ENVS[key];
if (/^\w+:\/\//.test(value) && !/\w+_ORG_MIRROR$/i.test(key)) {
npmrc[key.toLowerCase().replace(/^npm_config_/, '').replaceAll('_', '-')] = value.replace(opts.binMirrorsPrefix, '{bin-mirrors}');
}
}

argv.forEach(arg => {
if (!/^--(\w+.+?)=(.*?)$/.test(arg)) {
return;
Expand All @@ -113,6 +143,7 @@ function getConf (argv) {
key = RegExp.$1.toLowerCase();
env[key + '_proxy'] = value;
key = key + '-proxy';
return;
} else if (/^env-/i.test(key)) {
env[key.slice(4).toUpperCase().replace(/-/g, '_')] = value;
return;
Expand Down Expand Up @@ -172,31 +203,28 @@ function getConf (argv) {
});
});

return (
isWin && (!env.http_proxy || !env.https_proxy)
? reg.query('HKCU/Software/Microsoft/Windows/CurrentVersion/Internet Settings').then(settings => {
if (settings.autoConfigURL) {
env.https_proxy = settings.autoConfigURL.replace(/^(\w+:\/\/[^/]+).*/, '$1');
} else if (settings.proxyEnable && settings.proxyServer) {
settings.ProxyServer.split(';').forEach(server => {
server = server.match(/^(?:(\w+)=)?(.*)/);
if (server[1] && !/^https?$/.test(server[1])) {
return;
}
const key = (server[1] || 'https') + '_proxy';
if (!env[key]) {
env[key] = 'http://' + server[2];
}
});
if (isWin && (!env.http_proxy || !env.https_proxy)) {
const settings = await reg.query('HKCU/Software/Microsoft/Windows/CurrentVersion/Internet Settings');
if (settings.autoConfigURL) {
env.https_proxy = settings.autoConfigURL.replace(/^(\w+:\/\/[^/]+).*/, '$1');
} else if (settings.proxyEnable && settings.proxyServer) {
settings.ProxyServer.split(';').forEach(server => {
server = server.match(/^(?:(\w+)=)?(.*)/);
if (server[1] && !/^https?$/.test(server[1])) {
return;
}
})
: Promise.resolve()
).then(() => {
if (!env.http_proxy && env.https_proxy) {
env.http_proxy = env.https_proxy;
npmrc['http-proxy'] = env.https_proxy;
const key = (server[1] || 'https') + '_proxy';
if (!env[key]) {
env[key] = 'http://' + server[2];
}
});
}
return opts;
});
}

if (!env.http_proxy && env.https_proxy) {
env.http_proxy = env.https_proxy;
// npmrc['http-proxy'] = env.https_proxy;
}
return opts;
}
module.exports = getConf;
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"description": "Mirrors in China about node.js",
"devDependencies": {
"binary-mirror-config": "^2.11.0",
"chai": "^4.3.7",
"codecov": "^3.8.2",
"eslint": "^8.41.0",
Expand Down Expand Up @@ -47,5 +48,5 @@
"install-test": "npm run install && npm test",
"test": "mocha --no-timeouts"
},
"version": "2.6.0"
"version": "3.0.0"
}
11 changes: 1 addition & 10 deletions test/npmrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('npm config', () => {
});

it('puppeteer', () => {
assert.strictEqual(process.env.npm_config_puppeteer_download_host, 'https://cdn.npmmirror.com/binaries');
assert.strictEqual(process.env.npm_config_puppeteer_download_base_url, 'https://cdn.npmmirror.com/binaries/chrome-for-testing');
});

it('python', () => {
Expand Down Expand Up @@ -95,15 +95,6 @@ describe('get config', () => {
assert.strictEqual(npmrc['chromedriver-cdnurl'], 'https://mirror.mock/chromedriver');
assert.ifError(npmrc['bin-mirrors-prefix']);
});
it('--http-proxy', async () => {
const opts = await config([
'--https-proxy=https://proxy.https.mock',
'--http-proxy=https://proxy.http.mock',
]);
const npmrc = opts.npmrc;
assert.strictEqual(npmrc['https-proxy'], 'https://proxy.https.mock');
assert.strictEqual(npmrc['http-proxy'], 'https://proxy.http.mock');
});
});

describe('config file', () => {
Expand Down

0 comments on commit 23547d0

Please sign in to comment.