diff --git a/packages/wmr/src/cli.js b/packages/wmr/src/cli.js index aa45b90c..3c6669dc 100644 --- a/packages/wmr/src/cli.js +++ b/packages/wmr/src/cli.js @@ -35,6 +35,7 @@ prog .option('--visualize', 'Launch interactive bundle visualizer') .option('--minify', 'Enable minification of generated code (default: true)', true) .option('--autoInstall', 'Fetch missing npm packages from npm registry automatically (default: false') + .option('--registry', 'NPM registry url to fetch if "--autoInstall" is set (default: https://registry.npmjs.org)') .action(opts => { opts.minify = bool(opts.minify); run(build(opts)); @@ -62,6 +63,7 @@ prog .option('--profile', 'Generate build statistics') .option('--reload', 'Switch off hmr and reload on file saves') .option('--autoInstall', 'Fetch missing npm packages from npm registry automatically (default: false') + .option('--registry', 'NPM registry url to fetch if "--autoInstall" is set (default: https://registry.npmjs.org)') .action(opts => { opts.optimize = !/false|0/.test(opts.compress); opts.compress = bool(opts.compress); diff --git a/packages/wmr/src/lib/normalize-options.js b/packages/wmr/src/lib/normalize-options.js index bbbe464e..65657abf 100644 --- a/packages/wmr/src/lib/normalize-options.js +++ b/packages/wmr/src/lib/normalize-options.js @@ -25,6 +25,7 @@ export async function normalizeOptions(options, mode, configWatchFiles = []) { options.features = { preact: true }; options.alias = options.alias || options.aliases || {}; options.customRoutes = options.customRoutes || []; + options.registry = options.registry || 'https://registry.npmjs.org'; // `wmr` / `wmr start` is a development command. // `wmr build` / `wmr serve` are production commands. diff --git a/packages/wmr/src/lib/plugins.js b/packages/wmr/src/lib/plugins.js index 0a8153db..c904da2e 100644 --- a/packages/wmr/src/lib/plugins.js +++ b/packages/wmr/src/lib/plugins.js @@ -46,7 +46,8 @@ export function getPlugins(options) { sourcemap, features, visualize, - autoInstall + autoInstall, + registry } = options; // Plugins are pre-sorted @@ -99,7 +100,7 @@ export function getPlugins(options) { // Only transpile CommonJS in node_modules and explicit .cjs files: include: /(^npm\/|[/\\]node_modules[/\\]|\.cjs$)/ }), - npmPlugin({ cwd, autoInstall, production }), + npmPlugin({ cwd, autoInstall, production, registryUrl: registry }), resolveExtensionsPlugin({ extensions: ['.ts', '.tsx', '.js', '.cjs'], index: true diff --git a/packages/wmr/src/plugins/npm-plugin/index.js b/packages/wmr/src/plugins/npm-plugin/index.js index 20b687d6..36b5d897 100644 --- a/packages/wmr/src/plugins/npm-plugin/index.js +++ b/packages/wmr/src/plugins/npm-plugin/index.js @@ -13,9 +13,10 @@ const log = debug('npm', 196); * @param {string} options.cwd * @param {boolean} options.autoInstall * @param {boolean} options.production + * @param {string} options.registryUrl * @returns {import('rollup').Plugin} */ -export function npmPlugin({ cwd, autoInstall, production }) { +export function npmPlugin({ cwd, autoInstall, production, registryUrl }) { const PREFIX = '\0npm:'; const cacheDir = path.join(cwd, '.cache', '@npm'); @@ -52,7 +53,7 @@ export function npmPlugin({ cwd, autoInstall, production }) { } log(kl.dim(`bundle: `) + kl.cyan(id)); - let result = await npmBundle(id, { autoInstall, production, cacheDir, cwd, resolutionCache }); + let result = await npmBundle(id, { autoInstall, production, cacheDir, cwd, resolutionCache, registryUrl }); await Promise.all( result.output.map(async chunkOrAsset => { diff --git a/packages/wmr/src/plugins/npm-plugin/npm-auto-install.js b/packages/wmr/src/plugins/npm-plugin/npm-auto-install.js index 15dd4dd5..725f6095 100644 --- a/packages/wmr/src/plugins/npm-plugin/npm-auto-install.js +++ b/packages/wmr/src/plugins/npm-plugin/npm-auto-install.js @@ -96,12 +96,10 @@ async function parseTarball(bodyStream, onFile, { include, exclude }) { * prototyping. * @param {object} options * @param {string} options.cacheDir + * @param {string} options.registryUrl * @returns {import('rollup').Plugin} */ -export function npmAutoInstall({ cacheDir }) { - // TODO: Detect from `.npmrc` - const registryUrl = 'https://registry.npmjs.org'; - +export function npmAutoInstall({ cacheDir, registryUrl }) { /** Files that should always be ignored when storing packages */ const FILES_EXCLUDE = /([._-]test\.|__tests?|\/tests?\/|\/node_modules\/|\.d\.ts$)/i; diff --git a/packages/wmr/src/plugins/npm-plugin/npm-bundle.js b/packages/wmr/src/plugins/npm-plugin/npm-bundle.js index 668a2949..f7d71977 100644 --- a/packages/wmr/src/plugins/npm-plugin/npm-bundle.js +++ b/packages/wmr/src/plugins/npm-plugin/npm-bundle.js @@ -29,9 +29,10 @@ function customWarn(warning) { * @param {boolean} options.production * @param {string} options.cacheDir * @param {string} options.cwd + * @param {string} options.registryUrl * @param {Map} options.resolutionCache */ -export async function npmBundle(requestId, { autoInstall, production, cacheDir, cwd, resolutionCache }) { +export async function npmBundle(requestId, { autoInstall, production, cacheDir, cwd, resolutionCache, registryUrl }) { const meta = getPackageInfo(requestId); const pkgName = meta.name; @@ -46,7 +47,7 @@ export async function npmBundle(requestId, { autoInstall, production, cacheDir, browserFieldPlugin({ browserReplacement }), npmExternalDeps({ requestId }), !process.env.DISABLE_LOCAL_NPM && npmLocalPackage({ root: cwd }), - autoInstall && npmAutoInstall({ cacheDir }), + autoInstall && npmAutoInstall({ cacheDir, registryUrl }), npmLoad({ browserReplacement, resolutionCache }), jsonPlugin({ root: cwd }), commonjsPlugin({ production }), diff --git a/packages/wmr/test/npm.test.js b/packages/wmr/test/npm.test.js index 0bb56017..03a185ba 100644 --- a/packages/wmr/test/npm.test.js +++ b/packages/wmr/test/npm.test.js @@ -7,6 +7,7 @@ import { serveStatic, setupTest, teardown, + waitForMessage, waitForPass, withLog } from './test-helpers.js'; @@ -267,6 +268,16 @@ describe('node modules', () => { }); }); + // eslint-disable-next-line jest/expect-expect + it('should fetch package from --registry', async () => { + await loadFixture('npm-auto-install-version', env); + instance = await runWmrFast(env.tmp.path, '--autoInstall', '--registry', 'https://example.com', { + env: { DISABLE_LOCAL_NPM: true } + }); + await getOutput(env, instance); + await waitForMessage(instance.output, /500.*https:\/\/example\.com\/smoldash/); + }); + it('should load CSS from installed package', async () => { await loadFixture('npm-auto-install-css', env); instance = await runWmrFast(env.tmp.path, '--autoInstall', { env: { DISABLE_LOCAL_NPM: true } }); diff --git a/packages/wmr/types.d.ts b/packages/wmr/types.d.ts index c7452a9b..dc0ea2bd 100644 --- a/packages/wmr/types.d.ts +++ b/packages/wmr/types.d.ts @@ -84,6 +84,10 @@ declare module 'wmr' { * This is only intended for quick prototyping. */ autoInstall: boolean; + /** + * NPM registry url to use if `--autoInstall` is enabled + */ + registry: string; } export type BuildError = RollupError & { clientMessage?: string };