parent
2ee3359d3c
commit
f68e450ffe
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"comments": false,
|
||||||
|
"env": {
|
||||||
|
"main": {
|
||||||
|
"presets": [
|
||||||
|
["env", {
|
||||||
|
"targets": { "node": 7 }
|
||||||
|
}],
|
||||||
|
"stage-0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"renderer": {
|
||||||
|
"presets": [
|
||||||
|
["env", {
|
||||||
|
"modules": false
|
||||||
|
}],
|
||||||
|
"stage-0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"web": {
|
||||||
|
"presets": [
|
||||||
|
["env", {
|
||||||
|
"modules": false
|
||||||
|
}],
|
||||||
|
"stage-0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"plugins": ["transform-runtime"]
|
||||||
|
}
|
@ -0,0 +1,132 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
process.env.NODE_ENV = 'production'
|
||||||
|
|
||||||
|
const { say } = require('cfonts')
|
||||||
|
const chalk = require('chalk')
|
||||||
|
const del = require('del')
|
||||||
|
const { spawn } = require('child_process')
|
||||||
|
const webpack = require('webpack')
|
||||||
|
const Multispinner = require('multispinner')
|
||||||
|
|
||||||
|
|
||||||
|
const mainConfig = require('./webpack.main.config')
|
||||||
|
const rendererConfig = require('./webpack.renderer.config')
|
||||||
|
const webConfig = require('./webpack.web.config')
|
||||||
|
|
||||||
|
const doneLog = chalk.bgGreen.white(' DONE ') + ' '
|
||||||
|
const errorLog = chalk.bgRed.white(' ERROR ') + ' '
|
||||||
|
const okayLog = chalk.bgBlue.white(' OKAY ') + ' '
|
||||||
|
const isCI = process.env.CI || false
|
||||||
|
|
||||||
|
if (process.env.BUILD_TARGET === 'clean') clean()
|
||||||
|
else if (process.env.BUILD_TARGET === 'web') web()
|
||||||
|
else build()
|
||||||
|
|
||||||
|
function clean () {
|
||||||
|
del.sync(['build/*', '!build/icons', '!build/icons/icon.*'])
|
||||||
|
console.log(`\n${doneLog}\n`)
|
||||||
|
process.exit()
|
||||||
|
}
|
||||||
|
|
||||||
|
function build () {
|
||||||
|
greeting()
|
||||||
|
|
||||||
|
del.sync(['dist/electron/*', '!.gitkeep'])
|
||||||
|
|
||||||
|
const tasks = ['main', 'renderer']
|
||||||
|
const m = new Multispinner(tasks, {
|
||||||
|
preText: 'building',
|
||||||
|
postText: 'process'
|
||||||
|
})
|
||||||
|
|
||||||
|
let results = ''
|
||||||
|
|
||||||
|
m.on('success', () => {
|
||||||
|
process.stdout.write('\x1B[2J\x1B[0f')
|
||||||
|
console.log(`\n\n${results}`)
|
||||||
|
console.log(`${okayLog}take it away ${chalk.yellow('`electron-builder`')}\n`)
|
||||||
|
process.exit()
|
||||||
|
})
|
||||||
|
|
||||||
|
pack(mainConfig).then(result => {
|
||||||
|
results += result + '\n\n'
|
||||||
|
m.success('main')
|
||||||
|
}).catch(err => {
|
||||||
|
m.error('main')
|
||||||
|
console.log(`\n ${errorLog}failed to build main process`)
|
||||||
|
console.error(`\n${err}\n`)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
pack(rendererConfig).then(result => {
|
||||||
|
results += result + '\n\n'
|
||||||
|
m.success('renderer')
|
||||||
|
}).catch(err => {
|
||||||
|
m.error('renderer')
|
||||||
|
console.log(`\n ${errorLog}failed to build renderer process`)
|
||||||
|
console.error(`\n${err}\n`)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function pack (config) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
config.mode = 'production'
|
||||||
|
webpack(config, (err, stats) => {
|
||||||
|
if (err) reject(err.stack || err)
|
||||||
|
else if (stats.hasErrors()) {
|
||||||
|
let err = ''
|
||||||
|
|
||||||
|
stats.toString({
|
||||||
|
chunks: false,
|
||||||
|
colors: true
|
||||||
|
})
|
||||||
|
.split(/\r?\n/)
|
||||||
|
.forEach(line => {
|
||||||
|
err += ` ${line}\n`
|
||||||
|
})
|
||||||
|
|
||||||
|
reject(err)
|
||||||
|
} else {
|
||||||
|
resolve(stats.toString({
|
||||||
|
chunks: false,
|
||||||
|
colors: true
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function web () {
|
||||||
|
del.sync(['dist/web/*', '!.gitkeep'])
|
||||||
|
webConfig.mode = 'production'
|
||||||
|
webpack(webConfig, (err, stats) => {
|
||||||
|
if (err || stats.hasErrors()) console.log(err)
|
||||||
|
|
||||||
|
console.log(stats.toString({
|
||||||
|
chunks: false,
|
||||||
|
colors: true
|
||||||
|
}))
|
||||||
|
|
||||||
|
process.exit()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function greeting () {
|
||||||
|
const cols = process.stdout.columns
|
||||||
|
let text = ''
|
||||||
|
|
||||||
|
if (cols > 85) text = 'lets-build'
|
||||||
|
else if (cols > 60) text = 'lets-|build'
|
||||||
|
else text = false
|
||||||
|
|
||||||
|
if (text && !isCI) {
|
||||||
|
say(text, {
|
||||||
|
colors: ['yellow'],
|
||||||
|
font: 'simple3d',
|
||||||
|
space: false
|
||||||
|
})
|
||||||
|
} else console.log(chalk.yellow.bold('\n lets-build'))
|
||||||
|
console.log()
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
const hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
|
||||||
|
|
||||||
|
hotClient.subscribe(event => {
|
||||||
|
/**
|
||||||
|
* Reload browser when HTMLWebpackPlugin emits a new index.html
|
||||||
|
*
|
||||||
|
* Currently disabled until jantimon/html-webpack-plugin#680 is resolved.
|
||||||
|
* https://github.com/SimulatedGREG/electron-vue/issues/437
|
||||||
|
* https://github.com/jantimon/html-webpack-plugin/issues/680
|
||||||
|
*/
|
||||||
|
// if (event.action === 'reload') {
|
||||||
|
// window.location.reload()
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify `mainWindow` when `main` process is compiling,
|
||||||
|
* giving notice for an expected reload of the `electron` process
|
||||||
|
*/
|
||||||
|
if (event.action === 'compiling') {
|
||||||
|
document.body.innerHTML += `
|
||||||
|
<style>
|
||||||
|
#dev-client {
|
||||||
|
background: #4fc08d;
|
||||||
|
border-radius: 4px;
|
||||||
|
bottom: 20px;
|
||||||
|
box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.3);
|
||||||
|
color: #fff;
|
||||||
|
font-family: 'Source Sans Pro', sans-serif;
|
||||||
|
left: 20px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="dev-client">
|
||||||
|
Compiling Main Process...
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,190 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
const chalk = require('chalk')
|
||||||
|
const electron = require('electron')
|
||||||
|
const path = require('path')
|
||||||
|
const { say } = require('cfonts')
|
||||||
|
const { spawn } = require('child_process')
|
||||||
|
const webpack = require('webpack')
|
||||||
|
const WebpackDevServer = require('webpack-dev-server')
|
||||||
|
const webpackHotMiddleware = require('webpack-hot-middleware')
|
||||||
|
|
||||||
|
const mainConfig = require('./webpack.main.config')
|
||||||
|
const rendererConfig = require('./webpack.renderer.config')
|
||||||
|
|
||||||
|
let electronProcess = null
|
||||||
|
let manualRestart = false
|
||||||
|
let hotMiddleware
|
||||||
|
|
||||||
|
function logStats (proc, data) {
|
||||||
|
let log = ''
|
||||||
|
|
||||||
|
log += chalk.yellow.bold(`┏ ${proc} Process ${new Array((19 - proc.length) + 1).join('-')}`)
|
||||||
|
log += '\n\n'
|
||||||
|
|
||||||
|
if (typeof data === 'object') {
|
||||||
|
data.toString({
|
||||||
|
colors: true,
|
||||||
|
chunks: false
|
||||||
|
}).split(/\r?\n/).forEach(line => {
|
||||||
|
log += ' ' + line + '\n'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
log += ` ${data}\n`
|
||||||
|
}
|
||||||
|
|
||||||
|
log += '\n' + chalk.yellow.bold(`┗ ${new Array(28 + 1).join('-')}`) + '\n'
|
||||||
|
|
||||||
|
console.log(log)
|
||||||
|
}
|
||||||
|
|
||||||
|
function startRenderer () {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
rendererConfig.entry.renderer = [path.join(__dirname, 'dev-client')].concat(rendererConfig.entry.renderer)
|
||||||
|
rendererConfig.mode = 'development'
|
||||||
|
const compiler = webpack(rendererConfig)
|
||||||
|
hotMiddleware = webpackHotMiddleware(compiler, {
|
||||||
|
log: false,
|
||||||
|
heartbeat: 2500
|
||||||
|
})
|
||||||
|
|
||||||
|
compiler.hooks.compilation.tap('compilation', compilation => {
|
||||||
|
compilation.hooks.htmlWebpackPluginAfterEmit.tapAsync('html-webpack-plugin-after-emit', (data, cb) => {
|
||||||
|
hotMiddleware.publish({ action: 'reload' })
|
||||||
|
cb()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
compiler.hooks.done.tap('done', stats => {
|
||||||
|
logStats('Renderer', stats)
|
||||||
|
})
|
||||||
|
|
||||||
|
const server = new WebpackDevServer(
|
||||||
|
compiler,
|
||||||
|
{
|
||||||
|
contentBase: path.join(__dirname, '../'),
|
||||||
|
quiet: true,
|
||||||
|
before (app, ctx) {
|
||||||
|
app.use(hotMiddleware)
|
||||||
|
ctx.middleware.waitUntilValid(() => {
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
server.listen(9080)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function startMain () {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
mainConfig.entry.main = [path.join(__dirname, '../src/main/index.dev.js')].concat(mainConfig.entry.main)
|
||||||
|
mainConfig.mode = 'development'
|
||||||
|
const compiler = webpack(mainConfig)
|
||||||
|
|
||||||
|
compiler.hooks.watchRun.tapAsync('watch-run', (compilation, done) => {
|
||||||
|
logStats('Main', chalk.white.bold('compiling...'))
|
||||||
|
hotMiddleware.publish({ action: 'compiling' })
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
|
||||||
|
compiler.watch({}, (err, stats) => {
|
||||||
|
if (err) {
|
||||||
|
console.log(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logStats('Main', stats)
|
||||||
|
|
||||||
|
if (electronProcess && electronProcess.kill) {
|
||||||
|
manualRestart = true
|
||||||
|
process.kill(electronProcess.pid)
|
||||||
|
electronProcess = null
|
||||||
|
startElectron()
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
manualRestart = false
|
||||||
|
}, 5000)
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function startElectron () {
|
||||||
|
var args = [
|
||||||
|
'--inspect=5858',
|
||||||
|
path.join(__dirname, '../dist/electron/main.js')
|
||||||
|
]
|
||||||
|
|
||||||
|
// detect yarn or npm and process commandline args accordingly
|
||||||
|
if (process.env.npm_execpath.endsWith('yarn.js')) {
|
||||||
|
args = args.concat(process.argv.slice(3))
|
||||||
|
} else if (process.env.npm_execpath.endsWith('npm-cli.js')) {
|
||||||
|
args = args.concat(process.argv.slice(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
electronProcess = spawn(electron, args)
|
||||||
|
|
||||||
|
electronProcess.stdout.on('data', data => {
|
||||||
|
electronLog(data, 'blue')
|
||||||
|
})
|
||||||
|
electronProcess.stderr.on('data', data => {
|
||||||
|
electronLog(data, 'red')
|
||||||
|
})
|
||||||
|
|
||||||
|
electronProcess.on('close', () => {
|
||||||
|
if (!manualRestart) process.exit()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function electronLog (data, color) {
|
||||||
|
let log = ''
|
||||||
|
data = data.toString().split(/\r?\n/)
|
||||||
|
data.forEach(line => {
|
||||||
|
log += ` ${line}\n`
|
||||||
|
})
|
||||||
|
if (/[0-9A-z]+/.test(log)) {
|
||||||
|
console.log(
|
||||||
|
chalk[color].bold('┏ Electron -------------------') +
|
||||||
|
'\n\n' +
|
||||||
|
log +
|
||||||
|
chalk[color].bold('┗ ----------------------------') +
|
||||||
|
'\n'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function greeting () {
|
||||||
|
const cols = process.stdout.columns
|
||||||
|
let text = ''
|
||||||
|
|
||||||
|
if (cols > 104) text = 'electron-vue'
|
||||||
|
else if (cols > 76) text = 'electron-|vue'
|
||||||
|
else text = false
|
||||||
|
|
||||||
|
if (text) {
|
||||||
|
say(text, {
|
||||||
|
colors: ['yellow'],
|
||||||
|
font: 'simple3d',
|
||||||
|
space: false
|
||||||
|
})
|
||||||
|
} else console.log(chalk.yellow.bold('\n electron-vue'))
|
||||||
|
console.log(chalk.blue(' getting ready...') + '\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
function init () {
|
||||||
|
greeting()
|
||||||
|
|
||||||
|
Promise.all([startRenderer(), startMain()])
|
||||||
|
.then(() => {
|
||||||
|
startElectron()
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
init()
|
@ -0,0 +1,72 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
process.env.BABEL_ENV = 'main'
|
||||||
|
|
||||||
|
const path = require('path')
|
||||||
|
const { dependencies } = require('../package.json')
|
||||||
|
const webpack = require('webpack')
|
||||||
|
|
||||||
|
const BabiliWebpackPlugin = require('babili-webpack-plugin')
|
||||||
|
|
||||||
|
let mainConfig = {
|
||||||
|
entry: {
|
||||||
|
main: path.join(__dirname, '../src/main/index.js')
|
||||||
|
},
|
||||||
|
externals: [
|
||||||
|
...Object.keys(dependencies || {})
|
||||||
|
],
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
use: 'babel-loader',
|
||||||
|
exclude: /node_modules/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.node$/,
|
||||||
|
use: 'node-loader'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
node: {
|
||||||
|
__dirname: process.env.NODE_ENV !== 'production',
|
||||||
|
__filename: process.env.NODE_ENV !== 'production'
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
filename: '[name].js',
|
||||||
|
libraryTarget: 'commonjs2',
|
||||||
|
path: path.join(__dirname, '../dist/electron')
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.NoEmitOnErrorsPlugin()
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.js', '.json', '.node']
|
||||||
|
},
|
||||||
|
target: 'electron-main'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust mainConfig for development settings
|
||||||
|
*/
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
mainConfig.plugins.push(
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust mainConfig for production settings
|
||||||
|
*/
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
mainConfig.plugins.push(
|
||||||
|
new BabiliWebpackPlugin(),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env.NODE_ENV': '"production"'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = mainConfig
|
@ -0,0 +1,175 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
process.env.BABEL_ENV = 'renderer'
|
||||||
|
|
||||||
|
const path = require('path')
|
||||||
|
const { dependencies } = require('../package.json')
|
||||||
|
const webpack = require('webpack')
|
||||||
|
|
||||||
|
const BabiliWebpackPlugin = require('babili-webpack-plugin')
|
||||||
|
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||||
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||||
|
const { VueLoaderPlugin } = require('vue-loader')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of node_modules to include in webpack bundle
|
||||||
|
*
|
||||||
|
* Required for specific packages like Vue UI libraries
|
||||||
|
* that provide pure *.vue files that need compiling
|
||||||
|
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/webpack-configurations.html#white-listing-externals
|
||||||
|
*/
|
||||||
|
let whiteListedModules = ['vue']
|
||||||
|
|
||||||
|
let rendererConfig = {
|
||||||
|
devtool: '#cheap-module-eval-source-map',
|
||||||
|
entry: {
|
||||||
|
renderer: path.join(__dirname, '../src/renderer/main.js')
|
||||||
|
},
|
||||||
|
externals: [
|
||||||
|
...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d))
|
||||||
|
],
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.scss$/,
|
||||||
|
use: ['vue-style-loader', 'css-loader', 'sass-loader']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.less$/,
|
||||||
|
use: ['vue-style-loader', 'css-loader', 'less-loader']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: ['vue-style-loader', 'css-loader']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.html$/,
|
||||||
|
use: 'vue-html-loader'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
use: 'babel-loader',
|
||||||
|
exclude: /node_modules/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.node$/,
|
||||||
|
use: 'node-loader'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.vue$/,
|
||||||
|
use: {
|
||||||
|
loader: 'vue-loader',
|
||||||
|
options: {
|
||||||
|
extractCSS: process.env.NODE_ENV === 'production',
|
||||||
|
loaders: {
|
||||||
|
sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1',
|
||||||
|
scss: 'vue-style-loader!css-loader!sass-loader',
|
||||||
|
less: 'vue-style-loader!css-loader!less-loader'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||||
|
use: {
|
||||||
|
loader: 'url-loader',
|
||||||
|
query: {
|
||||||
|
limit: 10000,
|
||||||
|
name: 'imgs/[name]--[folder].[ext]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
|
||||||
|
loader: 'url-loader',
|
||||||
|
options: {
|
||||||
|
limit: 10000,
|
||||||
|
name: 'media/[name]--[folder].[ext]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||||
|
use: {
|
||||||
|
loader: 'url-loader',
|
||||||
|
query: {
|
||||||
|
limit: 10000,
|
||||||
|
name: 'fonts/[name]--[folder].[ext]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
node: {
|
||||||
|
__dirname: process.env.NODE_ENV !== 'production',
|
||||||
|
__filename: process.env.NODE_ENV !== 'production'
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new VueLoaderPlugin(),
|
||||||
|
new MiniCssExtractPlugin({filename: 'styles.css'}),
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
filename: 'index.html',
|
||||||
|
template: path.resolve(__dirname, '../src/index.ejs'),
|
||||||
|
minify: {
|
||||||
|
collapseWhitespace: true,
|
||||||
|
removeAttributeQuotes: true,
|
||||||
|
removeComments: true
|
||||||
|
},
|
||||||
|
nodeModules: process.env.NODE_ENV !== 'production'
|
||||||
|
? path.resolve(__dirname, '../node_modules')
|
||||||
|
: false
|
||||||
|
}),
|
||||||
|
new webpack.HotModuleReplacementPlugin(),
|
||||||
|
new webpack.NoEmitOnErrorsPlugin()
|
||||||
|
],
|
||||||
|
output: {
|
||||||
|
filename: '[name].js',
|
||||||
|
libraryTarget: 'commonjs2',
|
||||||
|
path: path.join(__dirname, '../dist/electron')
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': path.join(__dirname, '../src/renderer'),
|
||||||
|
'vue$': 'vue/dist/vue.esm.js'
|
||||||
|
},
|
||||||
|
extensions: ['.js', '.vue', '.json', '.css', '.node']
|
||||||
|
},
|
||||||
|
target: 'electron-renderer'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust rendererConfig for development settings
|
||||||
|
*/
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
rendererConfig.plugins.push(
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust rendererConfig for production settings
|
||||||
|
*/
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
rendererConfig.devtool = ''
|
||||||
|
|
||||||
|
rendererConfig.plugins.push(
|
||||||
|
new BabiliWebpackPlugin(),
|
||||||
|
new CopyWebpackPlugin([
|
||||||
|
{
|
||||||
|
from: path.join(__dirname, '../static'),
|
||||||
|
to: path.join(__dirname, '../dist/electron/static'),
|
||||||
|
ignore: ['.*']
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env.NODE_ENV': '"production"'
|
||||||
|
}),
|
||||||
|
new webpack.LoaderOptionsPlugin({
|
||||||
|
minimize: true
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = rendererConfig
|
@ -0,0 +1,132 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
process.env.BABEL_ENV = 'web'
|
||||||
|
|
||||||
|
const path = require('path')
|
||||||
|
const webpack = require('webpack')
|
||||||
|
|
||||||
|
const BabiliWebpackPlugin = require('babili-webpack-plugin')
|
||||||
|
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||||
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||||
|
const { VueLoaderPlugin } = require('vue-loader')
|
||||||
|
|
||||||
|
let webConfig = {
|
||||||
|
devtool: '#cheap-module-eval-source-map',
|
||||||
|
entry: {
|
||||||
|
web: path.join(__dirname, '../src/renderer/main.js')
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.less$/,
|
||||||
|
use: ['vue-style-loader', 'css-loader', 'less-loader']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: ['vue-style-loader', 'css-loader']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.html$/,
|
||||||
|
use: 'vue-html-loader'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
use: 'babel-loader',
|
||||||
|
include: [ path.resolve(__dirname, '../src/renderer') ],
|
||||||
|
exclude: /node_modules/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.vue$/,
|
||||||
|
use: {
|
||||||
|
loader: 'vue-loader',
|
||||||
|
options: {
|
||||||
|
extractCSS: true,
|
||||||
|
loaders: {
|
||||||
|
sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1',
|
||||||
|
scss: 'vue-style-loader!css-loader!sass-loader',
|
||||||
|
less: 'vue-style-loader!css-loader!less-loader'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||||
|
use: {
|
||||||
|
loader: 'url-loader',
|
||||||
|
query: {
|
||||||
|
limit: 10000,
|
||||||
|
name: 'imgs/[name].[ext]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||||
|
use: {
|
||||||
|
loader: 'url-loader',
|
||||||
|
query: {
|
||||||
|
limit: 10000,
|
||||||
|
name: 'fonts/[name].[ext]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new VueLoaderPlugin(),
|
||||||
|
new MiniCssExtractPlugin({filename: 'styles.css'}),
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
filename: 'index.html',
|
||||||
|
template: path.resolve(__dirname, '../src/index.ejs'),
|
||||||
|
minify: {
|
||||||
|
collapseWhitespace: true,
|
||||||
|
removeAttributeQuotes: true,
|
||||||
|
removeComments: true
|
||||||
|
},
|
||||||
|
nodeModules: false
|
||||||
|
}),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env.IS_WEB': 'true'
|
||||||
|
}),
|
||||||
|
new webpack.HotModuleReplacementPlugin(),
|
||||||
|
new webpack.NoEmitOnErrorsPlugin()
|
||||||
|
],
|
||||||
|
output: {
|
||||||
|
filename: '[name].js',
|
||||||
|
path: path.join(__dirname, '../dist/web')
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': path.join(__dirname, '../src/renderer'),
|
||||||
|
'vue$': 'vue/dist/vue.esm.js'
|
||||||
|
},
|
||||||
|
extensions: ['.js', '.vue', '.json', '.css']
|
||||||
|
},
|
||||||
|
target: 'web'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust webConfig for production settings
|
||||||
|
*/
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
webConfig.devtool = ''
|
||||||
|
|
||||||
|
webConfig.plugins.push(
|
||||||
|
new BabiliWebpackPlugin(),
|
||||||
|
new CopyWebpackPlugin([
|
||||||
|
{
|
||||||
|
from: path.join(__dirname, '../static'),
|
||||||
|
to: path.join(__dirname, '../dist/web/static'),
|
||||||
|
ignore: ['.*']
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env.NODE_ENV': '"production"'
|
||||||
|
}),
|
||||||
|
new webpack.LoaderOptionsPlugin({
|
||||||
|
minimize: true
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = webConfig
|
@ -1,120 +1,10 @@
|
|||||||
# ---> Vue
|
.DS_Store
|
||||||
# gitignore template for Vue.js projects
|
dist/electron/*
|
||||||
#
|
dist/web/*
|
||||||
# Recommended template: Node.gitignore
|
build/*
|
||||||
|
!build/icons
|
||||||
# TODO: where does this rule come from?
|
|
||||||
docs/_book
|
|
||||||
|
|
||||||
# TODO: where does this rule come from?
|
|
||||||
test/
|
|
||||||
|
|
||||||
# ---> Node
|
|
||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
|
|
||||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
|
||||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
|
||||||
|
|
||||||
# Runtime data
|
|
||||||
pids
|
|
||||||
*.pid
|
|
||||||
*.seed
|
|
||||||
*.pid.lock
|
|
||||||
|
|
||||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
||||||
lib-cov
|
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
|
||||||
coverage
|
|
||||||
*.lcov
|
|
||||||
|
|
||||||
# nyc test coverage
|
|
||||||
.nyc_output
|
|
||||||
|
|
||||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
|
||||||
.grunt
|
|
||||||
|
|
||||||
# Bower dependency directory (https://bower.io/)
|
|
||||||
bower_components
|
|
||||||
|
|
||||||
# node-waf configuration
|
|
||||||
.lock-wscript
|
|
||||||
|
|
||||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
|
||||||
build/Release
|
|
||||||
|
|
||||||
# Dependency directories
|
|
||||||
node_modules/
|
node_modules/
|
||||||
jspm_packages/
|
npm-debug.log
|
||||||
|
npm-debug.log.*
|
||||||
# TypeScript v1 declaration files
|
thumbs.db
|
||||||
typings/
|
!.gitkeep
|
||||||
|
|
||||||
# TypeScript cache
|
|
||||||
*.tsbuildinfo
|
|
||||||
|
|
||||||
# Optional npm cache directory
|
|
||||||
.npm
|
|
||||||
|
|
||||||
# Optional eslint cache
|
|
||||||
.eslintcache
|
|
||||||
|
|
||||||
# Microbundle cache
|
|
||||||
.rpt2_cache/
|
|
||||||
.rts2_cache_cjs/
|
|
||||||
.rts2_cache_es/
|
|
||||||
.rts2_cache_umd/
|
|
||||||
|
|
||||||
# Optional REPL history
|
|
||||||
.node_repl_history
|
|
||||||
|
|
||||||
# Output of 'npm pack'
|
|
||||||
*.tgz
|
|
||||||
|
|
||||||
# Yarn Integrity file
|
|
||||||
.yarn-integrity
|
|
||||||
|
|
||||||
# dotenv environment variables file
|
|
||||||
.env
|
|
||||||
.env.test
|
|
||||||
|
|
||||||
# parcel-bundler cache (https://parceljs.org/)
|
|
||||||
.cache
|
|
||||||
|
|
||||||
# Next.js build output
|
|
||||||
.next
|
|
||||||
|
|
||||||
# Nuxt.js build / generate output
|
|
||||||
.nuxt
|
|
||||||
dist
|
|
||||||
|
|
||||||
# Gatsby files
|
|
||||||
.cache/
|
|
||||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
|
||||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
|
||||||
# public
|
|
||||||
|
|
||||||
# vuepress build output
|
|
||||||
.vuepress/dist
|
|
||||||
|
|
||||||
# Serverless directories
|
|
||||||
.serverless/
|
|
||||||
|
|
||||||
# FuseBox cache
|
|
||||||
.fusebox/
|
|
||||||
|
|
||||||
# DynamoDB Local files
|
|
||||||
.dynamodb/
|
|
||||||
|
|
||||||
# TernJS port file
|
|
||||||
.tern-port
|
|
||||||
|
|
||||||
# Stores VSCode versions used for testing VSCode extensions
|
|
||||||
.vscode-test
|
|
||||||
|
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
osx_image: xcode8.3
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
|
language: c
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: osx
|
||||||
|
- os: linux
|
||||||
|
env: CC=clang CXX=clang++ npm_config_clang=1
|
||||||
|
compiler: clang
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- node_modules
|
||||||
|
- "$HOME/.electron"
|
||||||
|
- "$HOME/.cache"
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- libgnome-keyring-dev
|
||||||
|
- icnsutils
|
||||||
|
before_install:
|
||||||
|
- mkdir -p /tmp/git-lfs && curl -L https://github.com/github/git-lfs/releases/download/v1.2.1/git-lfs-$([
|
||||||
|
"$TRAVIS_OS_NAME" == "linux" ] && echo "linux" || echo "darwin")-amd64-1.2.1.tar.gz
|
||||||
|
| tar -xz -C /tmp/git-lfs --strip-components 1 && /tmp/git-lfs/git-lfs pull
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install --no-install-recommends -y icnsutils graphicsmagick xz-utils; fi
|
||||||
|
install:
|
||||||
|
- nvm install 7
|
||||||
|
- curl -o- -L https://yarnpkg.com/install.sh | bash
|
||||||
|
- source ~/.bashrc
|
||||||
|
- npm install -g xvfb-maybe
|
||||||
|
- yarn
|
||||||
|
script:
|
||||||
|
- yarn run build
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
@ -1,3 +1,12 @@
|
|||||||
# json-editor
|
# JSON-editor
|
||||||
|
|
||||||
|
一个使用vue-electron开发的桌面应用
|
||||||
|
|
||||||
|
使用JSON schema的配置文件来产生JSON
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
```
|
||||||
|
yarn run build
|
||||||
|
```
|
||||||
|
|
||||||
json编辑器
|
|
@ -0,0 +1,29 @@
|
|||||||
|
version: 0.1.{build}
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
image: Visual Studio 2017
|
||||||
|
platform:
|
||||||
|
- x64
|
||||||
|
|
||||||
|
cache:
|
||||||
|
- node_modules
|
||||||
|
- '%APPDATA%\npm-cache'
|
||||||
|
- '%USERPROFILE%\.electron'
|
||||||
|
- '%USERPROFILE%\AppData\Local\Yarn\cache'
|
||||||
|
|
||||||
|
init:
|
||||||
|
- git config --global core.autocrlf input
|
||||||
|
|
||||||
|
install:
|
||||||
|
- ps: Install-Product node 8 x64
|
||||||
|
- git reset --hard HEAD
|
||||||
|
- yarn
|
||||||
|
- node --version
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- yarn build
|
||||||
|
|
||||||
|
test: off
|
@ -0,0 +1,110 @@
|
|||||||
|
{
|
||||||
|
"name": "JSON-editor",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"author": "liyf <liyf@connor.net.cn>",
|
||||||
|
"description": "JSON-editor",
|
||||||
|
"license": null,
|
||||||
|
"main": "./dist/electron/main.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "node .electron-vue/build.js && electron-builder",
|
||||||
|
"build:dir": "node .electron-vue/build.js && electron-builder --dir",
|
||||||
|
"build:clean": "cross-env BUILD_TARGET=clean node .electron-vue/build.js",
|
||||||
|
"build:web": "cross-env BUILD_TARGET=web node .electron-vue/build.js",
|
||||||
|
"dev": "node .electron-vue/dev-runner.js",
|
||||||
|
"pack": "npm run pack:main && npm run pack:renderer",
|
||||||
|
"pack:main": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.main.config.js",
|
||||||
|
"pack:renderer": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.renderer.config.js",
|
||||||
|
"postinstall": ""
|
||||||
|
},
|
||||||
|
"build": {
|
||||||
|
"productName": "JSON-editor",
|
||||||
|
"appId": "com.json.editor",
|
||||||
|
"directories": {
|
||||||
|
"output": "build"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist/electron/**/*"
|
||||||
|
],
|
||||||
|
"dmg": {
|
||||||
|
"contents": [
|
||||||
|
{
|
||||||
|
"x": 410,
|
||||||
|
"y": 150,
|
||||||
|
"type": "link",
|
||||||
|
"path": "/Applications"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 130,
|
||||||
|
"y": 150,
|
||||||
|
"type": "file"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"mac": {
|
||||||
|
"icon": "build/icons/icon.icns"
|
||||||
|
},
|
||||||
|
"win": {
|
||||||
|
"icon": "build/icons/icon.ico"
|
||||||
|
},
|
||||||
|
"linux": {
|
||||||
|
"icon": "build/icons"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/cli": "^7.7.5",
|
||||||
|
"@fortawesome/fontawesome-free": "^5.11.2",
|
||||||
|
"@json-editor/json-editor": "1.3.5",
|
||||||
|
"axios": "^0.19.0",
|
||||||
|
"babel-loader": "7",
|
||||||
|
"bootstrap": "^4.4.1",
|
||||||
|
"electron-localshortcut": "^3.2.1",
|
||||||
|
"jquery": "^3.4.1",
|
||||||
|
"js-md5": "^0.7.3",
|
||||||
|
"node-sass": "^4.13.0",
|
||||||
|
"popper.js": "^1.16.0",
|
||||||
|
"sass-loader": "^8.0.0",
|
||||||
|
"select2": "^4.0.12",
|
||||||
|
"vue": "^2.6.10",
|
||||||
|
"vue-electron": "^1.0.6",
|
||||||
|
"vue-highcharts": "^0.1.0",
|
||||||
|
"vue-router": "^3.1.3",
|
||||||
|
"vue-socket.io": "^3.0.7",
|
||||||
|
"vuex": "^3.1.2",
|
||||||
|
"vuex-electron": "^1.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"ajv": "^6.10.2",
|
||||||
|
"babel-plugin-transform-runtime": "^6.23.0",
|
||||||
|
"babel-preset-env": "^1.7.0",
|
||||||
|
"babel-preset-stage-0": "^6.24.1",
|
||||||
|
"babel-register": "^6.26.0",
|
||||||
|
"babili-webpack-plugin": "^0.1.2",
|
||||||
|
"cfonts": "^2.4.5",
|
||||||
|
"chalk": "^3.0.0",
|
||||||
|
"copy-webpack-plugin": "^5.1.0",
|
||||||
|
"cross-env": "^6.0.3",
|
||||||
|
"css-loader": "^3.3.0",
|
||||||
|
"del": "^5.1.0",
|
||||||
|
"devtron": "^1.4.0",
|
||||||
|
"electron": "6.1.5",
|
||||||
|
"electron-builder": "^21.2.0",
|
||||||
|
"electron-debug": "^3.0.1",
|
||||||
|
"electron-devtools-installer": "^2.2.4",
|
||||||
|
"file-loader": "^5.0.2",
|
||||||
|
"html-webpack-plugin": "^3.2.0",
|
||||||
|
"mini-css-extract-plugin": "0.8.0",
|
||||||
|
"multispinner": "^0.2.1",
|
||||||
|
"node-loader": "^0.6.0",
|
||||||
|
"style-loader": "^1.0.1",
|
||||||
|
"url-loader": "^3.0.0",
|
||||||
|
"vue-html-loader": "^1.2.4",
|
||||||
|
"vue-loader": "^15.7.2",
|
||||||
|
"vue-style-loader": "^4.1.0",
|
||||||
|
"vue-template-compiler": "^2.6.10",
|
||||||
|
"webpack": "^4.41.2",
|
||||||
|
"webpack-cli": "^3.3.10",
|
||||||
|
"webpack-dev-server": "^3.9.0",
|
||||||
|
"webpack-hot-middleware": "^2.25.0",
|
||||||
|
"webpack-merge": "^4.2.2"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>JSON-Editor</title>
|
||||||
|
<% if (htmlWebpackPlugin.options.nodeModules) { %>
|
||||||
|
<!-- Add `node_modules/` to global paths so `require` works properly in development -->
|
||||||
|
<script>
|
||||||
|
require('module').globalPaths.push('<%= htmlWebpackPlugin.options.nodeModules.replace(/\\/g, '\\\\') %>')
|
||||||
|
</script>
|
||||||
|
<% } %>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<!-- Set `__static` path to static files in production -->
|
||||||
|
<% if (!process.browser) { %>
|
||||||
|
<script>
|
||||||
|
if (process.env.NODE_ENV !== 'development') window.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
|
||||||
|
</script>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
<!-- webpack builds are automatically injected -->
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* This file is used specifically and only for development. It installs
|
||||||
|
* `electron-debug` & `vue-devtools`. There shouldn't be any need to
|
||||||
|
* modify this file, but it can be used to extend your development
|
||||||
|
* environment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
// Install `electron-debug` with `devtron`
|
||||||
|
require('electron-debug')({ showDevTools: true })
|
||||||
|
|
||||||
|
// Install `vue-devtools`
|
||||||
|
require('electron').app.on('ready', () => {
|
||||||
|
let installExtension = require('electron-devtools-installer')
|
||||||
|
installExtension.default(installExtension.VUEJS_DEVTOOLS)
|
||||||
|
.then(() => {})
|
||||||
|
.catch(err => {
|
||||||
|
console.log('Unable to install `vue-devtools`: \n', err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Require `main` process to boot app
|
||||||
|
require('./index')
|
@ -0,0 +1,99 @@
|
|||||||
|
import {
|
||||||
|
app,
|
||||||
|
BrowserWindow
|
||||||
|
} from 'electron'
|
||||||
|
import action from "./model/action"
|
||||||
|
import store from "../renderer/store"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set `__static` path to static files in production
|
||||||
|
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
|
||||||
|
*/
|
||||||
|
if (process.env.NODE_ENV !== 'development') {
|
||||||
|
global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
|
||||||
|
}
|
||||||
|
const electronLocalshortcut = require('electron-localshortcut');
|
||||||
|
let mainWindow
|
||||||
|
const winURL = process.env.NODE_ENV === 'development' ?
|
||||||
|
`http://localhost:9080` :
|
||||||
|
`file://${__dirname}/index.html`
|
||||||
|
|
||||||
|
function createWindow() {
|
||||||
|
/**
|
||||||
|
* Initial window options
|
||||||
|
*/
|
||||||
|
mainWindow = new BrowserWindow({
|
||||||
|
height: 563,
|
||||||
|
useContentSize: true,
|
||||||
|
width: 1000,
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
mainWindow.loadURL(winURL)
|
||||||
|
|
||||||
|
mainWindow.on('closed', () => {
|
||||||
|
mainWindow = null
|
||||||
|
})
|
||||||
|
store.subscribe((mutation,state)=>{
|
||||||
|
console.log('mutation:',mutation);
|
||||||
|
if(mutation.payload.name=='file'){
|
||||||
|
mainWindow.setTitle(mutation.payload.value);
|
||||||
|
}
|
||||||
|
console.log('state:',state);
|
||||||
|
})
|
||||||
|
// 去掉顶部菜单
|
||||||
|
mainWindow.setMenu(null)
|
||||||
|
|
||||||
|
require('./model/menu.js');
|
||||||
|
electronLocalshortcut.register(mainWindow, 'Ctrl+S', () => {
|
||||||
|
action.save();
|
||||||
|
});
|
||||||
|
electronLocalshortcut.register(mainWindow, 'Ctrl+E', () => {
|
||||||
|
action.saveAs();
|
||||||
|
});
|
||||||
|
electronLocalshortcut.register(mainWindow, 'Ctrl+O', () => {
|
||||||
|
action.open();
|
||||||
|
});
|
||||||
|
electronLocalshortcut.register(mainWindow, 'Ctrl+D', () => {
|
||||||
|
action.openSetting();
|
||||||
|
});
|
||||||
|
electronLocalshortcut.register(mainWindow, 'Ctrl+C', () => {
|
||||||
|
action.copy();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
app.on('ready', createWindow)
|
||||||
|
|
||||||
|
app.on('window-all-closed', () => {
|
||||||
|
if (process.platform !== 'darwin') {
|
||||||
|
app.quit()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
app.on('activate', () => {
|
||||||
|
if (mainWindow === null) {
|
||||||
|
createWindow()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto Updater
|
||||||
|
*
|
||||||
|
* Uncomment the following code below and install `electron-updater` to
|
||||||
|
* support auto updating. Code Signing with a valid certificate is required.
|
||||||
|
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
import { autoUpdater } from 'electron-updater'
|
||||||
|
|
||||||
|
autoUpdater.on('update-downloaded', () => {
|
||||||
|
autoUpdater.quitAndInstall()
|
||||||
|
})
|
||||||
|
|
||||||
|
app.on('ready', () => {
|
||||||
|
if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates()
|
||||||
|
})
|
||||||
|
*/
|
@ -0,0 +1,102 @@
|
|||||||
|
import store from "../../renderer/store"
|
||||||
|
const {
|
||||||
|
dialog,clipboard
|
||||||
|
} = require('electron');
|
||||||
|
var fs = require("fs");
|
||||||
|
|
||||||
|
function saveFile(file){
|
||||||
|
console.log("content:",store.state.content);
|
||||||
|
console.log("content2:",JSON.stringify(store.state.content));
|
||||||
|
console.log("file:",file);
|
||||||
|
fs.writeFile(file, JSON.stringify(store.state.content), function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error("err:", err);
|
||||||
|
dialog.showMessageBox({
|
||||||
|
title: file+"保存失败",
|
||||||
|
message: JSON.stringify(err),
|
||||||
|
type: "info"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
dialog.showMessageBox({
|
||||||
|
title: "message",
|
||||||
|
message: file+"保存成功",
|
||||||
|
type: "info"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
let file = store.state.file;
|
||||||
|
console.log('file:',file);
|
||||||
|
if (file == null||file==undefined) {
|
||||||
|
saveAs();
|
||||||
|
} else {
|
||||||
|
saveFile(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveAs(){
|
||||||
|
dialog.showSaveDialog({
|
||||||
|
title:"保存"
|
||||||
|
}, function (file) {
|
||||||
|
console.log('files:', file)
|
||||||
|
if (file && file.length) {
|
||||||
|
store.commit('setValue', {
|
||||||
|
name: 'file',
|
||||||
|
value: file
|
||||||
|
});
|
||||||
|
saveFile(file);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function open() {
|
||||||
|
console.log('open');
|
||||||
|
dialog.showOpenDialog({
|
||||||
|
properties: ['openFile']
|
||||||
|
}, function (files) {
|
||||||
|
console.log('files:', files)
|
||||||
|
if (files && files.length) {
|
||||||
|
store.commit('setValue', {
|
||||||
|
name: 'file',
|
||||||
|
value: files[0]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function openSetting() {
|
||||||
|
dialog.showOpenDialog({
|
||||||
|
title:"选择配置文件",
|
||||||
|
properties: ['openFile']
|
||||||
|
}, function (files) {
|
||||||
|
if (files && files.length) {
|
||||||
|
fs.readFile(files[0], function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.error('err:', err);
|
||||||
|
}
|
||||||
|
console.log('schema',data.toString());
|
||||||
|
store.commit('setValue', {
|
||||||
|
name: 'schema',
|
||||||
|
value: JSON.parse(data.toString())
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function copy(){
|
||||||
|
console.log("text:"+JSON.stringify(store.state.content))
|
||||||
|
clipboard.writeText(JSON.stringify(store.state.content));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
save: save,
|
||||||
|
saveAs:saveAs,
|
||||||
|
open: open,
|
||||||
|
openSetting: openSetting,
|
||||||
|
copy:copy
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
const {
|
||||||
|
Menu,
|
||||||
|
ipcMain,
|
||||||
|
BrowserWindow,
|
||||||
|
dialog
|
||||||
|
} = require('electron');
|
||||||
|
import store from "../../renderer/store"
|
||||||
|
import {
|
||||||
|
fstat
|
||||||
|
} from "fs";
|
||||||
|
import action from "./action"
|
||||||
|
//右键菜单
|
||||||
|
const contextMenuTemplate = [{
|
||||||
|
label: '保存',
|
||||||
|
accelerator: 'CmdOrCtrl+S',
|
||||||
|
click: () => {
|
||||||
|
action.save();
|
||||||
|
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
label: '另存为',
|
||||||
|
accelerator: 'CmdOrCtrl+E',
|
||||||
|
|
||||||
|
click: () => {
|
||||||
|
action.saveAs();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '选择文档',
|
||||||
|
accelerator: 'CmdOrCtrl+O',
|
||||||
|
click: () => {
|
||||||
|
action.open();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '复制',
|
||||||
|
accelerator: 'CmdOrCtrl+C',
|
||||||
|
click: () => {
|
||||||
|
action.copy();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'separator'
|
||||||
|
}, //分隔线
|
||||||
|
{
|
||||||
|
label: '选择配置文件',
|
||||||
|
accelerator: 'CmdOrCtrl+D',
|
||||||
|
|
||||||
|
click: () => {
|
||||||
|
action.openSetting();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const contextMenu = Menu.buildFromTemplate(contextMenuTemplate);
|
||||||
|
|
||||||
|
|
||||||
|
ipcMain.on('contextmenu', function () {
|
||||||
|
|
||||||
|
contextMenu.popup(BrowserWindow.getFocusedWindow());
|
||||||
|
|
||||||
|
})
|
@ -0,0 +1,121 @@
|
|||||||
|
<template>
|
||||||
|
<div id="app">
|
||||||
|
|
||||||
|
<label v-if="getSchema==null">请点击右键菜单选择配置</label>
|
||||||
|
<div id="editor_holder"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import JSONEditor from "@json-editor/json-editor";
|
||||||
|
require("jquery");
|
||||||
|
require("popper.js");
|
||||||
|
require("bootstrap");
|
||||||
|
require("bootstrap/dist/css/bootstrap.css");
|
||||||
|
require("@fortawesome/fontawesome-free");
|
||||||
|
require("@fortawesome/fontawesome-free/css/all.css");
|
||||||
|
require("select2");
|
||||||
|
require("select2/dist/css/select2.css");
|
||||||
|
let fs = require("fs");
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "JSON-editor",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
winHeight: document.documentElement.clientHeight,
|
||||||
|
editor: null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
getSchema() {
|
||||||
|
return this.$store.state.schema;
|
||||||
|
},
|
||||||
|
getFile(){
|
||||||
|
return this.$store.state.file;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
window.addEventListener("contextmenu", e => {
|
||||||
|
e.preventDefault();
|
||||||
|
//给主进程广播事件 注意this指向
|
||||||
|
this.$electron.ipcRenderer.send("contextmenu");
|
||||||
|
});
|
||||||
|
console.log('schema:',this.getSchema);
|
||||||
|
if(this.getSchema!=null){
|
||||||
|
let element = document.getElementById("editor_holder");
|
||||||
|
|
||||||
|
this.editor = new JSONEditor(element, {
|
||||||
|
theme: "bootstrap4",
|
||||||
|
iconlib: "fontawesome5",
|
||||||
|
schema: this.getSchema
|
||||||
|
});
|
||||||
|
let $this = this;
|
||||||
|
|
||||||
|
if(this.getFile!=null){
|
||||||
|
fs.readFile(this.getFile,function(err,data){
|
||||||
|
if(err){
|
||||||
|
console.log('err:',err);
|
||||||
|
}else{
|
||||||
|
$this.editor.setValue(JSON.parse(data));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.editor.on("change", function() {
|
||||||
|
console.log("change");
|
||||||
|
$this.$store.dispatch("setValue", {
|
||||||
|
name: "content",
|
||||||
|
value: $this.editor.getValue()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
window.onresize = () => {
|
||||||
|
this.winHeight = document.documentElement.clientHeight;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
getSchema(val) {
|
||||||
|
console.log("val:" ,val);
|
||||||
|
console.log("schema updated");
|
||||||
|
if (this.editor) this.editor.destroy();
|
||||||
|
let element = document.getElementById("editor_holder");
|
||||||
|
|
||||||
|
this.editor = new JSONEditor(element, {
|
||||||
|
theme: "bootstrap4",
|
||||||
|
iconlib: "fontawesome5",
|
||||||
|
schema: val
|
||||||
|
});
|
||||||
|
let $this = this;
|
||||||
|
this.editor.on("change", function() {
|
||||||
|
console.log("change");
|
||||||
|
$this.$store.dispatch("setValue", {
|
||||||
|
name: "content",
|
||||||
|
value: $this.editor.getValue()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getFile(val){
|
||||||
|
console.log('file:',val);
|
||||||
|
let $this=this;
|
||||||
|
if(this.editor){
|
||||||
|
|
||||||
|
fs.readFile(val,function(err,data){
|
||||||
|
if(err){
|
||||||
|
console.log('err:',err);
|
||||||
|
}else{
|
||||||
|
$this.editor.setValue(JSON.parse(data));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
* {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
</style>
|
After Width: | Height: | Size: 60 KiB |
@ -0,0 +1,23 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
import App from './App'
|
||||||
|
import router from './router'
|
||||||
|
import store from './store'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (!process.env.IS_WEB) Vue.use(require('vue-electron'))
|
||||||
|
Vue.http = Vue.prototype.$http = axios
|
||||||
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
|
|
||||||
|
/* eslint-disable no-new */
|
||||||
|
new Vue({
|
||||||
|
components: { App },
|
||||||
|
router,
|
||||||
|
store,
|
||||||
|
template: '<App/>'
|
||||||
|
}).$mount('#app')
|
@ -0,0 +1,7 @@
|
|||||||
|
import md5 from 'js-md5'
|
||||||
|
|
||||||
|
var app={
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default app;
|
@ -0,0 +1,10 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import Router from 'vue-router'
|
||||||
|
|
||||||
|
// Vue.use(Router)
|
||||||
|
|
||||||
|
export default new Router({
|
||||||
|
routes: [
|
||||||
|
|
||||||
|
]
|
||||||
|
})
|
@ -0,0 +1,35 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
|
import {
|
||||||
|
createPersistedState,
|
||||||
|
createSharedMutations
|
||||||
|
} from 'vuex-electron'
|
||||||
|
|
||||||
|
|
||||||
|
Vue.use(Vuex)
|
||||||
|
const state = {
|
||||||
|
schema: null,
|
||||||
|
file: null,
|
||||||
|
content:null
|
||||||
|
}
|
||||||
|
const mutations = {
|
||||||
|
setValue(state, value) {
|
||||||
|
state[value.name] = value.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const actions={
|
||||||
|
setValue(context,value){
|
||||||
|
context.commit('setValue',value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default new Vuex.Store({
|
||||||
|
state: state,
|
||||||
|
mutations: mutations,
|
||||||
|
actions:actions,
|
||||||
|
plugins: [
|
||||||
|
createPersistedState(),
|
||||||
|
createSharedMutations()
|
||||||
|
],
|
||||||
|
strict: process.env.NODE_ENV !== 'production'
|
||||||
|
})
|
@ -0,0 +1,142 @@
|
|||||||
|
Arguments:
|
||||||
|
/Users/poetry/.nvm/versions/node/v10.14.1/bin/node /usr/local/bin/yarn run build
|
||||||
|
|
||||||
|
PATH:
|
||||||
|
/Users/poetry/.nvm/versions/node/v10.14.1/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
|
||||||
|
|
||||||
|
Yarn version:
|
||||||
|
1.5.1
|
||||||
|
|
||||||
|
Node version:
|
||||||
|
10.14.1
|
||||||
|
|
||||||
|
Platform:
|
||||||
|
darwin x64
|
||||||
|
|
||||||
|
npm manifest:
|
||||||
|
{
|
||||||
|
"name": "yuqing-monitor",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"author": "poetries <me@poetries.top>",
|
||||||
|
"description": "一个使用electron开发的舆情监控客户端",
|
||||||
|
"license": null,
|
||||||
|
"main": "./dist/electron/main.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "node .electron-vue/build.js && electron-builder",
|
||||||
|
"build:dir": "node .electron-vue/build.js && electron-builder --dir",
|
||||||
|
"build:clean": "cross-env BUILD_TARGET=clean node .electron-vue/build.js",
|
||||||
|
"build:web": "cross-env BUILD_TARGET=web node .electron-vue/build.js",
|
||||||
|
"dev": "node .electron-vue/dev-runner.js",
|
||||||
|
"pack": "npm run pack:main && npm run pack:renderer",
|
||||||
|
"pack:main": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.main.config.js",
|
||||||
|
"pack:renderer": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.renderer.config.js",
|
||||||
|
"postinstall": ""
|
||||||
|
},
|
||||||
|
"build": {
|
||||||
|
"productName": "舆情监控系统",
|
||||||
|
"appId": "com.yuqing-monitor",
|
||||||
|
"directories": {
|
||||||
|
"output": "build"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist/electron/**/*"
|
||||||
|
],
|
||||||
|
"dmg": {
|
||||||
|
"contents": [
|
||||||
|
{
|
||||||
|
"x": 410,
|
||||||
|
"y": 150,
|
||||||
|
"type": "link",
|
||||||
|
"path": "/Applications"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 130,
|
||||||
|
"y": 150,
|
||||||
|
"type": "file"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"mac": {
|
||||||
|
"icon": "build/icons/icon.icns"
|
||||||
|
},
|
||||||
|
"win": {
|
||||||
|
"icon": "build/icons/icon.ico"
|
||||||
|
},
|
||||||
|
"linux": {
|
||||||
|
"icon": "build/icons"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.18.0",
|
||||||
|
"element-ui": "^2.4.11",
|
||||||
|
"highcharts": "^7.0.2",
|
||||||
|
"js-md5": "^0.7.3",
|
||||||
|
"node-sass": "^4.11.0",
|
||||||
|
"sass-loader": "^7.1.0",
|
||||||
|
"vue": "^2.5.16",
|
||||||
|
"vue-electron": "^1.0.6",
|
||||||
|
"vue-highcharts": "^0.0.11",
|
||||||
|
"vue-router": "^3.0.1",
|
||||||
|
"vue-socket.io": "^3.0.4",
|
||||||
|
"vuex": "^3.0.1",
|
||||||
|
"vuex-electron": "^1.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"ajv": "^6.5.0",
|
||||||
|
"babel-core": "^6.26.3",
|
||||||
|
"babel-loader": "^7.1.4",
|
||||||
|
"babel-plugin-transform-runtime": "^6.23.0",
|
||||||
|
"babel-preset-env": "^1.7.0",
|
||||||
|
"babel-preset-stage-0": "^6.24.1",
|
||||||
|
"babel-register": "^6.26.0",
|
||||||
|
"babili-webpack-plugin": "^0.1.2",
|
||||||
|
"cfonts": "^2.1.2",
|
||||||
|
"chalk": "^2.4.1",
|
||||||
|
"copy-webpack-plugin": "^4.5.1",
|
||||||
|
"cross-env": "^5.1.6",
|
||||||
|
"css-loader": "^0.28.11",
|
||||||
|
"del": "^3.0.0",
|
||||||
|
"devtron": "^1.4.0",
|
||||||
|
"electron": "^2.0.4",
|
||||||
|
"electron-debug": "^1.5.0",
|
||||||
|
"electron-devtools-installer": "^2.2.4",
|
||||||
|
"electron-builder": "^20.19.2",
|
||||||
|
"mini-css-extract-plugin": "0.4.0",
|
||||||
|
"file-loader": "^1.1.11",
|
||||||
|
"html-webpack-plugin": "^3.2.0",
|
||||||
|
"multispinner": "^0.2.1",
|
||||||
|
"node-loader": "^0.6.0",
|
||||||
|
"style-loader": "^0.21.0",
|
||||||
|
"url-loader": "^1.0.1",
|
||||||
|
"vue-html-loader": "^1.2.4",
|
||||||
|
"vue-loader": "^15.2.4",
|
||||||
|
"vue-style-loader": "^4.1.0",
|
||||||
|
"vue-template-compiler": "^2.5.16",
|
||||||
|
"webpack-cli": "^3.0.8",
|
||||||
|
"webpack": "^4.15.1",
|
||||||
|
"webpack-dev-server": "^3.1.4",
|
||||||
|
"webpack-hot-middleware": "^2.22.2",
|
||||||
|
"webpack-merge": "^4.1.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
yarn manifest:
|
||||||
|
No manifest
|
||||||
|
|
||||||
|
Lockfile:
|
||||||
|
No lockfile
|
||||||
|
|
||||||
|
Trace:
|
||||||
|
Error: Command failed.
|
||||||
|
Exit code: 1
|
||||||
|
Command: sh
|
||||||
|
Arguments: -c node .electron-vue/build.js && electron-builder
|
||||||
|
Directory: /Users/poetry/workspace/code-practice/code-practice/electron/yuqing-monitor-electron
|
||||||
|
Output:
|
||||||
|
|
||||||
|
at ProcessTermError.MessageError (/usr/local/lib/node_modules/yarn/lib/cli.js:186:110)
|
||||||
|
at new ProcessTermError (/usr/local/lib/node_modules/yarn/lib/cli.js:226:113)
|
||||||
|
at ChildProcess.<anonymous> (/usr/local/lib/node_modules/yarn/lib/cli.js:30281:17)
|
||||||
|
at ChildProcess.emit (events.js:182:13)
|
||||||
|
at maybeClose (internal/child_process.js:962:16)
|
||||||
|
at Process.ChildProcess._handle.onexit (internal/child_process.js:251:5)
|
Loading…
Reference in new issue