UNPKG

@nuxt/cli-edge

Version:
633 lines (607 loc) • 18.3 kB
/*! * @nuxt/cli-edge v2.18.2-28661769.e265ef3 (c) 2016-2024 * Released under the MIT License * Repository: https://github.com/nuxt/nuxt.js * Website: https://nuxtjs.org */ 'use strict'; const utilsEdge = require('@nuxt/utils-edge'); const configEdge = require('@nuxt/config-edge'); const path = require('path'); const exit = require('exit'); const chalk = require('chalk'); const stdEnv = require('std-env'); const wrapAnsi = require('wrap-ansi'); const boxen = require('boxen'); const consola = require('consola'); const minimist = require('minimist'); const Hookable = require('hookable'); const defu = require('defu'); const semver = require('semver'); const fs = require('fs'); const execa = require('execa'); const commands = { start: () => Promise.resolve().then(function () { return require('./cli-start.js'); }), serve: () => Promise.resolve().then(function () { return require('./cli-serve.js'); }), dev: () => Promise.resolve().then(function () { return require('./cli-dev.js'); }), build: () => Promise.resolve().then(function () { return require('./cli-build.js'); }), generate: () => Promise.resolve().then(function () { return require('./cli-generate.js'); }), export: () => Promise.resolve().then(function () { return require('./cli-export.js'); }), webpack: () => Promise.resolve().then(function () { return require('./cli-webpack.js'); }), help: () => Promise.resolve().then(function () { return require('./cli-help.js'); }) }; function getCommand(name) { if (!commands[name]) { return Promise.resolve(null); } return commands[name]().then((m) => m.default); } const index$1 = /*#__PURE__*/Object.freeze({ __proto__: null, default: getCommand }); const importModule = (id) => { try { return Promise.resolve(utilsEdge.requireModule(id)); } catch (err) { if (err.code === "MODULE_NOT_FOUND") { err.message = `Cannot import module '${id}'`; } return Promise.reject(err); } }; const builder = () => importModule("@nuxt/builder-edge"); const webpack = () => importModule("@nuxt/webpack-edge"); const generator = () => importModule("@nuxt/generator-edge"); const core = () => importModule("@nuxt/core-edge"); const server$1 = () => importModule("@nuxt/server-edge"); const imports = /*#__PURE__*/Object.freeze({ __proto__: null, builder: builder, core: core, generator: generator, importModule: importModule, server: server$1, webpack: webpack }); const forceExitTimeout = 5; const startSpaces = 2; const optionSpaces = 2; const maxCharsPerLine = () => (process.stdout.columns || 100) * 80 / 100; function indent(count, chr = " ") { return chr.repeat(count); } function indentLines(string, spaces, firstLineSpaces) { const lines = Array.isArray(string) ? string : string.split("\n"); let s = ""; if (lines.length) { const i0 = indent(firstLineSpaces === void 0 ? spaces : firstLineSpaces); s = i0 + lines.shift(); } if (lines.length) { const i = indent(spaces); s += "\n" + lines.map((l) => i + l).join("\n"); } return s; } function foldLines(string, spaces, firstLineSpaces, charsPerLine = maxCharsPerLine()) { return indentLines(wrapAnsi(string, charsPerLine), spaces, firstLineSpaces); } function colorize(text) { return text.replace(/\[[^ ]+]/g, (m) => chalk.grey(m)).replace(/<[^ ]+>/g, (m) => chalk.green(m)).replace(/ (-[-\w,]+)/g, (m) => chalk.bold(m)).replace(/`([^`]+)`/g, (_, m) => chalk.bold.cyan(m)); } function box(message, title, options) { return boxen([ title || chalk.white("Nuxt Message"), "", chalk.white(foldLines(message, 0, 0, maxCharsPerLine())) ].join("\n"), Object.assign({ borderColor: "white", borderStyle: "round", padding: 1, margin: 1 }, options)) + "\n"; } function successBox(message, title) { return box(message, title || chalk.green("\u2714 Nuxt Success"), { borderColor: "green" }); } function warningBox(message, title) { return box(message, chalk.yellow("\u26A0 Nuxt Warning"), { borderColor: "yellow" }); } function errorBox(message, title) { return box(message, title || chalk.red("\u2716 Nuxt Error"), { borderColor: "red" }); } function fatalBox(message, title) { return errorBox(message, chalk.red("\u2716 Nuxt Fatal Error")); } const eventsMapping = { add: { icon: "+", color: "green", action: "Created" }, change: { icon: stdEnv.isWindows ? "\xBB" : "\u21BB", color: "blue", action: "Updated" }, unlink: { icon: "-", color: "red", action: "Removed" } }; function formatPath(filePath) { if (!filePath) { return; } return filePath.replace(process.cwd() + path.sep, ""); } function normalizeArg(arg, defaultValue) { switch (arg) { case "true": arg = true; break; case "": arg = true; break; case "false": arg = false; break; case void 0: arg = defaultValue; break; } return arg; } function forceExit(cmdName, timeout) { if (timeout !== false) { const exitTimeout = setTimeout(() => { const msg = `The command 'nuxt ${cmdName}' finished but did not exit after ${timeout}s This is most likely not caused by a bug in Nuxt Make sure to cleanup all timers and listeners you or your plugins/modules start. Nuxt will now force exit ${chalk.bold("DeprecationWarning: Starting with Nuxt version 3 this will be a fatal error")}`; process.stderr.write(warningBox(msg)); exit(0); }, timeout * 1e3); exitTimeout.unref(); } else { exit(0); } } function createLock(...args) { return utilsEdge.lock(...args); } const common = { spa: { alias: "s", type: "boolean", description: "Launch in SPA mode" }, universal: { alias: "u", type: "boolean", description: "Launch in Universal mode (default)" }, "config-file": { alias: "c", type: "string", default: configEdge.defaultNuxtConfigFile, description: `Path to Nuxt config file (default: \`${configEdge.defaultNuxtConfigFile}\`)` }, modern: { alias: "m", type: "string", description: "Build/Start app for modern browsers, e.g. server, client and false", prepare(cmd, options, argv) { if (argv.modern !== void 0) { options.modern = normalizeArg(argv.modern); } } }, target: { alias: "t", type: "string", description: "Build/start app for a different target, e.g. server, serverless and static", prepare(cmd, options, argv) { if (argv.target) { options.target = argv.target; } } }, "force-exit": { type: "boolean", default(cmd) { return ["build", "generate", "export"].includes(cmd.name); }, description: "Whether Nuxt should force exit after the command has finished" }, version: { alias: "v", type: "boolean", description: "Display the Nuxt version" }, help: { alias: "h", type: "boolean", description: "Display this message" }, processenv: { type: "boolean", default: true, description: "Disable reading from `process.env` and updating it with dotenv" }, dotenv: { type: "string", default: ".env", description: "Specify path to dotenv file (default: `.env`). Use `false` to disable" } }; const server = { port: { alias: "p", type: "string", description: "Port number on which to start the application", prepare(cmd, options, argv) { if (argv.port) { options.server.port = +argv.port; } } }, hostname: { alias: "H", type: "string", description: "Hostname on which to start the application", prepare(cmd, options, argv) { if (argv.hostname === "") { consola.fatal("Provided hostname argument has no value"); } } }, "unix-socket": { alias: "n", type: "string", description: "Path to a UNIX socket" } }; const locking = { lock: { type: "boolean", default: true, description: "Do not set a lock on the project when building" } }; const index = /*#__PURE__*/Object.freeze({ __proto__: null, common: common, locking: locking, server: server }); var name = "@nuxt/cli-edge"; var version = "2.18.2-28661769.e265ef3"; async function loadNuxtConfig(argv, configContext) { const rootDir = path.resolve(argv._[0] || "."); const configFile = argv["config-file"]; const options = await configEdge.loadNuxtConfig({ rootDir, configFile, configContext, envConfig: { dotenv: argv.dotenv === "false" ? false : argv.dotenv, env: argv.processenv ? process.env : {} } }); if (argv.spa === true) { options.ssr = false; } else if (argv.universal === true) { options.ssr = true; } options.server = defu.defu({ port: argv.port || null, host: argv.hostname || null, socket: argv["unix-socket"] || null }, options.server || {}, configEdge.getDefaultNuxtConfig().server); return options; } class NuxtCommand extends Hookable { constructor(cmd = { name: "", usage: "", description: "" }, argv = process.argv.slice(2), hooks = {}) { super(consola); this.addHooks(hooks); if (!cmd.options) { cmd.options = {}; } this.cmd = cmd; this._argv = Array.from(argv); this._parsedArgv = null; } static run(cmd, argv, hooks) { return NuxtCommand.from(cmd, argv, hooks).run(); } static from(cmd, argv, hooks) { if (cmd instanceof NuxtCommand) { return cmd; } return new NuxtCommand(cmd, argv, hooks); } async run() { await this.callHook("run:before", { argv: this._argv, cmd: this.cmd, rootDir: path.resolve(this.argv._[0] || ".") }); if (this.argv.help) { this.showHelp(); return; } if (this.argv.version) { this.showVersion(); return; } if (typeof this.cmd.run !== "function") { throw new TypeError("Invalid command! Commands should at least implement run() function."); } let cmdError; try { await this.cmd.run(this); } catch (e) { cmdError = e; } if (this.argv.lock) { await this.releaseLock(); } if (this.argv["force-exit"]) { const forceExitByUser = this.isUserSuppliedArg("force-exit"); if (cmdError) { consola.fatal(cmdError); } forceExit(this.cmd.name, forceExitByUser ? false : forceExitTimeout); if (forceExitByUser) { return; } } if (cmdError) { throw cmdError; } } showVersion() { process.stdout.write(`${name} v${version} `); } showHelp() { process.stdout.write(this._getHelp()); } get argv() { if (!this._parsedArgv) { const minimistOptions = this._getMinimistOptions(); this._parsedArgv = minimist(this._argv, minimistOptions); } return this._parsedArgv; } async getNuxtConfig(extraOptions = {}) { extraOptions._cli = true; const context = { command: this.cmd.name, dev: !!extraOptions.dev }; const config = await loadNuxtConfig(this.argv, context); const options = Object.assign(config, extraOptions); for (const name2 of Object.keys(this.cmd.options)) { this.cmd.options[name2].prepare && this.cmd.options[name2].prepare(this, options, this.argv); } await this.callHook("config", options); return options; } async getNuxt(options) { const { Nuxt } = await core(); const nuxt = new Nuxt(options); await nuxt.ready(); return nuxt; } async getBuilder(nuxt) { const { Builder } = await builder(); const { BundleBuilder } = await webpack(); return new Builder(nuxt, BundleBuilder); } async getGenerator(nuxt) { const { Generator } = await generator(); const builder = await this.getBuilder(nuxt); return new Generator(nuxt, builder); } async setLock(lockRelease) { if (lockRelease) { if (this._lockRelease) { consola.warn(`A previous unreleased lock was found, this shouldn't happen and is probably an error in 'nuxt ${this.cmd.name}' command. The lock will be removed but be aware of potential strange results`); await this.releaseLock(); this._lockRelease = lockRelease; } else { this._lockRelease = lockRelease; } } } async releaseLock() { if (this._lockRelease) { await this._lockRelease(); this._lockRelease = void 0; } } isUserSuppliedArg(option) { return this._argv.includes(`--${option}`) || this._argv.includes(`--no-${option}`); } _getDefaultOptionValue(option) { return typeof option.default === "function" ? option.default(this.cmd) : option.default; } _getMinimistOptions() { const minimistOptions = { alias: {}, boolean: [], string: [], default: {} }; for (const name2 of Object.keys(this.cmd.options)) { const option = this.cmd.options[name2]; if (option.alias) { minimistOptions.alias[option.alias] = name2; } if (option.type) { minimistOptions[option.type].push(option.alias || name2); } if (option.default) { minimistOptions.default[option.alias || name2] = this._getDefaultOptionValue(option); } } return minimistOptions; } _getHelp() { const options = []; let maxOptionLength = 0; for (const name2 in this.cmd.options) { const option = this.cmd.options[name2]; let optionHelp = "--"; optionHelp += option.type === "boolean" && this._getDefaultOptionValue(option) ? "no-" : ""; optionHelp += name2; if (option.alias) { optionHelp += `, -${option.alias}`; } maxOptionLength = Math.max(maxOptionLength, optionHelp.length); options.push([optionHelp, option.description]); } const _opts = options.map(([option, description2]) => { const i = indent(maxOptionLength + optionSpaces - option.length); return foldLines( option + i + description2, startSpaces + maxOptionLength + optionSpaces * 2, startSpaces + optionSpaces ); }).join("\n"); const usage = foldLines(`Usage: nuxt ${this.cmd.usage} [options]`, startSpaces); const description = foldLines(this.cmd.description, startSpaces); const opts = foldLines("Options:", startSpaces) + "\n\n" + _opts; let helpText = colorize(`${usage} `); if (this.cmd.description) { helpText += colorize(`${description} `); } if (options.length) { helpText += colorize(`${opts} `); } return helpText; } } const dependencies = { webpack: "^4.46.0", "css-loader": ">=4.2.0", "sass-loader": "^10.4.1" }; const nodeVersion = ">=14.18.0"; function getInstalledVersion(name) { try { return utilsEdge.getPKG(name).version; } catch { } } function checkDependencies() { for (const name in dependencies) { const installedVersion = getInstalledVersion(name); if (!installedVersion) { continue; } const expectedRange = dependencies[name]; if (!semver.satisfies(installedVersion, expectedRange)) { consola.warn(`${name}@${installedVersion} is installed but ${expectedRange} is expected`); } } if (!semver.satisfies(process.version, nodeVersion)) { consola.warn(`You are using an unsupported version of Node.js (${process.version}). It is recommended to use the latest LTS version (https://nodejs.org/en/about/releases)`); } } let _setup = false; function setup({ dev }) { if (!process.env.NODE_ENV) { process.env.NODE_ENV = dev ? "development" : "production"; } if (_setup) { return; } _setup = true; checkDependencies(); process.on("unhandledRejection", (err) => { consola.error(err); }); consola.addReporter({ log(logObj) { if (logObj.type === "fatal") { const errorMessage = String(logObj.args[0]); process.stderr.write(fatalBox(errorMessage)); exit(1); } } }); consola.wrapConsole(); } function isNuxtDir(rootDir) { if (fs.existsSync(path.join(rootDir, "nuxt.config.js")) || fs.existsSync(path.join(rootDir, "pages")) || fs.existsSync(path.join(rootDir, "nuxt.config.ts"))) { return true; } return false; } async function run(_argv, hooks = {}) { const dupPkg = "cli" ; const dupPkgJSON = path.resolve(__dirname, "../..", dupPkg, "package.json"); if (fs.existsSync(dupPkgJSON) && utilsEdge.requireModule(dupPkgJSON).name !== "@nuxt/" + dupPkg) { consola.warn("Both `nuxt` and `nuxt-edge` dependencies are installed! Please choose one and remove the other one from dependencies."); } const argv = _argv ? Array.from(_argv) : process.argv.slice(2); let cmd = await getCommand(argv[0]); if (!cmd && (!argv[0] || argv[0][0] === "-" || isNuxtDir(argv[0]))) { argv.unshift("dev"); cmd = await getCommand("dev"); } const dev = argv[0] === "dev"; setup({ dev }); if (cmd) { return NuxtCommand.run(cmd, argv.slice(1), hooks); } try { await execa(`nuxt-${argv[0]}`, argv.slice(1), { stdout: process.stdout, stderr: process.stderr, stdin: process.stdin }); } catch (error) { if (error.exitCode === 2) { throw String(`Command not found: nuxt-${argv[0]}`); } throw String(`Failed to run command \`nuxt-${argv[0]}\`: ${error}`); } } async function getWebpackConfig(name = "client", loadOptions = {}) { const { loadNuxt } = await core(); const { getBuilder } = await builder(); const nuxt = await loadNuxt(loadOptions); const builder$1 = await getBuilder(nuxt); const { bundleBuilder } = builder$1; return bundleBuilder.getWebpackConfig(name); } exports.NuxtCommand = NuxtCommand; exports.colorize = colorize; exports.common = common; exports.core = core; exports.createLock = createLock; exports.eventsMapping = eventsMapping; exports.foldLines = foldLines; exports.formatPath = formatPath; exports.getCommand = getCommand; exports.getWebpackConfig = getWebpackConfig; exports.imports = imports; exports.indent = indent; exports.index = index$1; exports.index$1 = index; exports.isNuxtDir = isNuxtDir; exports.loadNuxtConfig = loadNuxtConfig; exports.locking = locking; exports.normalizeArg = normalizeArg; exports.optionSpaces = optionSpaces; exports.run = run; exports.server = server$1; exports.server$1 = server; exports.setup = setup; exports.startSpaces = startSpaces; exports.successBox = successBox;