Spaces:
Sleeping
Sleeping
| const path = require('path') | |
| const hash = require('hash-sum') | |
| const { semver, matchesPluginId } = require('@vue/cli-shared-utils') | |
| // Note: if a plugin-registered command needs to run in a specific default mode, | |
| // the plugin needs to expose it via `module.exports.defaultModes` in the form | |
| // of { [commandName]: mode }. This is because the command mode needs to be | |
| // known and applied before loading user options / applying plugins. | |
| class PluginAPI { | |
| /** | |
| * @param {string} id - Id of the plugin. | |
| * @param {Service} service - A vue-cli-service instance. | |
| */ | |
| constructor (id, service) { | |
| this.id = id | |
| this.service = service | |
| } | |
| get version () { | |
| return require('../package.json').version | |
| } | |
| assertVersion (range) { | |
| if (typeof range === 'number') { | |
| if (!Number.isInteger(range)) { | |
| throw new Error('Expected string or integer value.') | |
| } | |
| range = `^${range}.0.0-0` | |
| } | |
| if (typeof range !== 'string') { | |
| throw new Error('Expected string or integer value.') | |
| } | |
| if (semver.satisfies(this.version, range, { includePrerelease: true })) return | |
| throw new Error( | |
| `Require @vue/cli-service "${range}", but was loaded with "${this.version}".` | |
| ) | |
| } | |
| /** | |
| * Current working directory. | |
| */ | |
| getCwd () { | |
| return this.service.context | |
| } | |
| /** | |
| * Resolve path for a project. | |
| * | |
| * @param {string} _path - Relative path from project root | |
| * @return {string} The resolved absolute path. | |
| */ | |
| resolve (_path) { | |
| return path.resolve(this.service.context, _path) | |
| } | |
| /** | |
| * Check if the project has a given plugin. | |
| * | |
| * @param {string} id - Plugin id, can omit the (@vue/|vue-|@scope/vue)-cli-plugin- prefix | |
| * @return {boolean} | |
| */ | |
| hasPlugin (id) { | |
| return this.service.plugins.some(p => matchesPluginId(id, p.id)) | |
| } | |
| /** | |
| * Register a command that will become available as `vue-cli-service [name]`. | |
| * | |
| * @param {string} name | |
| * @param {object} [opts] | |
| * { | |
| * description: string, | |
| * usage: string, | |
| * options: { [string]: string } | |
| * } | |
| * @param {function} fn | |
| * (args: { [string]: string }, rawArgs: string[]) => ?Promise | |
| */ | |
| registerCommand (name, opts, fn) { | |
| if (typeof opts === 'function') { | |
| fn = opts | |
| opts = null | |
| } | |
| this.service.commands[name] = { fn, opts: opts || {}} | |
| } | |
| /** | |
| * Register a function that will receive a chainable webpack config | |
| * the function is lazy and won't be called until `resolveWebpackConfig` is | |
| * called | |
| * | |
| * @param {function} fn | |
| */ | |
| chainWebpack (fn) { | |
| this.service.webpackChainFns.push(fn) | |
| } | |
| /** | |
| * Register | |
| * - a webpack configuration object that will be merged into the config | |
| * OR | |
| * - a function that will receive the raw webpack config. | |
| * the function can either mutate the config directly or return an object | |
| * that will be merged into the config. | |
| * | |
| * @param {object | function} fn | |
| */ | |
| configureWebpack (fn) { | |
| this.service.webpackRawConfigFns.push(fn) | |
| } | |
| /** | |
| * Register a dev serve config function. It will receive the express `app` | |
| * instance of the dev server. | |
| * | |
| * @param {function} fn | |
| */ | |
| configureDevServer (fn) { | |
| this.service.devServerConfigFns.push(fn) | |
| } | |
| /** | |
| * Resolve the final raw webpack config, that will be passed to webpack. | |
| * | |
| * @param {ChainableWebpackConfig} [chainableConfig] | |
| * @return {object} Raw webpack config. | |
| */ | |
| resolveWebpackConfig (chainableConfig) { | |
| return this.service.resolveWebpackConfig(chainableConfig) | |
| } | |
| /** | |
| * Resolve an intermediate chainable webpack config instance, which can be | |
| * further tweaked before generating the final raw webpack config. | |
| * You can call this multiple times to generate different branches of the | |
| * base webpack config. | |
| * See https://github.com/mozilla-neutrino/webpack-chain | |
| * | |
| * @return {ChainableWebpackConfig} | |
| */ | |
| resolveChainableWebpackConfig () { | |
| return this.service.resolveChainableWebpackConfig() | |
| } | |
| /** | |
| * Generate a cache identifier from a number of variables | |
| */ | |
| genCacheConfig (id, partialIdentifier, configFiles = []) { | |
| const fs = require('fs') | |
| const cacheDirectory = this.resolve(`node_modules/.cache/${id}`) | |
| // replace \r\n to \n generate consistent hash | |
| const fmtFunc = conf => { | |
| if (typeof conf === 'function') { | |
| return conf.toString().replace(/\r\n?/g, '\n') | |
| } | |
| return conf | |
| } | |
| const variables = { | |
| partialIdentifier, | |
| 'cli-service': require('../package.json').version, | |
| 'cache-loader': require('cache-loader/package.json').version, | |
| env: process.env.NODE_ENV, | |
| test: !!process.env.VUE_CLI_TEST, | |
| config: [ | |
| fmtFunc(this.service.projectOptions.chainWebpack), | |
| fmtFunc(this.service.projectOptions.configureWebpack) | |
| ] | |
| } | |
| if (!Array.isArray(configFiles)) { | |
| configFiles = [configFiles] | |
| } | |
| configFiles = configFiles.concat([ | |
| 'package-lock.json', | |
| 'yarn.lock', | |
| 'pnpm-lock.yaml' | |
| ]) | |
| const readConfig = file => { | |
| const absolutePath = this.resolve(file) | |
| if (!fs.existsSync(absolutePath)) { | |
| return | |
| } | |
| if (absolutePath.endsWith('.js')) { | |
| // should evaluate config scripts to reflect environment variable changes | |
| try { | |
| return JSON.stringify(require(absolutePath)) | |
| } catch (e) { | |
| return fs.readFileSync(absolutePath, 'utf-8') | |
| } | |
| } else { | |
| return fs.readFileSync(absolutePath, 'utf-8') | |
| } | |
| } | |
| variables.configFiles = configFiles.map(file => { | |
| const content = readConfig(file) | |
| return content && content.replace(/\r\n?/g, '\n') | |
| }) | |
| const cacheIdentifier = hash(variables) | |
| return { cacheDirectory, cacheIdentifier } | |
| } | |
| } | |
| module.exports = PluginAPI | |