From 53bc50d05cd9266afa6cca7741fda86830661c3f Mon Sep 17 00:00:00 2001 From: lyswhut Date: Thu, 17 Aug 2023 17:49:47 +0800 Subject: [PATCH] Revert vite build --- build-config/css-loader.config.js | 9 + build-config/main/webpack.config.base.js | 48 + build-config/main/webpack.config.dev.js | 28 + build-config/main/webpack.config.prod.js | 49 + build-config/pack.js | 145 +- .../renderer-lyric/webpack.config.base.js | 152 + .../renderer-lyric/webpack.config.dev.js | 26 + .../renderer-lyric/webpack.config.prod.js | 49 + .../renderer-scripts/webpack.config.base.js | 57 + .../renderer-scripts/webpack.config.dev.js | 24 + .../renderer-scripts/webpack.config.prod.js | 45 + build-config/renderer/webpack.config.base.js | 158 + build-config/renderer/webpack.config.dev.js | 27 + build-config/renderer/webpack.config.prod.js | 62 + build-config/runner-dev.js | 249 +- build-config/utils.js | 65 + build-config/vite/configs/main.ts | 77 - build-config/vite/configs/renderer-lyric.ts | 74 - build-config/vite/configs/renderer-scripts.ts | 61 - build-config/vite/configs/renderer.ts | 105 - build-config/vite/copyAssets.ts | 27 - build-config/vite/pack.ts | 62 - build-config/vite/runner-dev.ts | 119 - build-config/vite/utils.ts | 140 - build-config/vite/worker.ts | 33 - build-config/vue-loader.config.js | 12 + build-config/webpack-build-config.js | 3 + package-lock.json | 11754 +++++++++++++--- package.json | 77 +- .../postcss.config.js => postcss.config.js | 0 publish/changeLog.md | 3 +- .../{theme_images => images}/china_ink.jpg | Bin .../theme/{theme_images => images}/jqbg.jpg | Bin .../{theme_images => images}/landingMoon.png | Bin .../theme/{theme_images => images}/myzcbg.jpg | Bin .../theme/{theme_images => images}/xnkl.png | Bin src/main/app.ts | 4 +- src/main/index-dev.ts | 2 +- src/main/modules/userApi/main.ts | 9 +- .../rendererEvent/{name.ts => name.js} | 0 src/main/modules/winLyric/main.ts | 2 +- src/main/modules/winLyric/utils.ts | 1 - src/main/modules/winMain/main.ts | 2 +- .../winMain/rendererEvent/tx_decodeLyric.ts | 4 +- src/main/tsconfig.json | 1 - src/main/types/global.d.ts | 5 +- src/main/worker/dbService/db.ts | 2 +- src/main/worker/utils/index.ts | 12 +- src/renderer-lyric/components/index.js | 25 +- src/renderer-lyric/index.html | 1 - src/renderer/components/index.js | 25 +- .../useApp/usePlayer/useMediaSessionInfo.ts | 3 +- .../core/useApp/usePlayer/useSoundEffect.ts | 63 +- src/renderer/index.html | 1 - src/renderer/main.ts | 1 - src/renderer/plugins/SvgIcon/index.js | 6 +- src/renderer/plugins/player/index.ts | 8 +- src/renderer/router.ts | 22 +- src/renderer/store/index.ts | 6 +- src/renderer/types/env.d.ts | 2 - .../views/Setting/components/SettingBasic.vue | 2 +- src/renderer/worker/utils/index.ts | 21 +- tsconfig.json | 3 + 63 files changed, 11408 insertions(+), 2565 deletions(-) create mode 100644 build-config/css-loader.config.js create mode 100644 build-config/main/webpack.config.base.js create mode 100644 build-config/main/webpack.config.dev.js create mode 100644 build-config/main/webpack.config.prod.js create mode 100644 build-config/renderer-lyric/webpack.config.base.js create mode 100644 build-config/renderer-lyric/webpack.config.dev.js create mode 100644 build-config/renderer-lyric/webpack.config.prod.js create mode 100644 build-config/renderer-scripts/webpack.config.base.js create mode 100644 build-config/renderer-scripts/webpack.config.dev.js create mode 100644 build-config/renderer-scripts/webpack.config.prod.js create mode 100644 build-config/renderer/webpack.config.base.js create mode 100644 build-config/renderer/webpack.config.dev.js create mode 100644 build-config/renderer/webpack.config.prod.js create mode 100644 build-config/utils.js delete mode 100644 build-config/vite/configs/main.ts delete mode 100644 build-config/vite/configs/renderer-lyric.ts delete mode 100644 build-config/vite/configs/renderer-scripts.ts delete mode 100644 build-config/vite/configs/renderer.ts delete mode 100644 build-config/vite/copyAssets.ts delete mode 100644 build-config/vite/pack.ts delete mode 100644 build-config/vite/runner-dev.ts delete mode 100644 build-config/vite/utils.ts delete mode 100644 build-config/vite/worker.ts create mode 100644 build-config/vue-loader.config.js create mode 100644 build-config/webpack-build-config.js rename build-config/vite/configs/postcss.config.js => postcss.config.js (100%) rename src/common/theme/{theme_images => images}/china_ink.jpg (100%) rename src/common/theme/{theme_images => images}/jqbg.jpg (100%) rename src/common/theme/{theme_images => images}/landingMoon.png (100%) rename src/common/theme/{theme_images => images}/myzcbg.jpg (100%) rename src/common/theme/{theme_images => images}/xnkl.png (100%) rename src/main/modules/userApi/rendererEvent/{name.ts => name.js} (100%) delete mode 100644 src/renderer/types/env.d.ts diff --git a/build-config/css-loader.config.js b/build-config/css-loader.config.js new file mode 100644 index 00000000..05dfd1c2 --- /dev/null +++ b/build-config/css-loader.config.js @@ -0,0 +1,9 @@ +const isDev = process.env.NODE_ENV === 'development' + +module.exports = { + modules: { + localIdentName: isDev ? '[path][name]__[local]--[hash:base64:5]' : '[hash:base64:5]', + exportLocalsConvention: 'camelCase', + }, + sourceMap: isDev, +} diff --git a/build-config/main/webpack.config.base.js b/build-config/main/webpack.config.base.js new file mode 100644 index 00000000..bfd839c6 --- /dev/null +++ b/build-config/main/webpack.config.base.js @@ -0,0 +1,48 @@ +const path = require('path') +const ESLintPlugin = require('eslint-webpack-plugin') + +const isDev = process.env.NODE_ENV === 'development' + +module.exports = { + target: 'electron-main', + output: { + filename: '[name].js', + library: { + type: 'commonjs2', + }, + path: path.join(__dirname, '../../dist'), + }, + externals: { + 'font-list': 'font-list', + 'better-sqlite3': 'better-sqlite3', + 'electron-font-manager': 'electron-font-manager', + bufferutil: 'bufferutil', + 'utf-8-validate': 'utf-8-validate', + 'qrc_decode.node': isDev ? path.join(__dirname, '../../build/Release/qrc_decode.node') : path.join('../build/Release/qrc_decode.node'), + }, + resolve: { + alias: { + '@main': path.join(__dirname, '../../src/main'), + '@renderer': path.join(__dirname, '../../src/renderer'), + '@lyric': path.join(__dirname, '../../src/renderer-lyric'), + '@common': path.join(__dirname, '../../src/common'), + }, + extensions: ['.tsx', '.ts', '.js', '.mjs', '.json', '.node'], + }, + module: { + rules: [ + { + test: /\.node$/, + use: 'node-loader', + }, + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + plugins: [ + new ESLintPlugin(), + ], +} diff --git a/build-config/main/webpack.config.dev.js b/build-config/main/webpack.config.dev.js new file mode 100644 index 00000000..18ae009b --- /dev/null +++ b/build-config/main/webpack.config.dev.js @@ -0,0 +1,28 @@ +const path = require('path') +const { merge } = require('webpack-merge') +const webpack = require('webpack') + +const baseConfig = require('./webpack.config.base') + + +module.exports = merge(baseConfig, { + mode: 'development', + entry: { + main: path.join(__dirname, '../../src/main/index-dev.ts'), + // 'dbService.worker': path.join(__dirname, '../../src/main/worker/dbService/index.ts'), + }, + devtool: 'eval-source-map', + plugins: [ + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: '"development"', + }, + webpackStaticPath: `"${path.join(__dirname, '../../src/static').replace(/\\/g, '\\\\')}"`, + webpackUserApiPath: `"${path.join(__dirname, '../../src/main/modules/userApi').replace(/\\/g, '\\\\')}"`, + }), + ], + performance: { + maxEntrypointSize: 1024 * 1024 * 50, + maxAssetSize: 1024 * 1024 * 30, + }, +}) diff --git a/build-config/main/webpack.config.prod.js b/build-config/main/webpack.config.prod.js new file mode 100644 index 00000000..dbc694f4 --- /dev/null +++ b/build-config/main/webpack.config.prod.js @@ -0,0 +1,49 @@ +const path = require('path') +const { merge } = require('webpack-merge') +const webpack = require('webpack') +const CopyWebpackPlugin = require('copy-webpack-plugin') + +const baseConfig = require('./webpack.config.base') + +// const { dependencies } = require('../../package.json') + +const buildConfig = require('../webpack-build-config') + + +module.exports = merge(baseConfig, { + mode: 'production', + entry: { + main: path.join(__dirname, '../../src/main/index.ts'), + // 'dbService.worker': path.join(__dirname, '../../src/main/worker/dbService/index.ts'), + }, + node: { + __dirname: false, + __filename: false, + }, + plugins: [ + new CopyWebpackPlugin({ + patterns: [ + { + from: path.join(__dirname, '../../src/main/modules/userApi/renderer/user-api.html'), + to: path.join(__dirname, '../../dist/userApi/renderer/user-api.html'), + }, + { + from: path.join(__dirname, '../../src/common/theme/images/*').replace(/\\/g, '/'), + to: path.join(__dirname, '../../dist/theme_images/[name][ext]'), + }, + ], + }), + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: '"production"', + }, + }), + ], + performance: { + maxEntrypointSize: 1024 * 1024 * 10, + maxAssetSize: 1024 * 1024 * 20, + }, + optimization: { + minimize: buildConfig.minimize, + }, +}) diff --git a/build-config/pack.js b/build-config/pack.js index f7ecaf71..b9011d66 100644 --- a/build-config/pack.js +++ b/build-config/pack.js @@ -1,3 +1,146 @@ process.env.NODE_ENV = 'production' -require('./vite/pack') +const chalk = require('chalk') +const del = require('del') +const webpack = require('webpack') +const Spinnies = require('spinnies') + +const mainConfig = './main/webpack.config.prod' +const rendererConfig = './renderer/webpack.config.prod' +const rendererLyricConfig = './renderer-lyric/webpack.config.prod' +const rendererScriptConfig = './renderer-scripts/webpack.config.prod' + +const errorLog = chalk.bgRed.white(' ERROR ') + ' ' +const okayLog = chalk.bgGreen.white(' OKAY ') + ' ' + +const { Worker, isMainThread, parentPort } = require('worker_threads') + + +function build() { + console.time('build') + del.sync(['dist/**', 'build/**']) + + const spinners = new Spinnies({ color: 'blue' }) + spinners.add('main', { text: 'main building' }) + spinners.add('renderer', { text: 'renderer building' }) + spinners.add('renderer-lyric', { text: 'renderer-lyric building' }) + spinners.add('renderer-scripts', { text: 'renderer-scripts building' }) + 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() + // }) + function handleSuccess() { + process.stdout.write('\x1B[2J\x1B[0f') + console.log(`\n\n${results}`) + console.log(`${okayLog}take it away ${chalk.yellow('`electron-builder`')}\n`) + console.timeEnd('build') + process.exit() + } + + Promise.all([ + pack(mainConfig).then(result => { + results += result + '\n\n' + spinners.succeed('main', { text: 'main build success!' }) + }).catch(err => { + spinners.fail('main', { text: 'main build fail :(' }) + 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' + spinners.succeed('renderer', { text: 'renderer build success!' }) + }).catch(err => { + spinners.fail('renderer', { text: 'renderer build fail :(' }) + console.log(`\n ${errorLog}failed to build renderer process`) + console.error(`\n${err}\n`) + process.exit(1) + }), + pack(rendererLyricConfig).then(result => { + results += result + '\n\n' + spinners.succeed('renderer-lyric', { text: 'renderer-lyric build success!' }) + }).catch(err => { + spinners.fail('renderer-lyric', { text: 'renderer-lyric build fail :(' }) + console.log(`\n ${errorLog}failed to build renderer-lyric process`) + console.error(`\n${err}\n`) + process.exit(1) + }), + pack(rendererScriptConfig).then(result => { + results += result + '\n\n' + spinners.succeed('renderer-scripts', { text: 'renderer-scripts build success!' }) + }).catch(err => { + spinners.fail('renderer-scripts', { text: 'renderer-scripts build fail :(' }) + console.log(`\n ${errorLog}failed to build renderer-scripts process`) + console.error(`\n${err}\n`) + process.exit(1) + }), + ]).then(handleSuccess) +} + +function pack(config) { + return new Promise((resolve, reject) => { + const worker = new Worker(__filename) + const subChannel = new MessageChannel() + worker.postMessage({ port: subChannel.port1, config }, [subChannel.port1]) + subChannel.port2.on('message', ({ status, message }) => { + switch (status) { + case 'success': return resolve(message) + case 'error': return reject(message) + } + }) + }) +} + +function runPack(config) { + return new Promise((resolve, reject) => { + config = require(config) + config.mode = 'production' + webpack(config, (err, stats) => { + if (err) reject(err.stack || err) + else if (stats.hasErrors()) { + let err = '' + + stats.toString({ + chunks: false, + modules: false, + colors: true, + }) + .split(/\r?\n/) + .forEach(line => { + err += ` ${line}\n` + }) + + reject(err) + } else { + resolve(stats.toString({ + chunks: false, + colors: true, + })) + } + }) + }) +} + +if (isMainThread) build() +else { + parentPort.once('message', ({ port, config }) => { + // assert(port instanceof MessagePort) + runPack(config).then((result) => { + port.postMessage({ + status: 'success', + message: result, + }) + }).catch((err) => { + port.postMessage({ + status: 'error', + message: err, + }) + }).finally(() => { + port.close() + }) + }) +} diff --git a/build-config/renderer-lyric/webpack.config.base.js b/build-config/renderer-lyric/webpack.config.base.js new file mode 100644 index 00000000..ccaa86be --- /dev/null +++ b/build-config/renderer-lyric/webpack.config.base.js @@ -0,0 +1,152 @@ +const path = require('path') +const { VueLoaderPlugin } = require('vue-loader') +const HTMLPlugin = require('html-webpack-plugin') +const MiniCssExtractPlugin = require('mini-css-extract-plugin') +const ESLintPlugin = require('eslint-webpack-plugin') + +const vueLoaderConfig = require('../vue-loader.config') +const { mergeCSSLoader } = require('../utils') + +const isDev = process.env.NODE_ENV === 'development' + +module.exports = { + target: 'electron-renderer', + entry: { + 'renderer-lyric': path.join(__dirname, '../../src/renderer-lyric/main.ts'), + }, + output: { + filename: '[name].js', + library: { + type: 'commonjs2', + }, + path: path.join(__dirname, '../../dist'), + publicPath: '', + }, + resolve: { + alias: { + '@root': path.join(__dirname, '../../src'), + '@main': path.join(__dirname, '../../src/main'), + '@renderer': path.join(__dirname, '../../src/renderer'), + '@lyric': path.join(__dirname, '../../src/renderer-lyric'), + '@static': path.join(__dirname, '../../src/static'), + '@common': path.join(__dirname, '../../src/common'), + }, + extensions: ['.tsx', '.ts', '.js', '.json', '.node'], + }, + module: { + rules: [ + { + test: /\.js$/, + loader: 'babel-loader', + exclude: /node_modules/, + }, + { + test: /\.tsx?$/, + exclude: /node_modules/, + use: { + loader: 'ts-loader', + options: { + appendTsSuffixTo: [/\.vue$/], + }, + }, + }, + { + test: /\.node$/, + use: 'node-loader', + }, + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig, + }, + { + test: /\.pug$/, + loader: 'pug-plain-loader', + }, + { + test: /\.css$/, + oneOf: mergeCSSLoader(), + }, + { + test: /\.less$/, + oneOf: mergeCSSLoader({ + loader: 'less-loader', + options: { + sourceMap: true, + }, + }), + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + exclude: path.join(__dirname, '../../src/renderer/assets/svgs'), + type: 'asset', + parser: { + dataUrlCondition: { + maxSize: 10000, + }, + }, + generator: { + filename: 'imgs/[name]-[contenthash:8][ext]', + }, + }, + { + test: /\.svg$/, + include: path.join(__dirname, '../../src/renderer/assets/svgs'), + use: [ + { + loader: 'svg-sprite-loader', + options: { + symbolId: 'icon-[name]', + }, + }, + 'svg-transform-loader', + 'svgo-loader', + ], + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + type: 'asset', + parser: { + dataUrlCondition: { + maxSize: 10000, + }, + }, + generator: { + filename: 'media/[name]-[contenthash:8][ext]', + }, + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + type: 'asset', + parser: { + dataUrlCondition: { + maxSize: 10000, + }, + }, + generator: { + filename: 'fonts/[name]-[contenthash:8][ext]', + }, + }, + ], + }, + plugins: [ + new HTMLPlugin({ + filename: 'lyric.html', + template: path.join(__dirname, '../../src/renderer-lyric/index.html'), + isProd: process.env.NODE_ENV == 'production', + browser: process.browser, + __dirname, + }), + new VueLoaderPlugin(), + new MiniCssExtractPlugin({ + // Options similar to the same options in webpackOptions.output + // both options are optional + filename: isDev ? '[name].css' : '[name].[contenthash:8].css', + chunkFilename: isDev ? '[id].css' : '[id].[contenthash:8].css', + }), + new ESLintPlugin({ + extensions: ['js', 'vue'], + formatter: require('eslint-formatter-friendly'), + }), + ], +} diff --git a/build-config/renderer-lyric/webpack.config.dev.js b/build-config/renderer-lyric/webpack.config.dev.js new file mode 100644 index 00000000..1cc61b23 --- /dev/null +++ b/build-config/renderer-lyric/webpack.config.dev.js @@ -0,0 +1,26 @@ +const path = require('path') +const webpack = require('webpack') + +const { merge } = require('webpack-merge') + +const baseConfig = require('./webpack.config.base') + +module.exports = merge(baseConfig, { + mode: 'development', + devtool: 'eval-source-map', + plugins: [ + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: '"development"', + ELECTRON_DISABLE_SECURITY_WARNINGS: 'true', + }, + __VUE_OPTIONS_API__: 'true', + __VUE_PROD_DEVTOOLS__: 'false', + staticPath: `"${path.join(__dirname, '../../src/static').replace(/\\/g, '\\\\')}"`, + }), + ], + performance: { + hints: false, + }, +}) + diff --git a/build-config/renderer-lyric/webpack.config.prod.js b/build-config/renderer-lyric/webpack.config.prod.js new file mode 100644 index 00000000..eeff1dba --- /dev/null +++ b/build-config/renderer-lyric/webpack.config.prod.js @@ -0,0 +1,49 @@ +// const path = require('path') +const webpack = require('webpack') +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') +const TerserPlugin = require('terser-webpack-plugin') +const { merge } = require('webpack-merge') + +const baseConfig = require('./webpack.config.base') +const buildConfig = require('../webpack-build-config') + +// const { dependencies } = require('../../package.json') + +// let whiteListedModules = ['vue'] +// let whiteListedModules = ['vue', 'vue-router', 'vuex', 'vue-i18n'] + + +module.exports = merge(baseConfig, { + mode: 'production', + devtool: false, + externals: [ + // ...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d)), + ], + plugins: [ + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: '"production"', + }, + __VUE_OPTIONS_API__: 'true', + __VUE_PROD_DEVTOOLS__: 'false', + }), + ], + optimization: { + minimize: buildConfig.minimize, + minimizer: [ + new TerserPlugin(), + new CssMinimizerPlugin(), + ], + }, + performance: { + maxEntrypointSize: 1024 * 1024 * 10, + maxAssetSize: 1024 * 1024 * 20, + hints: 'warning', + }, + node: { + __dirname: false, + __filename: false, + }, +}) + + diff --git a/build-config/renderer-scripts/webpack.config.base.js b/build-config/renderer-scripts/webpack.config.base.js new file mode 100644 index 00000000..50ad2b1d --- /dev/null +++ b/build-config/renderer-scripts/webpack.config.base.js @@ -0,0 +1,57 @@ +const path = require('path') +const ESLintPlugin = require('eslint-webpack-plugin') + +module.exports = { + target: 'electron-renderer', + entry: { + 'user-api-preload': path.join(__dirname, '../../src/main/modules/userApi/renderer/preload.js'), + }, + output: { + filename: '[name].js', + library: { + type: 'commonjs2', + }, + path: path.join(__dirname, '../../dist'), + publicPath: '', + }, + resolve: { + alias: { + '@root': path.join(__dirname, '../../src'), + '@main': path.join(__dirname, '../../src/main'), + '@renderer': path.join(__dirname, '../../src/renderer'), + '@lyric': path.join(__dirname, '../../src/renderer-lyric'), + '@static': path.join(__dirname, '../../src/static'), + '@common': path.join(__dirname, '../../src/common'), + }, + extensions: ['.tsx', '.ts', '.js', '.json', '.node'], + }, + module: { + rules: [ + { + test: /\.js$/, + loader: 'babel-loader', + exclude: /node_modules/, + }, + { + test: /\.tsx?$/, + exclude: /node_modules/, + use: { + loader: 'ts-loader', + options: { + appendTsSuffixTo: [/\.vue$/], + }, + }, + }, + { + test: /\.node$/, + use: 'node-loader', + }, + ], + }, + plugins: [ + new ESLintPlugin({ + extensions: ['js'], + formatter: require('eslint-formatter-friendly'), + }), + ], +} diff --git a/build-config/renderer-scripts/webpack.config.dev.js b/build-config/renderer-scripts/webpack.config.dev.js new file mode 100644 index 00000000..bbecbacf --- /dev/null +++ b/build-config/renderer-scripts/webpack.config.dev.js @@ -0,0 +1,24 @@ +const path = require('path') +const webpack = require('webpack') + +const { merge } = require('webpack-merge') + +const baseConfig = require('./webpack.config.base') + +module.exports = merge(baseConfig, { + mode: 'development', + devtool: 'eval-source-map', + plugins: [ + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: '"development"', + ELECTRON_DISABLE_SECURITY_WARNINGS: 'true', + }, + staticPath: `"${path.join(__dirname, '../../src/static').replace(/\\/g, '\\\\')}"`, + }), + ], + performance: { + hints: false, + }, +}) + diff --git a/build-config/renderer-scripts/webpack.config.prod.js b/build-config/renderer-scripts/webpack.config.prod.js new file mode 100644 index 00000000..3c7b86da --- /dev/null +++ b/build-config/renderer-scripts/webpack.config.prod.js @@ -0,0 +1,45 @@ +// const path = require('path') +const webpack = require('webpack') +const TerserPlugin = require('terser-webpack-plugin') +const { merge } = require('webpack-merge') + +const baseConfig = require('./webpack.config.base') +const buildConfig = require('../webpack-build-config') + +// const { dependencies } = require('../../package.json') + +// let whiteListedModules = ['vue'] +// let whiteListedModules = ['vue', 'vue-router', 'vuex', 'vue-i18n'] + + +module.exports = merge(baseConfig, { + mode: 'production', + devtool: false, + externals: [ + // ...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d)), + ], + plugins: [ + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: '"production"', + }, + }), + ], + optimization: { + minimize: buildConfig.minimize, + minimizer: [ + new TerserPlugin(), + ], + }, + performance: { + maxEntrypointSize: 1024 * 1024 * 10, + maxAssetSize: 1024 * 1024 * 20, + hints: 'warning', + }, + node: { + __dirname: false, + __filename: false, + }, +}) + + diff --git a/build-config/renderer/webpack.config.base.js b/build-config/renderer/webpack.config.base.js new file mode 100644 index 00000000..7e45bbc9 --- /dev/null +++ b/build-config/renderer/webpack.config.base.js @@ -0,0 +1,158 @@ +const path = require('path') +const { VueLoaderPlugin } = require('vue-loader') +const HTMLPlugin = require('html-webpack-plugin') +const MiniCssExtractPlugin = require('mini-css-extract-plugin') +const ESLintPlugin = require('eslint-webpack-plugin') + +const vueLoaderConfig = require('../vue-loader.config') +const { mergeCSSLoader } = require('../utils') + +const isDev = process.env.NODE_ENV === 'development' + +module.exports = { + target: 'electron-renderer', + entry: { + renderer: path.join(__dirname, '../../src/renderer/main.ts'), + }, + output: { + filename: '[name].js', + library: { + type: 'commonjs2', + }, + path: path.join(__dirname, '../../dist'), + publicPath: '', + }, + resolve: { + alias: { + '@root': path.join(__dirname, '../../src'), + '@main': path.join(__dirname, '../../src/main'), + '@renderer': path.join(__dirname, '../../src/renderer'), + '@lyric': path.join(__dirname, '../../src/renderer-lyric'), + '@static': path.join(__dirname, '../../src/static'), + '@common': path.join(__dirname, '../../src/common'), + }, + extensions: ['.tsx', '.ts', '.js', '.json', '.node'], + }, + module: { + rules: [ + { + test: /\.js$/, + loader: 'babel-loader', + exclude: /node_modules/, + }, + { + test: /\.tsx?$/, + exclude: /node_modules/, + use: { + loader: 'ts-loader', + options: { + appendTsSuffixTo: [/\.vue$/], + }, + }, + parser: { + worker: [ + '*audioContext.audioWorklet.addModule()', + '...', + ], + }, + }, + { + test: /\.node$/, + use: 'node-loader', + }, + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig, + }, + { + test: /\.pug$/, + loader: 'pug-plain-loader', + }, + { + test: /\.css$/, + oneOf: mergeCSSLoader(), + }, + { + test: /\.less$/, + oneOf: mergeCSSLoader({ + loader: 'less-loader', + options: { + sourceMap: true, + }, + }), + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + exclude: path.join(__dirname, '../../src/renderer/assets/svgs'), + type: 'asset', + parser: { + dataUrlCondition: { + maxSize: 10000, + }, + }, + generator: { + filename: 'imgs/[name]-[contenthash:8][ext]', + }, + }, + { + test: /\.svg$/, + include: path.join(__dirname, '../../src/renderer/assets/svgs'), + use: [ + { + loader: 'svg-sprite-loader', + options: { + symbolId: 'icon-[name]', + }, + }, + 'svg-transform-loader', + 'svgo-loader', + ], + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)$/, + type: 'asset', + parser: { + dataUrlCondition: { + maxSize: 10000, + }, + }, + generator: { + filename: 'media/[name]-[contenthash:8][ext]', + }, + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + type: 'asset', + parser: { + dataUrlCondition: { + maxSize: 10000, + }, + }, + generator: { + filename: 'fonts/[name]-[contenthash:8][ext]', + }, + }, + ], + }, + plugins: [ + new HTMLPlugin({ + filename: 'index.html', + template: path.join(__dirname, '../../src/renderer/index.html'), + isProd: process.env.NODE_ENV == 'production', + browser: process.browser, + __dirname, + }), + new VueLoaderPlugin(), + new MiniCssExtractPlugin({ + // Options similar to the same options in webpackOptions.output + // both options are optional + filename: isDev ? '[name].css' : '[name].[contenthash:8].css', + chunkFilename: isDev ? '[id].css' : '[id].[contenthash:8].css', + }), + new ESLintPlugin({ + extensions: ['js', 'vue'], + formatter: require('eslint-formatter-friendly'), + }), + ], +} diff --git a/build-config/renderer/webpack.config.dev.js b/build-config/renderer/webpack.config.dev.js new file mode 100644 index 00000000..369d25f6 --- /dev/null +++ b/build-config/renderer/webpack.config.dev.js @@ -0,0 +1,27 @@ +const path = require('path') +const webpack = require('webpack') + +const { merge } = require('webpack-merge') + +const baseConfig = require('./webpack.config.base') + +module.exports = merge(baseConfig, { + mode: 'development', + devtool: 'eval-source-map', + plugins: [ + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: '"development"', + ELECTRON_DISABLE_SECURITY_WARNINGS: 'true', + }, + // ENVIRONMENT: 'process.env', + __VUE_OPTIONS_API__: 'true', + __VUE_PROD_DEVTOOLS__: 'false', + staticPath: `"${path.join(__dirname, '../../src/static').replace(/\\/g, '\\\\')}"`, + }), + ], + performance: { + hints: false, + }, +}) + diff --git a/build-config/renderer/webpack.config.prod.js b/build-config/renderer/webpack.config.prod.js new file mode 100644 index 00000000..8994b89d --- /dev/null +++ b/build-config/renderer/webpack.config.prod.js @@ -0,0 +1,62 @@ +const path = require('path') +const webpack = require('webpack') +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') +const TerserPlugin = require('terser-webpack-plugin') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const { merge } = require('webpack-merge') + +const baseConfig = require('./webpack.config.base') +const buildConfig = require('../webpack-build-config') + +// const { dependencies } = require('../../package.json') + +// let whiteListedModules = ['vue', 'vue-router', 'vuex', 'vue-i18n'] + + +module.exports = merge(baseConfig, { + mode: 'production', + devtool: false, + externals: [ + // ...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d)), + ], + plugins: [ + new CopyWebpackPlugin({ + patterns: [ + { + from: path.join(__dirname, '../../src/static'), + to: path.join(__dirname, '../../dist/static'), + }, + ], + }), + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: '"production"', + }, + // ENVIRONMENT: 'process.env', + __VUE_OPTIONS_API__: 'true', + __VUE_PROD_DEVTOOLS__: 'false', + }), + ], + optimization: { + minimize: buildConfig.minimize, + minimizer: [ + new TerserPlugin(), + new CssMinimizerPlugin(), + ], + splitChunks: { + chunks: 'initial', + minChunks: 2, + }, + }, + performance: { + maxEntrypointSize: 1024 * 1024 * 10, + maxAssetSize: 1024 * 1024 * 20, + hints: 'warning', + }, + node: { + __dirname: false, + __filename: false, + }, +}) + + diff --git a/build-config/runner-dev.js b/build-config/runner-dev.js index 24b4bb01..79bfd031 100644 --- a/build-config/runner-dev.js +++ b/build-config/runner-dev.js @@ -1,3 +1,250 @@ process.env.NODE_ENV = 'development' -require('./vite/runner-dev') +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 HtmlWebpackPlugin = require('html-webpack-plugin') +const webpackHotMiddleware = require('webpack-hot-middleware') + +const mainConfig = require('./main/webpack.config.dev') +const rendererConfig = require('./renderer/webpack.config.dev') +const rendererLyricConfig = require('./renderer-lyric/webpack.config.dev') +const rendererScriptConfig = require('./renderer-scripts/webpack.config.dev') +const { Arch } = require('electron-builder') +const replaceLib = require('./build-before-pack') + +let electronProcess = null +let manualRestart = false +let hotMiddlewareRenderer +let hotMiddlewareRendererLyric + + +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) + hotMiddlewareRenderer = webpackHotMiddleware(compiler, { + log: false, + heartbeat: 2500, + }) + + compiler.hooks.compilation.tap('compilation', compilation => { + // console.log(Object.keys(compilation.hooks)) + HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync('html-webpack-plugin-after-emit', (data, cb) => { + hotMiddlewareRenderer.publish({ action: 'reload' }) + cb() + }) + }) + + // compiler.hooks.done.tap('done', stats => { + // // logStats('Renderer', 'Compile done') + // // logStats('Renderer', stats) + // }) + + const server = new WebpackDevServer({ + port: 9080, + hot: true, + historyApiFallback: true, + static: { + directory: path.join(__dirname, '../src/common/theme/images'), + publicPath: '/theme_images', + }, + client: { + logging: 'warn', + overlay: true, + }, + setupMiddlewares(middlewares, devServer) { + devServer.app.use(hotMiddlewareRenderer) + devServer.middleware.waitUntilValid(resolve) + + return middlewares + }, + }, compiler) + + server.start() + }) +} + +function startRendererLyric() { + return new Promise((resolve, reject) => { + // rendererConfig.entry.renderer = [path.join(__dirname, 'dev-client')].concat(rendererConfig.entry.renderer) + // rendererConfig.mode = 'development' + const compiler = webpack(rendererLyricConfig) + hotMiddlewareRendererLyric = webpackHotMiddleware(compiler, { + log: false, + heartbeat: 2500, + }) + + compiler.hooks.compilation.tap('compilation', compilation => { + // console.log(Object.keys(compilation.hooks)) + HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync('html-webpack-plugin-after-emit', (data, cb) => { + hotMiddlewareRendererLyric.publish({ action: 'reload' }) + cb() + }) + }) + + // compiler.hooks.done.tap('done', stats => { + // // logStats('Renderer', 'Compile done') + // // logStats('Renderer', stats) + // }) + + const server = new WebpackDevServer({ + port: 9081, + hot: true, + historyApiFallback: true, + // static: { + // directory: path.join(__dirname, '../'), + // }, + client: { + logging: 'warn', + overlay: true, + }, + setupMiddlewares(middlewares, devServer) { + devServer.app.use(hotMiddlewareRenderer) + devServer.middleware.waitUntilValid(resolve) + return middlewares + }, + }, compiler) + + server.start() + }) +} + +function startRendererScripts() { + 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(rendererScriptConfig) + + compiler.watch({}, (err, stats) => { + if (err) { + console.log(err) + return + } + resolve() + }) + }) +} + +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) => { + hotMiddlewareRenderer.publish({ action: 'compiling' }) + hotMiddlewareRendererLyric.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() { + let args = [ + '--inspect=5858', + // 'NODE_ENV=development', + path.join(__dirname, '../dist/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() + }) +} + +const logs = [ + 'Manifest version 2 is deprecated, and support will be removed in 2023', + '"Extension server error: Operation failed: Permission denied", source: devtools://devtools/bundled', + + // https://github.com/electron/electron/issues/32133 + '"Electron sandbox_bundle.js script failed to run"', + '"TypeError: object null is not iterable (cannot read property Symbol(Symbol.iterator))",', +] +function electronLog(data, color) { + let log = data.toString() + if (/[0-9A-z]+/.test(log)) { + // 抑制某些无关的报错日志 + if (color == 'red' && typeof log === 'string' && logs.some(l => log.includes(l))) return + + console.log(chalk[color](log)) + } +} + +function init() { + const Spinnies = require('spinnies') + const spinners = new Spinnies({ color: 'blue' }) + spinners.add('main', { text: 'main compiling' }) + spinners.add('renderer', { text: 'renderer compiling' }) + spinners.add('renderer-lyric', { text: 'renderer-lyric compiling' }) + spinners.add('renderer-scripts', { text: 'renderer-scripts compiling' }) + function handleSuccess(name) { + spinners.succeed(name, { text: name + ' compile success!' }) + } + function handleFail(name) { + spinners.fail(name, { text: name + ' compile fail!' }) + } + replaceLib({ electronPlatformName: process.platform, arch: Arch[process.arch] }) + + Promise.all([ + startRenderer().then(() => handleSuccess('renderer')).catch((err) => { + console.error(err.message) + return handleFail('renderer') + }), + startRendererLyric().then(() => handleSuccess('renderer-lyric')).catch((err) => { + console.error(err.message) + return handleFail('renderer-lyric') + }), + startRendererScripts().then(() => handleSuccess('renderer-scripts')).catch((err) => { + console.error(err.message) + return handleFail('renderer-scripts') + }), + startMain().then(() => handleSuccess('main')).catch(() => handleFail('main')), + ]).then(startElectron).catch(err => { + console.error(err) + }) +} + +init() diff --git a/build-config/utils.js b/build-config/utils.js new file mode 100644 index 00000000..708233df --- /dev/null +++ b/build-config/utils.js @@ -0,0 +1,65 @@ +const MiniCssExtractPlugin = require('mini-css-extract-plugin') +const cssLoaderConfig = require('./css-loader.config') +const chalk = require('chalk') + +// merge css-loader +exports.mergeCSSLoader = beforeLoader => { + const loader = [ + // 这里匹配 `