mirror of
https://github.com/vuejs/vue-cli.git
synced 2026-01-17 21:00:03 -06:00
407 lines
11 KiB
JavaScript
407 lines
11 KiB
JavaScript
const path = require('path')
|
|
const fs = require('fs-extra')
|
|
const { processStats } = require('./utils/stats')
|
|
|
|
module.exports = api => {
|
|
const { getSharedData, setSharedData, removeSharedData } = api.namespace('org.vue.webpack.')
|
|
|
|
let firstRun = true
|
|
let hadFailed = false
|
|
|
|
// Specific to each modes (serve, build, ...)
|
|
const fields = {
|
|
status: null,
|
|
progress: {},
|
|
operations: null,
|
|
stats: null,
|
|
sizes: null,
|
|
problems: null,
|
|
url: null
|
|
}
|
|
|
|
// Common fields for all mode
|
|
const commonFields = {
|
|
'modern-mode': false
|
|
}
|
|
|
|
// Init data
|
|
api.onProjectOpen(setup)
|
|
api.onPluginReload(setup)
|
|
|
|
function setup () {
|
|
for (const key of ['serve', 'build', 'build-modern']) {
|
|
setupSharedData(key)
|
|
}
|
|
setupCommonData()
|
|
}
|
|
|
|
// Called when opening a project
|
|
function setupSharedData (mode) {
|
|
resetSharedData(mode)
|
|
}
|
|
|
|
// Called when opening a project
|
|
function setupCommonData () {
|
|
for (const field in commonFields) {
|
|
setSharedData(field, getSharedDataInitialValue(field, commonFields[field]))
|
|
}
|
|
}
|
|
|
|
function resetSharedData (mode, clear = false) {
|
|
for (const field in fields) {
|
|
const id = `${mode}-${field}`
|
|
setSharedData(id, getSharedDataInitialValue(id, fields[field], clear))
|
|
}
|
|
}
|
|
|
|
function getSharedDataInitialValue (id, defaultValue, clear) {
|
|
if (!clear) {
|
|
const data = getSharedData(id)
|
|
if (data != null) return data.value
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
async function onWebpackMessage ({ data: message }) {
|
|
if (message.webpackDashboardData) {
|
|
const modernMode = getSharedData('modern-mode').value
|
|
const type = message.webpackDashboardData.type
|
|
|
|
for (const data of message.webpackDashboardData.value) {
|
|
const id = `${type}-${data.type}`
|
|
|
|
if (data.type === 'stats') {
|
|
// Stats are read from a file
|
|
const statsFile = path.resolve(api.getCwd(), `./node_modules/.stats-${type}.json`)
|
|
const value = await fs.readJson(statsFile)
|
|
const { stats, analyzer } = processStats(value)
|
|
setSharedData(id, stats)
|
|
setSharedData(`${id}-analyzer`, analyzer)
|
|
await fs.remove(statsFile)
|
|
} else if (data.type === 'progress') {
|
|
if (type === 'serve' || !modernMode) {
|
|
setSharedData(id, {
|
|
[type]: data.value
|
|
})
|
|
} else {
|
|
// Display two progress bars
|
|
const progress = getSharedData(id).value
|
|
progress[type] = data.value
|
|
for (const t of ['build', 'build-modern']) {
|
|
setSharedData(`${t}-${data.type}`, {
|
|
build: progress.build || 0,
|
|
'build-modern': progress['build-modern'] || 0
|
|
})
|
|
}
|
|
}
|
|
} else {
|
|
// Don't display success until both build and build-modern are done
|
|
if (type !== 'serve' && modernMode && data.type === 'status' && data.value === 'Success') {
|
|
if (type === 'build-modern') {
|
|
for (const t of ['build', 'build-modern']) {
|
|
setSharedData(`${t}-status`, data.value)
|
|
}
|
|
}
|
|
} else {
|
|
setSharedData(id, data.value)
|
|
}
|
|
|
|
// Notifications
|
|
if (type === 'serve' && data.type === 'status') {
|
|
if (data.value === 'Failed') {
|
|
api.notify({
|
|
title: 'Build failed',
|
|
message: 'The build has errors.',
|
|
icon: 'error'
|
|
})
|
|
hadFailed = true
|
|
} else if (data.value === 'Success') {
|
|
if (hadFailed) {
|
|
api.notify({
|
|
title: 'Build fixed',
|
|
message: 'The build succeeded.',
|
|
icon: 'done'
|
|
})
|
|
hadFailed = false
|
|
} else if (firstRun) {
|
|
api.notify({
|
|
title: 'App ready',
|
|
message: 'The build succeeded.',
|
|
icon: 'done'
|
|
})
|
|
firstRun = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Tasks
|
|
const views = {
|
|
views: [
|
|
{
|
|
id: 'org.vue.webpack.views.dashboard',
|
|
label: 'org.vue.vue-webpack.dashboard.title',
|
|
icon: 'dashboard',
|
|
component: 'org.vue.webpack.components.dashboard'
|
|
},
|
|
{
|
|
id: 'org.vue.webpack.views.analyzer',
|
|
label: 'org.vue.vue-webpack.analyzer.title',
|
|
icon: 'donut_large',
|
|
component: 'org.vue.webpack.components.analyzer'
|
|
}
|
|
],
|
|
defaultView: 'org.vue.webpack.views.dashboard'
|
|
}
|
|
api.describeTask({
|
|
match: /vue-cli-service serve(\s+--\S+(\s+\S+)?)*$/,
|
|
description: 'org.vue.vue-webpack.tasks.serve.description',
|
|
link: 'https://cli.vuejs.org/guide/cli-service.html#vue-cli-service-serve',
|
|
icon: '/public/webpack-logo.png',
|
|
prompts: [
|
|
{
|
|
name: 'open',
|
|
type: 'confirm',
|
|
default: false,
|
|
description: 'org.vue.vue-webpack.tasks.serve.open'
|
|
},
|
|
{
|
|
name: 'mode',
|
|
type: 'list',
|
|
default: 'development',
|
|
choices: [
|
|
{
|
|
name: 'development',
|
|
value: 'development'
|
|
},
|
|
{
|
|
name: 'production',
|
|
value: 'production'
|
|
},
|
|
{
|
|
name: 'test',
|
|
value: 'test'
|
|
},
|
|
{
|
|
name: '(unset)',
|
|
value: ''
|
|
}
|
|
],
|
|
description: 'org.vue.vue-webpack.tasks.serve.mode'
|
|
},
|
|
{
|
|
name: 'host',
|
|
type: 'input',
|
|
default: '',
|
|
description: 'org.vue.vue-webpack.tasks.serve.host'
|
|
},
|
|
{
|
|
name: 'port',
|
|
type: 'input',
|
|
default: undefined,
|
|
description: 'org.vue.vue-webpack.tasks.serve.port'
|
|
},
|
|
{
|
|
name: 'https',
|
|
type: 'confirm',
|
|
default: false,
|
|
description: 'org.vue.vue-webpack.tasks.serve.https'
|
|
}
|
|
],
|
|
onBeforeRun: ({ answers, args }) => {
|
|
// Args
|
|
if (answers.open) args.push('--open')
|
|
if (answers.mode) args.push('--mode', answers.mode)
|
|
if (answers.host) args.push('--host', answers.host)
|
|
if (answers.port) args.push('--port', answers.port)
|
|
if (answers.https) args.push('--https')
|
|
args.push('--dashboard')
|
|
|
|
// Data
|
|
resetSharedData('serve', true)
|
|
firstRun = true
|
|
hadFailed = false
|
|
},
|
|
onRun: () => {
|
|
api.ipcOn(onWebpackMessage)
|
|
},
|
|
onExit: () => {
|
|
api.ipcOff(onWebpackMessage)
|
|
removeSharedData('serve-url')
|
|
},
|
|
...views
|
|
})
|
|
api.describeTask({
|
|
match: /vue-cli-service build(\s+--\S+(\s+\S+)?)*$/,
|
|
description: 'org.vue.vue-webpack.tasks.build.description',
|
|
link: 'https://cli.vuejs.org/guide/cli-service.html#vue-cli-service-build',
|
|
icon: '/public/webpack-logo.png',
|
|
prompts: [
|
|
{
|
|
name: 'modern',
|
|
type: 'confirm',
|
|
default: false,
|
|
message: 'org.vue.vue-webpack.tasks.build.modern.label',
|
|
description: 'org.vue.vue-webpack.tasks.build.modern.description',
|
|
link: 'https://cli.vuejs.org/guide/browser-compatibility.html#modern-mode'
|
|
},
|
|
{
|
|
name: 'mode',
|
|
type: 'list',
|
|
default: 'production',
|
|
choices: [
|
|
{
|
|
name: 'development',
|
|
value: 'development'
|
|
},
|
|
{
|
|
name: 'production',
|
|
value: 'production'
|
|
},
|
|
{
|
|
name: 'test',
|
|
value: 'test'
|
|
},
|
|
{
|
|
name: '(unset)',
|
|
value: ''
|
|
}
|
|
],
|
|
description: 'org.vue.vue-webpack.tasks.build.mode'
|
|
},
|
|
{
|
|
name: 'dest',
|
|
type: 'input',
|
|
default: 'dist',
|
|
description: 'org.vue.vue-webpack.tasks.build.dest'
|
|
},
|
|
{
|
|
name: 'target',
|
|
type: 'list',
|
|
default: 'app',
|
|
choices: [
|
|
{
|
|
name: 'org.vue.vue-webpack.tasks.build.target.app',
|
|
value: 'app'
|
|
},
|
|
{
|
|
name: 'org.vue.vue-webpack.tasks.build.target.lib',
|
|
value: 'lib'
|
|
},
|
|
{
|
|
name: 'org.vue.vue-webpack.tasks.build.target.wc',
|
|
value: 'wc'
|
|
},
|
|
{
|
|
name: 'org.vue.vue-webpack.tasks.build.target.wc-async',
|
|
value: 'wc-async'
|
|
}
|
|
],
|
|
description: 'org.vue.vue-webpack.tasks.build.target.description'
|
|
},
|
|
{
|
|
name: 'name',
|
|
type: 'input',
|
|
default: '',
|
|
description: 'org.vue.vue-webpack.tasks.build.name'
|
|
},
|
|
{
|
|
name: 'watch',
|
|
type: 'confirm',
|
|
default: false,
|
|
description: 'org.vue.vue-webpack.tasks.build.watch'
|
|
}
|
|
],
|
|
onBeforeRun: ({ answers, args }) => {
|
|
// Args
|
|
if (answers.mode) args.push('--mode', answers.mode)
|
|
if (answers.dest) args.push('--dest', answers.dest)
|
|
if (answers.target) args.push('--target', answers.target)
|
|
if (answers.name) args.push('--name', answers.name)
|
|
if (answers.watch) args.push('--watch')
|
|
if (answers.modern) args.push('--modern')
|
|
setSharedData('modern-mode', !!answers.modern)
|
|
args.push('--dashboard')
|
|
|
|
// Data
|
|
resetSharedData('build', true)
|
|
resetSharedData('build-modern', true)
|
|
},
|
|
onRun: () => {
|
|
api.ipcOn(onWebpackMessage)
|
|
},
|
|
onExit: () => {
|
|
api.ipcOff(onWebpackMessage)
|
|
},
|
|
...views
|
|
})
|
|
// vue inspect
|
|
api.addTask({
|
|
name: 'inspect',
|
|
command: 'vue-cli-service inspect',
|
|
description: 'org.vue.vue-webpack.tasks.inspect.description',
|
|
link: 'https://cli.vuejs.org/guide/webpack.html#inspecting-the-project-s-webpack-config',
|
|
icon: '/public/webpack-inspect-logo.png',
|
|
prompts: [
|
|
{
|
|
name: 'mode',
|
|
type: 'list',
|
|
default: 'production',
|
|
choices: [
|
|
{
|
|
name: 'development',
|
|
value: 'development'
|
|
},
|
|
{
|
|
name: 'production',
|
|
value: 'production'
|
|
},
|
|
{
|
|
name: 'test',
|
|
value: 'test'
|
|
},
|
|
{
|
|
name: '(unset)',
|
|
value: ''
|
|
}
|
|
],
|
|
description: 'org.vue.vue-webpack.tasks.inspect.mode'
|
|
},
|
|
{
|
|
name: 'verbose',
|
|
type: 'confirm',
|
|
default: false,
|
|
description: 'org.vue.vue-webpack.tasks.inspect.verbose'
|
|
}
|
|
],
|
|
onBeforeRun: ({ answers, args }) => {
|
|
if (answers.mode) args.push('--mode', answers.mode)
|
|
if (answers.verbose) args.push('--verbose')
|
|
}
|
|
})
|
|
|
|
if (process.env.VUE_APP_CLI_UI_DEV) {
|
|
// Add dynamic components in dev mode (webpack dashboard & analyzer)
|
|
api.addClientAddon({
|
|
id: 'org.vue.webpack.client-addon.dev',
|
|
url: 'http://localhost:8096/index.js'
|
|
})
|
|
} else {
|
|
// Webpack dashboard
|
|
api.addClientAddon({
|
|
id: 'org.vue.webpack.client-addon',
|
|
path: '@vue/cli-ui-addon-webpack/dist'
|
|
})
|
|
}
|
|
|
|
// Open app button
|
|
api.ipcOn(({ data }) => {
|
|
if (data.vueServe) {
|
|
setSharedData('serve-url', data.vueServe.url)
|
|
}
|
|
})
|
|
}
|