initial commit

This commit is contained in:
leejooy96 committed 2022-06-10 14:21:26 +09:00
commit 13ae6c773c
36 files changed
+24137

No files matched your search

+100
View File
@@ -0,0 +1,100 @@
import './env.mjs'
import chalk from 'chalk'
import webpack from 'webpack'
import Listr from 'listr'
import { performance } from 'perf_hooks'
import _ from 'qsu'
import FsMan from 'fsman'
import mainConfig from '../config/webpack.main.mjs'
import rendererConfig from '../config/webpack.renderer.mjs'
const TAG_ERROR = `${chalk.bgRed.white(' ERROR ')} `
const TAG_SUCCESS = `${chalk.bgGreen.white(' SUCCESS ')} `
async function build () {
FsMan.empty('dist/electron')
let results = ''
const tasks = new Listr(
[
{
title: 'building main process',
task: async () => {
await pack(mainConfig)
.then(result => {
results += result + '\n\n'
})
.catch(err => {
console.log(`\n ${TAG_ERROR}failed to build main process`)
console.error(`\n${err}\n`)
})
}
},
{
title: 'building renderer process',
task: async () => {
await pack(rendererConfig)
.then(result => {
results += result + '\n\n'
})
.catch(err => {
console.log(`\n ${TAG_ERROR}failed to build renderer process`)
console.error(`\n${err}\n`)
})
}
}
],
{
concurrent: 2
}
)
await tasks.run()
.catch(() => {
process.exit(1)
})
process.stdout.write('\x1B[2J\x1B[0f')
console.log(`
\n\n${results}
${TAG_SUCCESS}Wait for ${chalk.greenBright('`electron-builder`')} process...
${TAG_SUCCESS}${chalk.yellowBright(`Webpack Build Time: ${_.msToTime(performance.now())}`)}\n
`)
process.exit()
}
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
}))
}
})
})
}
(async () => {
performance.now()
await build()
})()
+2
View File
@@ -0,0 +1,2 @@
import dotenv from 'dotenv'
dotenv.config({ path: '.env.build' })
+68
View File
@@ -0,0 +1,68 @@
import path from 'path'
import packageJson from '../../package.json'
import webpack from 'webpack'
import TerserPlugin from 'terser-webpack-plugin'
import eslintFriendlyFormatter from 'eslint-friendly-formatter'
import ESLintPlugin from 'eslint-webpack-plugin'
import { fileURLToPath } from 'url'
process.env.BABEL_ENV = 'main'
const IS_DEV_ENV = process.env.NODE_ENV !== 'production'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
export default {
entry: {
main: path.join(__dirname, '../../src/main/index.js')
},
externals: [
...Object.keys(packageJson.dependencies || {})
],
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.node$/,
use: 'node-loader'
}
]
},
node: {
__dirname: IS_DEV_ENV,
__filename: IS_DEV_ENV
},
output: {
filename: '[name].js',
libraryTarget: 'commonjs2',
path: path.join(__dirname, '../../dist/electron')
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
new ESLintPlugin({
extensions: ['js'],
formatter: eslintFriendlyFormatter()
}),
new TerserPlugin(),
new webpack.DefinePlugin({
...IS_DEV_ENV
? {
__static: `"${path.join(__dirname, '../../static').replace(/\\/g, '\\\\')}"`
}
: {},
...IS_DEV_ENV
? {}
: {
'process.env.NODE_ENV': '"production"'
}
})
],
resolve: {
extensions: ['.js', '.json', '.node']
},
target: 'electron-main'
}
@@ -0,0 +1,4 @@
export default [
'vue',
'vuetify'
]
+166
View File
@@ -0,0 +1,166 @@
import path from 'path'
import packageJson from '../../package.json'
import webpack from 'webpack'
import TerserPlugin from 'terser-webpack-plugin'
import CopyWebpackPlugin from 'copy-webpack-plugin'
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
import HtmlWebpackPlugin from 'html-webpack-plugin'
import { VueLoaderPlugin } from 'vue-loader'
import eslintFriendlyFormatter from 'eslint-friendly-formatter'
import ESLintPlugin from 'eslint-webpack-plugin'
import externalsWhiteList from './webpack.renderer.externals.whitelist.mjs'
import { fileURLToPath } from 'url'
const IS_DEV_ENV = process.env.NODE_ENV !== 'production'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
process.env.BABEL_ENV = 'renderer'
export default {
devtool: IS_DEV_ENV ? 'source-map' : false,
optimization: {
minimize: true,
minimizer: [new TerserPlugin()]
},
entry: {
renderer: path.join(__dirname, '../../src/renderer/main.js')
},
externals: [
...Object.keys(packageJson.dependencies || {}).filter(d => !externalsWhiteList.includes(d))
],
module: {
rules: [
{
test: /\.vue$/,
use: {
loader: 'vue-loader',
options: {
extractCSS: !IS_DEV_ENV,
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: /\.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: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
type: 'asset/inline'
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
type: 'asset/inline'
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
type: 'asset/inline'
}
]
},
node: {
__dirname: IS_DEV_ENV,
__filename: IS_DEV_ENV
},
plugins: [
new TerserPlugin(),
new VueLoaderPlugin(),
new MiniCssExtractPlugin({ filename: 'styles.css' }),
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(__dirname, '../../src/index.ejs'),
templateParameters (compilation, assets, options) {
return {
compilation,
webpack: compilation.getStats().toJson(),
webpackConfig: compilation.options,
htmlWebpackPlugin: {
files: assets,
options
},
process
}
},
minify: {
collapseWhitespace: true,
removeAttributeQuotes: true,
removeComments: true
},
isBrowser: false,
isDevelopment: IS_DEV_ENV,
nodeModules: IS_DEV_ENV
? path.resolve(__dirname, '../../node_modules')
: false
}),
new webpack.NoEmitOnErrorsPlugin(),
new ESLintPlugin({
extensions: ['js', 'vue'],
exclude: [
'/node_modules/'
],
formatter: eslintFriendlyFormatter()
}),
new webpack.DefinePlugin(IS_DEV_ENV
? {
__static: `"${path.join(__dirname, '../../static').replace(/\\/g, '\\\\')}"`,
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false
}
: {
'process.env.NODE_ENV': '"production"',
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false
}
),
...IS_DEV_ENV
? []
: [new CopyWebpackPlugin({
patterns: [
{
from: path.join(__dirname, '../../static'),
to: path.join(__dirname, '../../dist/electron/static')
}
]
})],
...IS_DEV_ENV
? []
: [new webpack.LoaderOptionsPlugin({
minimize: true
})]
],
cache: true,
output: {
filename: '[name].js',
libraryTarget: 'commonjs2',
path: path.join(__dirname, '../../dist/electron')
},
resolve: {
alias: {
'@': path.join(__dirname, '../../src/renderer')
},
extensions: ['.js', '.vue', '.json', '.css', '.node']
},
target: 'electron-renderer'
}
+152
View File
@@ -0,0 +1,152 @@
import dotenv from 'dotenv'
import chalk from 'chalk'
import electron from 'electron'
import path from 'path'
import { spawn } from 'child_process'
import webpack from 'webpack'
import WebpackDevServer from 'webpack-dev-server'
import webpackHotMiddleware from 'webpack-hot-middleware'
import mainConfig from './config/webpack.main.mjs'
import rendererConfig from './config/webpack.renderer.mjs'
import { fileURLToPath } from 'url'
dotenv.config({ path: '.env.dev' })
const __dirname = path.dirname(fileURLToPath(import.meta.url))
let electronProcess = null
let manualRestart = false
function log (processName, data, color = 'yellow') {
let strLog = ''
if (typeof data === 'object') {
data.toString().split(/\r?\n/).forEach(line => {
strLog += ' ' + line + '\n'
})
} else {
strLog += ` ${data}\n`
}
if (/[\dA-z]+/.test(strLog)) {
console.log(`${chalk[color].bold(`[${processName}]---------------`)}\n`)
console.log(`${strLog}${chalk[color].bold(`[${processName}]---------------`)}\n`)
}
}
function startRenderer () {
return new Promise(resolve => {
(async () => {
rendererConfig.entry.renderer = [path.join(__dirname, 'devClient.mjs'), rendererConfig.entry.renderer]
const compiler = webpack({
mode: 'development',
...rendererConfig
})
compiler.hooks.done.tap('done', stats => {
log('Renderer', stats)
})
const server = new WebpackDevServer(
{
port: 9080,
liveReload: true,
static: {
directory: path.join(__dirname, '../'),
watch: {
usePolling: true,
ignored: /node_modules/
}
},
setupMiddlewares (middlewares, devServer) {
devServer.app.use(webpackHotMiddleware(compiler, {
log: false,
heartbeat: 2500
}))
devServer.middleware.waitUntilValid(() => {
resolve()
})
return middlewares
}
},
compiler
)
await server.start()
})()
})
}
function startMain () {
return new Promise(resolve => {
mainConfig.entry.main = [path.join(__dirname, '../src/main/index.dev.js'), mainConfig.entry.main]
const compiler = webpack({
mode: 'development',
...mainConfig
})
compiler.hooks.watchRun.tapAsync('watch-run', (compilation, done) => {
log('Main', chalk.white.bold('Compiling...'))
done()
})
compiler.watch({}, (err, stats) => {
if (err) {
console.log(err)
return
}
log('Main', stats)
if (electronProcess?.kill) {
manualRestart = true
process.kill(electronProcess.pid)
electronProcess = null
startElectron()
setTimeout(() => {
manualRestart = false
}, 3500)
}
resolve()
})
})
}
function startElectron () {
electronProcess = spawn(electron, [
...[
'--inspect=5858',
path.join(__dirname, '/../dist/electron/main.js')
],
...process.argv.slice(2)
])
electronProcess.stdout.on('data', data => {
log('Electron', data, 'blue')
})
electronProcess.stderr.on('data', data => {
log('Electron', data, 'red')
})
electronProcess.on('close', () => {
if (!manualRestart) {
process.exit()
}
})
}
(async () => {
try {
await startRenderer()
await startMain()
startElectron()
} catch (e) {
console.error(e)
}
})()
+15
View File
@@ -0,0 +1,15 @@
import * as hotClient from 'webpack-hot-middleware/client.js?noInfo=true&reload=true'
hotClient.subscribe(event => {
if (event.action === 'compiling') {
document.body.innerHTML += `
<style>
.root {
color: #000;
padding: 10px 20px;
}
</style>
<div class="root">Compiling Main Process...</div>
`
}
})