From d9ab23f6b550bd8bf5313aded4e6c14c7beddaf6 Mon Sep 17 00:00:00 2001 From: Axel Rindle Date: Wed, 28 Jun 2023 14:50:00 +0200 Subject: [PATCH 01/10] Migrate to electron-forge --- .electron-vue/build.js | 135 - .electron-vue/dev-client.js | 40 - .electron-vue/dev-runner.js | 197 - .electron-vue/electron-builder/afterPack.js | 51 - .electron-vue/marktextEnvironment.js | 38 - .electron-vue/postinstall.js | 32 - .electron-vue/preinstall.js | 12 - .electron-vue/webpack.main.config.js | 112 - .electron-vue/webpack.renderer.config.js | 285 - .eslintrc.js | 38 +- .gitignore | 2 + babel.config.js | 56 - forge.config.js | 54 + src/index.ejs => index.html | 21 +- log.txt | 53 + package.json | 97 +- src/main/app/index.js | 4 +- src/main/app/paths.js | 4 +- src/main/cli/index.js | 2 +- src/main/commands/index.js | 2 +- src/main/dataCenter/index.js | 4 +- src/main/filesystem/index.js | 2 +- src/main/filesystem/markdown.js | 4 +- src/main/filesystem/watcher.js | 4 +- src/main/globalSetting.js | 6 - src/main/index.js | 6 +- src/main/jsconfig.json | 11 - src/main/keyboard/shortcutHandler.js | 4 +- src/main/menu/actions/file.js | 4 +- src/main/menu/index.js | 2 +- src/main/menu/templates/help.js | 2 +- src/main/menu/templates/index.js | 2 - src/main/preferences/index.js | 3 +- src/main/preload.js | 1 + src/main/utils/imagePathAutoComplement.js | 4 +- src/main/utils/pandoc.js | 2 +- src/main/utils/static.js | 7 + src/main/windows/editor.js | 5 +- src/main/windows/setting.js | 3 +- src/renderer/commands/fileEncoding.js | 4 +- src/renderer/commands/index.js | 2 +- src/renderer/commands/lineEnding.js | 2 +- src/renderer/commands/quickOpen.js | 4 +- src/renderer/commands/spellcheckerLanguage.js | 8 +- src/renderer/commands/trailingNewline.js | 2 +- .../components/editorWithTabs/editor.vue | 56 +- .../components/editorWithTabs/sourceCode.vue | 4 +- .../components/exportSettings/index.vue | 12 +- src/renderer/components/import/index.vue | 4 +- src/renderer/components/recent/index.vue | 2 +- src/renderer/components/search/index.vue | 6 +- src/renderer/components/sideBar/help.js | 8 +- src/renderer/components/sideBar/search.vue | 8 +- src/renderer/components/sideBar/toc.vue | 2 +- src/renderer/components/sideBar/tree.vue | 2 +- src/renderer/components/titleBar/index.vue | 4 +- src/renderer/jsconfig.json | 13 - src/renderer/main.js | 2 +- src/renderer/mixins/index.js | 2 +- src/renderer/node/paths.js | 2 +- src/renderer/pages/app.vue | 30 +- src/renderer/pages/preference.vue | 12 +- src/renderer/prefComponents/editor/config.js | 2 +- src/renderer/prefComponents/editor/index.vue | 14 +- src/renderer/prefComponents/general/index.vue | 14 +- .../image/components/folderSetting/index.vue | 6 +- .../image/components/uploader/index.vue | 6 +- src/renderer/prefComponents/image/index.vue | 8 +- .../keybindings/KeybindingConfigurator.js | 4 +- .../prefComponents/keybindings/index.vue | 6 +- .../prefComponents/markdown/index.vue | 8 +- src/renderer/prefComponents/sideBar/config.js | 14 +- .../prefComponents/spellchecker/index.vue | 16 +- src/renderer/prefComponents/theme/index.vue | 6 +- src/renderer/router/index.js | 18 +- src/renderer/spellchecker/index.js | 2 +- src/renderer/store/editor.js | 2 +- src/renderer/util/dompurify.js | 2 +- src/renderer/util/fileSystem.js | 2 +- src/renderer/util/pdf.js | 4 +- tools/generateThirdPartyLicense.js | 2 +- {.electron-vue => tools}/thirdPartyChecker.js | 0 tools/validateLicenses.js | 2 +- vetur.config.js | 9 - vite.main.config.mjs | 20 + vite.preload.config.mjs | 4 + vite.renderer.config.mjs | 15 + yarn.lock | 7861 ++++------------- 88 files changed, 2050 insertions(+), 7499 deletions(-) delete mode 100644 .electron-vue/build.js delete mode 100644 .electron-vue/dev-client.js delete mode 100644 .electron-vue/dev-runner.js delete mode 100644 .electron-vue/electron-builder/afterPack.js delete mode 100644 .electron-vue/marktextEnvironment.js delete mode 100755 .electron-vue/postinstall.js delete mode 100644 .electron-vue/preinstall.js delete mode 100644 .electron-vue/webpack.main.config.js delete mode 100644 .electron-vue/webpack.renderer.config.js delete mode 100644 babel.config.js create mode 100644 forge.config.js rename src/index.ejs => index.html (74%) create mode 100644 log.txt delete mode 100644 src/main/globalSetting.js delete mode 100644 src/main/jsconfig.json create mode 100644 src/main/preload.js create mode 100644 src/main/utils/static.js delete mode 100644 src/renderer/jsconfig.json rename {.electron-vue => tools}/thirdPartyChecker.js (100%) delete mode 100644 vetur.config.js create mode 100644 vite.main.config.mjs create mode 100644 vite.preload.config.mjs create mode 100644 vite.renderer.config.mjs diff --git a/.electron-vue/build.js b/.electron-vue/build.js deleted file mode 100644 index 84fd546a4..000000000 --- a/.electron-vue/build.js +++ /dev/null @@ -1,135 +0,0 @@ -'use strict' - -process.env.NODE_ENV = 'production' - -const { say } = require('cfonts') -const path = require('path') -const chalk = require('chalk') -const del = require('del') -const fs = require('fs-extra') -const webpack = require('webpack') -const Listr = require('listr') - - -const mainConfig = require('./webpack.main.config') -const rendererConfig = require('./webpack.renderer.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() -} - -async function build () { - greeting() - - del.sync(['dist/electron/*', '!.gitkeep']) - del.sync(['static/themes/*']) - - const from = path.resolve(__dirname, '../src/muya/themes') - const to = path.resolve(__dirname, '../static/themes') - await fs.copy(from, to) - - 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 ${errorLog}failed to build main process`) - console.error(`\n${err}\n`) - process.exit(1) - }) - } - }, - { - title: 'building renderer process', - task: async () => { - await pack(rendererConfig) - .then(result => { - results += result + '\n\n' - }) - .catch(err => { - console.log(`\n ${errorLog}failed to build renderer process`) - console.error(`\n${err}\n`) - process.exit(1) - }) - } - } - ], - { concurrent: 2 } - ) - - await tasks - .run() - .then(() => { - 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() - }) - .catch(err => { - process.exit(1) - }) -} - -function pack (config) { - return new Promise((resolve, reject) => { - 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 greeting () { - const cols = process.stdout.columns - let text = '' - - if (cols > 155) text = 'building marktext' - else if (cols > 76) text = 'building|marktext' - else text = false - - if (text && !isCI) { - say(text, { - colors: ['yellow'], - font: 'simple3d', - space: false - }) - } else { - console.log(chalk.yellow.bold('\n building marktext')) - } -} diff --git a/.electron-vue/dev-client.js b/.electron-vue/dev-client.js deleted file mode 100644 index 147c7806a..000000000 --- a/.electron-vue/dev-client.js +++ /dev/null @@ -1,40 +0,0 @@ -const hotClient = require('webpack-hot-middleware/client?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 += ` - - -
- Compiling Main Process... -
- ` - } -}) diff --git a/.electron-vue/dev-runner.js b/.electron-vue/dev-runner.js deleted file mode 100644 index 676a314de..000000000 --- a/.electron-vue/dev-runner.js +++ /dev/null @@ -1,197 +0,0 @@ -'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 HtmlWebpackPlugin = require('html-webpack-plugin') -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) - - const compiler = webpack(rendererConfig) - hotMiddleware = webpackHotMiddleware(compiler, { - log: false, - heartbeat: 2500 - }) - - compiler.hooks.compilation.tap('HtmlWebpackPluginAfterEmit', compilation => { - HtmlWebpackPlugin.getHooks(compilation).afterEmit.tapAsync( - 'AfterPlugin', - (data, cb) => { - hotMiddleware.publish({ action: 'reload' }) - // Tell webpack to move on - cb(null, data) - } - ) - }) - - compiler.hooks.done.tap('AfterCompiler', stats => { - logStats('Renderer', stats) - }) - - const server = new WebpackDevServer({ - host: '127.0.0.1', - port: 9091, - hot: true, - liveReload: true, - compress: true, - static: [ - { - directory: path.join(__dirname, '../node_modules/codemirror/mode'), - publicPath: '/codemirror/mode', - watch: false - } - ], - onBeforeSetupMiddleware ({ app, middleware }) { - app.use(hotMiddleware) - middleware.waitUntilValid(() => { - resolve() - }) - } - }, compiler) - - server.start() - }) -} - -function startMain () { - return new Promise((resolve, reject) => { - mainConfig.entry.main = [path.join(__dirname, '../src/main/index.dev.js')].concat(mainConfig.entry.main) - - const compiler = webpack(mainConfig) - - compiler.hooks.watchRun.tapAsync('Compiling', (_, 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 () { - electronProcess = spawn(electron, [ - '--inspect=5858', - '--remote-debugging-port=8315', - '--nolazy', - path.join(__dirname, '../dist/electron/main.js') - ]) - - 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 > 155) text = 'building marktext' - else if (cols > 76) text = 'building|marktext' - else text = false - - if (text) { - say(text, { - colors: ['yellow'], - font: 'simple3d', - space: false - }) - } else { - console.log(chalk.yellow.bold('\n building marktext')) - } - console.log(chalk.blue(' getting ready...') + '\n') -} - -function init () { - greeting() - - Promise.all([startRenderer(), startMain()]) - .then(() => { - startElectron() - }) - .catch(err => { - console.error(err) - }) -} - -init() diff --git a/.electron-vue/electron-builder/afterPack.js b/.electron-vue/electron-builder/afterPack.js deleted file mode 100644 index 7f4a10e87..000000000 --- a/.electron-vue/electron-builder/afterPack.js +++ /dev/null @@ -1,51 +0,0 @@ -'use strict' -const fs = require('fs') -const path = require('path') -const { exec: execNode } = require("child_process") -const util = require('util') - -const exec = util.promisify(execNode) - -// interface AfterPackContext { -// outDir: string -// appOutDir: string -// packager: PlatformPackager -// electronPlatformName: string -// arch: Arch -// targets: Array -// } - -/** - * - * @param {AfterPackContext} context - */ -const afterPack = async (context) => { - // Workaround to remove debug information from production binaries on Linux (Electron#32669). - if (context.packager.platform.name === 'linux') { - console.log('[afterPack] Removing Electron debug information on Linux') - - const { appOutDir } = context - const chromeCrashpadHandlerPath = path.join(appOutDir, 'chrome_crashpad_handler') - const libvkPath = path.join(appOutDir, 'libvk_swiftshader.so') - - if (fs.existsSync(chromeCrashpadHandlerPath)) { - const { err } = await exec(`strip "${chromeCrashpadHandlerPath}"`) - if (err) { - console.log('[afterPack] Unable to strip "chrome_crashpad_handler".') - } - } else { - console.log(`[afterPack] "chrome_crashpad_handler" doesn't exists: "${chromeCrashpadHandlerPath}".`) - } - - if (fs.existsSync(libvkPath)) { - const { err } = await exec(`strip "${libvkPath}"`) - if (err) { - console.log('[afterPack] Unable to strip "libvk_swiftshader.so".') - } - } else { - console.log(`[afterPack] "libvk_swiftshader.so" doesn't exists: "${libvkPath}".`) - } - } -} - -exports.default = afterPack diff --git a/.electron-vue/marktextEnvironment.js b/.electron-vue/marktextEnvironment.js deleted file mode 100644 index d347b0398..000000000 --- a/.electron-vue/marktextEnvironment.js +++ /dev/null @@ -1,38 +0,0 @@ -const { GitRevisionPlugin } = require('git-revision-webpack-plugin') -const { version } = require('../package.json') - -const getEnvironmentDefinitions = function () { - let shortHash = 'N/A' - let fullHash = 'N/A' - try { - const gitRevisionPlugin = new GitRevisionPlugin() - shortHash = gitRevisionPlugin.version() - fullHash = gitRevisionPlugin.commithash() - } catch(_) { - // Ignore error if we build without git. - } - - const isStableRelease = !!process.env.MARKTEXT_IS_STABLE - const versionSuffix = isStableRelease ? '' : ` (${shortHash})` - return { - 'global.MARKTEXT_GIT_SHORT_HASH': JSON.stringify(shortHash), - 'global.MARKTEXT_GIT_HASH': JSON.stringify(fullHash), - - 'global.MARKTEXT_VERSION': JSON.stringify(version), - 'global.MARKTEXT_VERSION_STRING': JSON.stringify(`v${version}${versionSuffix}`), - 'global.MARKTEXT_IS_STABLE': JSON.stringify(isStableRelease) - } -} - -const getRendererEnvironmentDefinitions = function () { - const env = getEnvironmentDefinitions() - return { - 'process.versions.MARKTEXT_VERSION': env['global.MARKTEXT_VERSION'], - 'process.versions.MARKTEXT_VERSION_STRING': env['global.MARKTEXT_VERSION_STRING'], - } -} - -module.exports = { - getEnvironmentDefinitions: getEnvironmentDefinitions, - getRendererEnvironmentDefinitions: getRendererEnvironmentDefinitions -} diff --git a/.electron-vue/postinstall.js b/.electron-vue/postinstall.js deleted file mode 100755 index fd81fb1d8..000000000 --- a/.electron-vue/postinstall.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict' -const fs = require('fs') -const path = require('path') - -// WORKAROUND: Fix slow startup time on Windows due to blocking powershell call(s) in windows-release. -// Replace the problematic file with our "fixed" version. -const windowsReleasePath = path.resolve(__dirname, '../node_modules/windows-release') -if (fs.existsSync(windowsReleasePath)) { - const windowsReleaseJson = path.join(windowsReleasePath, 'package.json') - const packageJson = JSON.parse(fs.readFileSync(windowsReleaseJson, { encoding : 'utf-8' })) - - const windowsReleaseMajor = Number(packageJson.version.match(/^(\d+)\./)[1]) - if (windowsReleaseMajor >= 5) { - console.error('[ERROR] "windows-release" workaround failed because version is >=5.\n') - process.exit(1) - } - - const srcPath = path.resolve(__dirname, '../resources/build/windows-release.js') - const destPath = path.join(windowsReleasePath, 'index.js') - fs.copyFileSync(srcPath, destPath) -} - -// WORKAROUND: electron-builder downloads the wrong prebuilt architecture on macOS and the reason is unknown. -// For now, we rebuild all native libraries from source. -const keytarPath = path.resolve(__dirname, '../node_modules/keytar') -if (process.platform === 'darwin' && fs.existsSync(keytarPath)) { - const keytarPackageJsonPath = path.join(keytarPath, 'package.json') - let packageText = fs.readFileSync(keytarPackageJsonPath, { encoding : 'utf-8' }) - - packageText = packageText.replace(/"install": "prebuild-install \|\| npm run build",/i, '"install": "npm run build",') - fs.writeFileSync(keytarPackageJsonPath, packageText, { encoding : 'utf-8' }) -} diff --git a/.electron-vue/preinstall.js b/.electron-vue/preinstall.js deleted file mode 100644 index 6f19d4458..000000000 --- a/.electron-vue/preinstall.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict' - -const nodeMajor = Number(process.versions.node.match(/^(\d+)\./)[1]) -if (nodeMajor < 14) { - console.error('[ERROR] Node.js v14 or above is required.\n') - process.exit(1) -} - -if (!/yarn$/.test(process.env.npm_execpath)) { - console.error('[ERROR] Please use yarn to install dependencies.\n') - process.exit(1) -} diff --git a/.electron-vue/webpack.main.config.js b/.electron-vue/webpack.main.config.js deleted file mode 100644 index 6ec024696..000000000 --- a/.electron-vue/webpack.main.config.js +++ /dev/null @@ -1,112 +0,0 @@ -'use strict' - -process.env.BABEL_ENV = 'main' - -const path = require('path') -const webpack = require('webpack') -const ESLintPlugin = require('eslint-webpack-plugin') - -const { getEnvironmentDefinitions } = require('./marktextEnvironment') -const { dependencies } = require('../package.json') - -const isProduction = process.env.NODE_ENV === 'production' - -/** @type {import('webpack').Configuration} */ -const mainConfig = { - mode: 'development', - devtool: 'eval-cheap-module-source-map', - optimization: { - emitOnErrors: false - }, - 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$/, - loader: 'node-loader', - options: { - name: '[name].[ext]' - } - } - ] - }, - node: { - __dirname: !isProduction, - __filename: !isProduction - }, - cache: false, - output: { - filename: '[name].js', - libraryTarget: 'commonjs2', - path: path.join(__dirname, '../dist/electron') - }, - plugins: [ - new ESLintPlugin({ - extensions: ['js'], - files: [ - 'src', - 'test' - ], - exclude: [ - 'node_modules' - ], - emitError: true, - failOnError: true, - // NB: Threads must be disabled, otherwise no errors are emitted. - threads: false, - formatter: require('eslint-friendly-formatter'), - context: path.resolve(__dirname, '../'), - overrideConfigFile: '.eslintrc.js' - }), - // Add global environment definitions. - new webpack.DefinePlugin(getEnvironmentDefinitions()) - ], - resolve: { - alias: { - 'common': path.join(__dirname, '../src/common') - }, - extensions: ['.js', '.json', '.node'] - }, - target: 'electron-main' -} - -// Fix debugger breakpoints -if (!isProduction && process.env.MARKTEXT_BUILD_VSCODE_DEBUG) { - mainConfig.devtool = 'inline-source-map' -} - -/** - * Adjust mainConfig for development settings - */ -if (!isProduction) { - mainConfig.cache = { - name: 'main-dev', - type: 'filesystem' - } - mainConfig.plugins.push( - new webpack.DefinePlugin({ - '__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"` - }) - ) -} - -/** - * Adjust mainConfig for production settings - */ -if (isProduction) { - mainConfig.devtool = 'nosources-source-map' - mainConfig.mode = 'production' - mainConfig.optimization.minimize = true -} - -module.exports = mainConfig diff --git a/.electron-vue/webpack.renderer.config.js b/.electron-vue/webpack.renderer.config.js deleted file mode 100644 index 3abf3145c..000000000 --- a/.electron-vue/webpack.renderer.config.js +++ /dev/null @@ -1,285 +0,0 @@ -'use strict' - -process.env.BABEL_ENV = 'renderer' - -const path = require('path') -const webpack = require('webpack') -const CopyWebpackPlugin = require('copy-webpack-plugin') -const MiniCssExtractPlugin = require("mini-css-extract-plugin") -const HtmlWebpackPlugin = require('html-webpack-plugin') -const VueLoaderPlugin = require('vue-loader/lib/plugin') -const SpritePlugin = require('svg-sprite-loader/plugin') -const postcssPresetEnv = require('postcss-preset-env') -const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer') -const ESLintPlugin = require('eslint-webpack-plugin') - -const { getRendererEnvironmentDefinitions } = require('./marktextEnvironment') -const { dependencies } = require('../package.json') - -const isProduction = process.env.NODE_ENV === 'production' -/** - * 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 - */ -const whiteListedModules = ['vue'] - -/** @type {import('webpack').Configuration} */ -const rendererConfig = { - mode: 'development', - devtool: 'eval-cheap-module-source-map', - optimization: { - emitOnErrors: false - }, - infrastructureLogging: { - level: 'warn', - }, - entry: { - renderer: path.join(__dirname, '../src/renderer/main.js') - }, - externals: [ - ...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d)) - ], - module: { - rules: [ - { - test: require.resolve(path.join(__dirname, '../src/muya/lib/assets/libs/snap.svg-min.js')), - use: 'imports-loader?this=>window,fix=>module.exports=0' - }, - { - test: /\.vue$/, - use: { - loader: 'vue-loader', - options: { - sourceMap: true - } - } - }, - { - test: /(theme\-chalk(?:\/|\\)index|exportStyle|katex|github\-markdown|prism[\-a-z]*|\.theme|headerFooterStyle)\.css$/, - use: [ - 'to-string-loader', - 'css-loader' - ] - }, - { - test: /\.css$/, - exclude: /(theme\-chalk(?:\/|\\)index|exportStyle|katex|github\-markdown|prism[\-a-z]*|\.theme|headerFooterStyle)\.css$/, - use: [ - isProduction ? MiniCssExtractPlugin.loader : 'style-loader', - { - loader: 'css-loader', - options: { importLoaders: 1 } - }, - { - loader: 'postcss-loader', - options: { - postcssOptions: { - plugins: [ - postcssPresetEnv({ stage: 0 }) - ], - }, - } - } - ] - }, - { - test: /\.html$/, - use: 'vue-html-loader' - }, - { - test: /\.js$/, - use: [ - { - loader: 'babel-loader', - options: { - cacheDirectory: true - } - } - ], - exclude: /node_modules/ - }, - { - test: /\.node$/, - loader: 'node-loader', - options: { - name: '[name].[ext]' - } - }, - { - test: /\.svg$/, - use: [ - { - loader: 'svg-sprite-loader', - options: { - extract: true, - publicPath: './static/' - } - }, - 'svgo-loader' - ] - }, - { - test: /\.(png|jpe?g|gif)(\?.*)?$/, - type: 'asset', - generator: { - filename: 'images/[name].[contenthash:8][ext]' - } - }, - { - test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, - type: 'asset/resource', - generator: { - filename: 'media/[name].[contenthash:8][ext]' - } - }, - { - test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, - type: 'asset/resource', - generator: { - filename: 'fonts/[name].[contenthash:8][ext]' - } - }, - { - test: /\.md$/, - type: 'asset/source' - } - ] - }, - node: { - __dirname: !isProduction, - __filename: !isProduction - }, - plugins: [ - new ESLintPlugin({ - cache: !isProduction, - extensions: ['js', 'vue'], - files: [ - 'src', - 'test' - ], - exclude: [ - 'node_modules' - ], - emitError: true, - failOnError: true, - // NB: Threads must be disabled, otherwise no errors are emitted. - threads: false, - formatter: require('eslint-friendly-formatter'), - context: path.resolve(__dirname, '../'), - overrideConfigFile: '.eslintrc.js' - }), - new SpritePlugin(), - new HtmlWebpackPlugin({ - filename: 'index.html', - template: path.resolve(__dirname, '../src/index.ejs'), - minify: { - collapseWhitespace: true, - removeAttributeQuotes: true, - removeComments: true, - minifyJS: true, - minifyCSS: true - }, - isBrowser: false, - isDevelopment: !isProduction, - nodeModules: !isProduction - ? path.resolve(__dirname, '../node_modules') - : false - }), - new webpack.DefinePlugin(getRendererEnvironmentDefinitions()), - // Use node http request instead axios's XHR adapter. - new webpack.NormalModuleReplacementPlugin( - /.+[\/\\]node_modules[\/\\]axios[\/\\]lib[\/\\]adapters[\/\\]xhr\.js$/, - 'http.js' - ), - new VueLoaderPlugin() - ], - cache: false, - output: { - filename: '[name].js', - libraryTarget: 'commonjs2', - path: path.join(__dirname, '../dist/electron'), - assetModuleFilename: 'assets/[name].[contenthash:8][ext]', - asyncChunks: true - }, - resolve: { - alias: { - 'main': path.join(__dirname, '../src/main'), - '@': path.join(__dirname, '../src/renderer'), - 'common': path.join(__dirname, '../src/common'), - 'muya': path.join(__dirname, '../src/muya'), - snapsvg: path.join(__dirname, '../src/muya/lib/assets/libs/snap.svg-min.js'), - 'vue$': 'vue/dist/vue.esm.js' - }, - extensions: ['.js', '.vue', '.json', '.css', '.node'] - }, - target: 'electron-renderer' -} - -/** - * Adjust rendererConfig for development settings - */ -if (!isProduction) { - rendererConfig.cache = { type: 'memory' } - // NOTE: Caching between builds is currently not possible because all SVGs are invalid on second build due to svgo-loader. - // rendererConfig.cache = { - // name: 'renderer-dev', - // type: 'filesystem' - // } - rendererConfig.plugins.push( - new webpack.DefinePlugin({ - '__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"` - }) - ) -} - -if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test' && - !process.env.MARKTEXT_DEV_HIDE_BROWSER_ANALYZER) { - rendererConfig.plugins.push( - new BundleAnalyzerPlugin() - ) -} - -// Fix debugger breakpoints -if (!isProduction && process.env.MARKTEXT_BUILD_VSCODE_DEBUG) { - rendererConfig.devtool = 'inline-source-map' -} - -/** - * Adjust rendererConfig for production settings - */ -if (isProduction) { - rendererConfig.devtool = 'nosources-source-map' - rendererConfig.mode = 'production' - rendererConfig.optimization.minimize = true - - rendererConfig.plugins.push( - new webpack.DefinePlugin({ - 'process.env.UNSPLASH_ACCESS_KEY': JSON.stringify(process.env.UNSPLASH_ACCESS_KEY) - }), - new MiniCssExtractPlugin({ - // Options similar to the same options in webpackOptions.output - // both options are optional - filename: '[name].[contenthash].css', - chunkFilename: '[id].[contenthash].css' - }), - new CopyWebpackPlugin({ - patterns: [ - { - from: path.join(__dirname, '../static'), - to: path.join(__dirname, '../dist/electron/static'), - globOptions: { - ignore: ['.*'] - } - }, - { - from: path.resolve(__dirname, '../node_modules/codemirror/mode/*/*').replace(/\\/g, '/'), - to: path.join(__dirname, '../dist/electron/codemirror/mode/[name]/[name][ext]') - } - ] - }) - ) -} - -module.exports = rendererConfig diff --git a/.eslintrc.js b/.eslintrc.js index 992d0e0d6..0f35f95eb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,29 +1,37 @@ module.exports = { - root: true, - parserOptions: { - parser: '@babel/eslint-parser', - ecmaVersion: 11, - ecmaFeatures: { - impliedStrict: true - }, - sourceType: 'module' - }, env: { browser: true, - es6: true, + es2021: true, node: true }, extends: [ 'standard', - 'eslint:recommended', - 'plugin:vue/base', - 'plugin:import/errors', - 'plugin:import/warnings' + 'plugin:vue/vue3-essential' + ], + overrides: [ + { + env: { + node: true + }, + files: [ + '.eslintrc.{js,cjs}' + ], + parserOptions: { + sourceType: 'script' + } + } ], globals: { __static: true }, - plugins: ['html', 'vue'], + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module' + }, + plugins: [ + 'html', + 'vue' + ], rules: { // Two spaces but disallow semicolons indent: ['error', 2, { 'SwitchCase': 1, 'ignoreComments': true }], diff --git a/.gitignore b/.gitignore index 2f74b8807..a3d98f03c 100644 --- a/.gitignore +++ b/.gitignore @@ -178,3 +178,5 @@ dist # .pnp.* # End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,node,yarn + +.vite diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index a1642c7d0..000000000 --- a/babel.config.js +++ /dev/null @@ -1,56 +0,0 @@ -const proposalClassProperties = require('@babel/plugin-proposal-class-properties') -const syntaxClassProperties = require('@babel/plugin-syntax-class-properties') -const transformRuntime = require('@babel/plugin-transform-runtime') -const syntaxDynamicImport = require('@babel/plugin-syntax-dynamic-import') -const functionBind = require('@babel/plugin-proposal-function-bind') -const exportDefault = require('@babel/plugin-proposal-export-default-from') -const isTanbul = require('babel-plugin-istanbul') -const component = require('babel-plugin-component') -const presetEnv = require('@babel/preset-env') - -const presetsHash = { - test: [ - [presetEnv, - { - targets: { 'node': 16 } - }] - ], - main: [ - [presetEnv, - { - targets: { 'node': 16 } - }] - ], - renderer: [ - [presetEnv, - { - useBuiltIns: false, - targets: { - electron: require('electron/package.json').version, - node: 16 - } - }] - ] -} - -module.exports = function (api) { - const plugins = [ proposalClassProperties, syntaxClassProperties, transformRuntime, syntaxDynamicImport, functionBind, exportDefault ] - const env = api.env() - const presets = presetsHash[env] - - if (env === 'test') { - plugins.push(isTanbul) - } else if (env === 'renderer') { - plugins.push( - [component, { - style: false, - libraryName: 'element-ui' - } - ]) - } - - return { - presets, - plugins - } -} diff --git a/forge.config.js b/forge.config.js new file mode 100644 index 000000000..2338ca070 --- /dev/null +++ b/forge.config.js @@ -0,0 +1,54 @@ +module.exports = { + packagerConfig: { + asar: true + }, + rebuildConfig: {}, + makers: [ + { + name: '@electron-forge/maker-squirrel', + config: {} + }, + { + name: '@electron-forge/maker-zip', + platforms: ['darwin'] + }, + { + name: '@electron-forge/maker-deb', + config: {} + }, + { + name: '@electron-forge/maker-rpm', + config: {} + } + ], + plugins: [ + { + name: '@electron-forge/plugin-auto-unpack-natives', + config: {} + }, + { + name: '@electron-forge/plugin-vite', + config: { + // `build` can specify multiple entry builds, which can be Main process, Preload scripts, Worker process, etc. + // If you are familiar with Vite configuration, it will look really familiar. + build: [ + { + // `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`. + entry: 'src/main/index.js', + config: 'vite.main.config.mjs' + }, + { + entry: 'src/main/preload.js', + config: 'vite.preload.config.mjs' + } + ], + renderer: [ + { + name: 'main_window', + config: 'vite.renderer.config.mjs' + } + ] + } + } + ] +} diff --git a/src/index.ejs b/index.html similarity index 74% rename from src/index.ejs rename to index.html index 7f1b9ded5..e0e3be721 100644 --- a/src/index.ejs +++ b/index.html @@ -61,12 +61,6 @@ } } - <% if (htmlWebpackPlugin.options.nodeModules) { %> - - - <% } %> @@ -84,11 +78,11 @@ const params = new URLSearchParams(window.location.search) const THEMES_COLOR = { 'one-dark': 'rgba(77, 120, 204, 1)', - 'dark': '#409eff', - 'graphite': 'rgb(104, 134, 170)', + dark: '#409eff', + graphite: 'rgb(104, 134, 170)', 'material-dark': '#f48237', - 'light': 'rgba(33, 181, 111, 1)', - 'ulysses': 'rgb(12, 139, 186)' + light: 'rgba(33, 181, 111, 1)', + ulysses: 'rgb(12, 139, 186)' } const dots = document.querySelectorAll('.dot') @@ -97,12 +91,7 @@ }) - - <% if (!htmlWebpackPlugin.options.isBrowser && !htmlWebpackPlugin.options.isDevelopment) { %> - - <% } %> + diff --git a/log.txt b/log.txt new file mode 100644 index 000000000..fd1cf4a07 --- /dev/null +++ b/log.txt @@ -0,0 +1,53 @@ +[STARTED] Checking your system +[STARTED] Checking git exists +[STARTED] Checking node version +[STARTED] Checking packageManager version +[TITLE] Found git@2.34.1 +[SUCCESS] Found git@2.34.1 +[TITLE] Found node@18.16.1 +[SUCCESS] Found node@18.16.1 +[TITLE] Found yarn@3.6.0 +[SUCCESS] Found yarn@3.6.0 +[SUCCESS] Checking your system +[STARTED] Locating application +[SUCCESS] Locating application +[STARTED] Loading configuration +[SUCCESS] Loading configuration +[STARTED] Preparing native dependencies +[TITLE] Preparing native dependencies +[TITLE] Preparing native dependencies: 0 / 1 +[TITLE] Preparing native dependencies: 1 / 1 +[TITLE] Preparing native dependencies: 1 / 2 +[TITLE] Preparing native dependencies: 2 / 2 +[TITLE] Preparing native dependencies: 2 / 3 +[TITLE] Preparing native dependencies: 3 / 3 +[TITLE] Preparing native dependencies: 3 / 4 +[TITLE] Preparing native dependencies: 4 / 4 +[SUCCESS] Preparing native dependencies: 4 / 4 +[STARTED] Running generateAssets hook +[SUCCESS] Running generateAssets hook +[STARTED] [plugin-vite] Launching dev servers for renderer process code + ➜ Local: http://localhost:5173/ + ➜ Network: use --host to expose +[SUCCESS] [plugin-vite] Launching dev servers for renderer process code +[STARTED] [plugin-vite] Compiling main process code +vite v4.3.9 building for development... + +watching for file changes... +vite v4.3.9 building for development... + +watching for file changes... + +build started... + +build started... +transforming... +transforming... +✓ 1 modules transformed. +rendering chunks... +computing gzip size... +.vite/build/preload.js 0.04 kB │ gzip: 0.06 kB +built in 569ms. +✓ 91 modules transformed. +[SUCCESS] [plugin-vite] Compiling main process code + diff --git a/package.json b/package.json index 3eaf6cf22..c6194810c 100644 --- a/package.json +++ b/package.json @@ -4,31 +4,18 @@ "homepage": "https://github.com/marktext/marktext/", "description": "Next generation markdown editor", "license": "MIT", - "main": "./dist/electron/main.js", + "main": ".vite/build/index.js", "scripts": { - "release": "echo 'Please run \"build\" or \"release:{linux,mac,win}\"' && exit 1", - "release:linux": "node .electron-vue/build.js && electron-builder build --linux", - "release:mac": "node .electron-vue/build.js && electron-builder build --mac", - "release:win": "node .electron-vue/build.js && electron-builder build --win", - "build": "node .electron-vue/build.js && electron-builder", - "build:bin": "node .electron-vue/build.js && electron-builder --dir", - "build:clean": "cross-env BUILD_TARGET=clean node .electron-vue/build.js", - "build:dev": "node .electron-vue/build.js", - "dev": "cross-env node .electron-vue/dev-runner.js", + "start": "electron-forge start", + "package": "electron-forge package", + "make": "electron-forge make", + "publish": "electron-forge publish", "e2e": "yarn run pack && cross-env MARKTEXT_EXIT_ON_ERROR=1 playwright test -c test/e2e/playwright.config.js test/e2e", "lint": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter src test", "lint:fix": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter --fix src test", - "pack": "yarn run pack:main && yarn run pack:renderer", - "pack:main": "cross-env NODE_ENV=production webpack --progress --config .electron-vue/webpack.main.config.js", - "pack:renderer": "cross-env NODE_ENV=production webpack --progress --config .electron-vue/webpack.renderer.config.js", - "postinstall": "node .electron-vue/postinstall.js && yarn run rebuild && yarn run lint:fix", "test": "yarn run unit && yarn run e2e", "test:specs": "node -r esm test/specs/commonMark/run.spec.js && node -r esm test/specs/gfm/run.spec.js", "unit": "cross-env NODE_ENV=test ELECTRON_DISABLE_SECURITY_WARNINGS=true karma start test/unit/karma.conf.js", - "preinstall": "node .electron-vue/preinstall.js", - "build:muya": "cd src/muya && webpack --progress --config webpack.config.js", - "release:muya": "yarn run build:muya && cd src/muya && yarn publish", - "rebuild": "electron-rebuild -f", "gen-third-party": "node tools/generateThirdPartyLicense.js", "validate-licenses": "node tools/validateLicenses.js", "deobfuscateStackTrace": "node tools/deobfuscateStackTrace.js" @@ -50,6 +37,7 @@ "dompurify": "^2.3.6", "dragula": "^3.7.3", "electron-log": "^4.4.6", + "electron-squirrel-startup": "^1.0.0", "electron-store": "^8.0.1", "electron-window-state": "^5.0.3", "element-resize-detector": "^1.2.4", @@ -82,61 +70,43 @@ "vega-embed": "^6.20.8", "vega-lite": "^5.2.0", "vscode-ripgrep": "^1.12.1", - "vue": "^2.6.14", + "vue": "^2.7.0", "vue-electron": "^1.0.6", "vue-router": "^3.5.3", "vuex": "^3.6.2", "webfontloader": "^1.6.28" }, "devDependencies": { - "@babel/core": "^7.17.7", - "@babel/eslint-parser": "^7.17.0", - "@babel/plugin-proposal-class-properties": "^7.16.7", - "@babel/plugin-proposal-export-default-from": "^7.16.7", - "@babel/plugin-proposal-function-bind": "^7.16.7", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.17.0", - "@babel/preset-env": "^7.16.11", - "@babel/register": "^7.17.7", - "@babel/runtime": "^7.17.7", + "@electron-forge/cli": "^6.2.1", + "@electron-forge/maker-deb": "^6.2.1", + "@electron-forge/maker-rpm": "^6.2.1", + "@electron-forge/maker-squirrel": "^6.2.1", + "@electron-forge/maker-zip": "^6.2.1", + "@electron-forge/plugin-auto-unpack-natives": "^6.2.1", + "@electron-forge/plugin-vite": "^6.2.1", "@markedjs/html-differ": "^3.0.4", "@playwright/test": "^1.20.0", - "babel-loader": "^8.2.3", - "babel-plugin-component": "^1.1.1", - "babel-plugin-istanbul": "^6.1.1", + "@types/node": "^16.15.1", + "@vitejs/plugin-vue2": "^2.2.0", "cfonts": "^2.10.0", "chai": "^4.3.6", "chalk": "^4.1.2", "cheerio": "^1.0.0-rc.10", - "copy-webpack-plugin": "^10.2.4", "cross-env": "^7.0.3", - "css-loader": "^6.7.1", "del": "^6.0.0", "devtron": "^1.4.0", "dotenv": "^16.0.0", - "electron": "^17.1.2", - "electron-builder": "^22.14.13", + "electron": "17.1.2", "electron-devtools-installer": "^3.2.0", - "electron-rebuild": "^3.2.7", "electron-updater": "^4.6.5", - "eslint": "^8.11.0", - "eslint-config-standard": "^17", - "eslint-friendly-formatter": "^4.0.1", + "eslint": "^8.0.1", + "eslint-config-standard": "latest", "eslint-import-resolver-alias": "^1.1.2", - "eslint-plugin-html": "^6.2.0", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-n": "^16.0.1", - "eslint-plugin-node": "^11.1.0", + "eslint-plugin-html": "^7.1.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", "eslint-plugin-promise": "^6.0.0", - "eslint-plugin-standard": "^4.1.0", - "eslint-plugin-vue": "^8.5.0", - "eslint-webpack-plugin": "^3.1.1", - "esm": "^3.2.25", - "file-loader": "^6.2.0", - "git-revision-webpack-plugin": "^5.0.0", - "html-webpack-plugin": "^5.5.0", - "imports-loader": "^0.8.0", + "eslint-plugin-vue": "latest", "karma": "^6.3.17", "karma-chai": "^0.1.0", "karma-coverage": "^2.2.0", @@ -144,38 +114,19 @@ "karma-mocha": "^2.0.1", "karma-sourcemap-loader": "^0.3.8", "karma-spec-reporter": "0.0.33", - "karma-webpack": "^5.0.0", "license-checker": "^25.0.1", "listr": "^0.14.3", "marked": "^1.2.9", - "mini-css-extract-plugin": "^2.6.0", "mocha": "^9.2.2", "node-fetch": "^2.6.7", - "node-loader": "^2.0.0", "path-browserify": "^1.0.1", "playwright": "^1.20.0", "postcss": "^8.4.12", - "postcss-loader": "^6.2.1", "postcss-preset-env": "^7.4.2", - "raw-loader": "^4.0.2", "require-dir": "^1.2.0", "stacktrace-parser": "^0.1.10", - "style-loader": "^3.3.1", - "svg-sprite-loader": "^6.0.11", "svgo": "^2.8.0", - "svgo-loader": "^3.0.0", - "to-string-loader": "^1.2.0", - "url-loader": "^4.1.1", - "vue-html-loader": "^1.2.4", - "vue-loader": "^15.9.8", - "vue-style-loader": "^4.1.3", - "vue-template-compiler": "^2.6.14", - "webpack": "^5.70.0", - "webpack-bundle-analyzer": "^4.5.0", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.7.4", - "webpack-hot-middleware": "^2.25.1", - "webpack-merge": "^5.8.0" + "vite": "^4.3.9" }, "resolutions": { "node-abi": "^3.8.0", diff --git a/src/main/app/index.js b/src/main/app/index.js index 8581ac8c1..a5777b06c 100644 --- a/src/main/app/index.js +++ b/src/main/app/index.js @@ -4,14 +4,14 @@ import { exec } from 'child_process' import dayjs from 'dayjs' import log from 'electron-log' import { app, BrowserWindow, clipboard, dialog, ipcMain, nativeTheme } from 'electron' -import { isChildOfDirectory } from 'common/filesystem/paths' +import { isChildOfDirectory } from '../../common/filesystem/paths' import { isLinux, isOsx, isWindows } from '../config' import parseArgs from '../cli/parser' import { normalizeAndResolvePath } from '../filesystem' import { normalizeMarkdownPath } from '../filesystem/markdown' import { registerKeyboardListeners } from '../keyboard' import { selectTheme } from '../menu/actions/theme' -import { dockMenu } from '../menu/templates' +import dockMenu from '../menu/templates/dock' import registerSpellcheckerListeners from '../spellchecker' import { watchers } from '../utils/imagePathAutoComplement' import { WindowType } from '../windows/base' diff --git a/src/main/app/paths.js b/src/main/app/paths.js index 9b7d244ce..f2f0d435d 100644 --- a/src/main/app/paths.js +++ b/src/main/app/paths.js @@ -1,6 +1,6 @@ import { app } from 'electron' -import EnvPaths from 'common/envPaths' -import { ensureDirSync } from 'common/filesystem' +import EnvPaths from '../../common/envPaths' +import { ensureDirSync } from '../../common/filesystem' class AppPaths extends EnvPaths { /** diff --git a/src/main/cli/index.js b/src/main/cli/index.js index 66399e3c3..735d167aa 100644 --- a/src/main/cli/index.js +++ b/src/main/cli/index.js @@ -1,7 +1,7 @@ import path from 'path' import { app } from 'electron' import os from 'os' -import { isDirectory } from 'common/filesystem' +import { isDirectory } from '../../common/filesystem' import parseArgs from './parser' import { getPath } from '../utils' diff --git a/src/main/commands/index.js b/src/main/commands/index.js index 3ae07978a..8505b208c 100644 --- a/src/main/commands/index.js +++ b/src/main/commands/index.js @@ -1,4 +1,4 @@ -import COMMAND_CONSTANTS from 'common/commands/constants' +import COMMAND_CONSTANTS from '../../common/commands/constants' import { loadFileCommands } from './file' import { loadTabCommands } from './tab' diff --git a/src/main/dataCenter/index.js b/src/main/dataCenter/index.js index 1927956b2..58c1aab2c 100644 --- a/src/main/dataCenter/index.js +++ b/src/main/dataCenter/index.js @@ -6,8 +6,8 @@ import keytar from 'keytar' import schema from './schema' import Store from 'electron-store' import log from 'electron-log' -import { ensureDirSync } from 'common/filesystem' -import { IMAGE_EXTENSIONS } from 'common/filesystem/paths' +import { ensureDirSync } from '../../common/filesystem' +import { IMAGE_EXTENSIONS } from '../../common/filesystem/paths' const DATA_CENTER_NAME = 'dataCenter' diff --git a/src/main/filesystem/index.js b/src/main/filesystem/index.js index 870738af3..adc983b30 100644 --- a/src/main/filesystem/index.js +++ b/src/main/filesystem/index.js @@ -1,6 +1,6 @@ import fs from 'fs-extra' import path from 'path' -import { isDirectory, isFile, isSymbolicLink } from 'common/filesystem' +import { isDirectory, isFile, isSymbolicLink } from '../../common/filesystem' /** * Normalize the path into an absolute path and resolves the link target if needed. diff --git a/src/main/filesystem/markdown.js b/src/main/filesystem/markdown.js index 46a01ce3f..2c852848b 100644 --- a/src/main/filesystem/markdown.js +++ b/src/main/filesystem/markdown.js @@ -3,8 +3,8 @@ import path from 'path' import log from 'electron-log' import iconv from 'iconv-lite' import { LINE_ENDING_REG, LF_LINE_ENDING_REG, CRLF_LINE_ENDING_REG } from '../config' -import { isDirectory2 } from 'common/filesystem' -import { isMarkdownFile } from 'common/filesystem/paths' +import { isDirectory2 } from '../../common/filesystem' +import { isMarkdownFile } from '../../common/filesystem/paths' import { normalizeAndResolvePath, writeFile } from '../filesystem' import { guessEncoding } from './encoding' diff --git a/src/main/filesystem/watcher.js b/src/main/filesystem/watcher.js index 7789865a9..9b94ab21b 100644 --- a/src/main/filesystem/watcher.js +++ b/src/main/filesystem/watcher.js @@ -2,8 +2,8 @@ import path from 'path' import fsPromises from 'fs/promises' import log from 'electron-log' import chokidar from 'chokidar' -import { exists } from 'common/filesystem' -import { hasMarkdownExtension, checkPathExcludePattern } from 'common/filesystem/paths' +import { exists } from '../../common/filesystem' +import { hasMarkdownExtension, checkPathExcludePattern } from '../../common/filesystem/paths' import { getUniqueId } from '../utils' import { loadMarkdownFile } from '../filesystem/markdown' import { isLinux, isOsx } from '../config' diff --git a/src/main/globalSetting.js b/src/main/globalSetting.js deleted file mode 100644 index 0184b5f15..000000000 --- a/src/main/globalSetting.js +++ /dev/null @@ -1,6 +0,0 @@ -import path from 'path' - -// Set `__static` path to static files in production. -if (process.env.NODE_ENV !== 'development') { - global.__static = path.join(__dirname, '/static').replace(/\\/g, '\\\\') -} diff --git a/src/main/index.js b/src/main/index.js index eb50b0d05..bcb56d91d 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -1,4 +1,3 @@ -import './globalSetting' import path from 'path' import { app, dialog } from 'electron' import { initialize as remoteInitializeServer } from '@electron/remote/main' @@ -27,6 +26,11 @@ if (!/^(darwin|win32|linux)$/i.test(process.platform)) { process.exit(1) } +// Handle creating/removing shortcuts on Windows when installing/uninstalling. +if (require('electron-squirrel-startup')) { + app.quit() +} + setupExceptionHandler() const args = cli() diff --git a/src/main/jsconfig.json b/src/main/jsconfig.json deleted file mode 100644 index fd304b3a5..000000000 --- a/src/main/jsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "moduleResolution": "node", - "target": "es2020", - "paths": { - "common/*": ["../common/*"] - } - }, - "include": ["."] -} diff --git a/src/main/keyboard/shortcutHandler.js b/src/main/keyboard/shortcutHandler.js index fbd4dd416..5644aacbe 100644 --- a/src/main/keyboard/shortcutHandler.js +++ b/src/main/keyboard/shortcutHandler.js @@ -4,8 +4,8 @@ import fsPromises from 'fs/promises' import path from 'path' import log from 'electron-log' import { electronLocalshortcut, isValidElectronAccelerator } from '@hfelix/electron-localshortcut' -import { isFile2 } from 'common/filesystem' -import { isEqualAccelerator } from 'common/keybinding' +import { isFile2 } from '../../common/filesystem' +import { isEqualAccelerator } from '../../common/keybinding' import { isLinux, isOsx } from '../config' import { getKeyboardInfo, keyboardLayoutMonitor } from '../keyboard' import keybindingsDarwin from './keybindingsDarwin' diff --git a/src/main/menu/actions/file.js b/src/main/menu/actions/file.js index 568cd5444..78200bc9d 100644 --- a/src/main/menu/actions/file.js +++ b/src/main/menu/actions/file.js @@ -2,8 +2,8 @@ import fs from 'fs-extra' import path from 'path' import { BrowserWindow, app, dialog, ipcMain, shell } from 'electron' import log from 'electron-log' -import { isDirectory, isFile, exists } from 'common/filesystem' -import { MARKDOWN_EXTENSIONS, isMarkdownFile } from 'common/filesystem/paths' +import { isDirectory, isFile, exists } from '../../../common/filesystem' +import { MARKDOWN_EXTENSIONS, isMarkdownFile } from '../../../common/filesystem/paths' import { checkUpdates, userSetting } from './marktext' import { showTabBar } from './view' import { COMMANDS } from '../../commands' diff --git a/src/main/menu/index.js b/src/main/menu/index.js index 3b640e256..6eb746cf3 100644 --- a/src/main/menu/index.js +++ b/src/main/menu/index.js @@ -2,7 +2,7 @@ import fs from 'fs' import path from 'path' import { app, ipcMain, Menu } from 'electron' import log from 'electron-log' -import { ensureDirSync, isDirectory2, isFile2 } from 'common/filesystem' +import { ensureDirSync, isDirectory2, isFile2 } from '../../common/filesystem' import { isLinux, isOsx, isWindows } from '../config' import { updateSidebarMenu } from '../menu/actions/edit' import { updateFormatMenu } from '../menu/actions/format' diff --git a/src/main/menu/templates/help.js b/src/main/menu/templates/help.js index 7cfdf495b..a73c65416 100755 --- a/src/main/menu/templates/help.js +++ b/src/main/menu/templates/help.js @@ -1,6 +1,6 @@ import path from 'path' import { shell } from 'electron' -import { isFile } from 'common/filesystem' +import { isFile } from '../../../common/filesystem' import * as actions from '../actions/help' import { checkUpdates } from '../actions/marktext' diff --git a/src/main/menu/templates/index.js b/src/main/menu/templates/index.js index b404fe33a..9b92fa614 100644 --- a/src/main/menu/templates/index.js +++ b/src/main/menu/templates/index.js @@ -9,8 +9,6 @@ import paragraph from './paragraph' import format from './format' import theme from './theme' -export dockMenu from './dock' - /** * Create the setting window menu. * diff --git a/src/main/preferences/index.js b/src/main/preferences/index.js index 95ceac272..9416a861e 100644 --- a/src/main/preferences/index.js +++ b/src/main/preferences/index.js @@ -7,6 +7,7 @@ import log from 'electron-log' import { isWindows } from '../config' import { hasSameKeys } from '../utils' import schema from './schema' +import __static from '../utils/static' const PREFERENCES_FILE_NAME = 'preferences' @@ -29,7 +30,7 @@ class Preference extends EventEmitter { name: PREFERENCES_FILE_NAME }) - this.staticPath = path.join(__static, 'preference.json') + this.staticPath = path.join(__static(), 'preference.json') this.init() } diff --git a/src/main/preload.js b/src/main/preload.js new file mode 100644 index 000000000..736f19f9e --- /dev/null +++ b/src/main/preload.js @@ -0,0 +1 @@ +console.log('preload') diff --git a/src/main/utils/imagePathAutoComplement.js b/src/main/utils/imagePathAutoComplement.js index 235c86c6a..a3fe91b27 100644 --- a/src/main/utils/imagePathAutoComplement.js +++ b/src/main/utils/imagePathAutoComplement.js @@ -2,8 +2,8 @@ import fs from 'fs' import path from 'path' import { filter } from 'fuzzaldrin' import log from 'electron-log' -import { isDirectory, isFile } from 'common/filesystem' -import { IMAGE_EXTENSIONS } from 'common/filesystem/paths' +import { isDirectory, isFile } from '../../common/filesystem' +import { IMAGE_EXTENSIONS } from '../../common/filesystem/paths' import { BLACK_LIST } from '../config' // TODO(need::refactor): Refactor this file. Just return an array of directories and files without caching and watching? diff --git a/src/main/utils/pandoc.js b/src/main/utils/pandoc.js index a04f80fd9..3fc0f4c49 100644 --- a/src/main/utils/pandoc.js +++ b/src/main/utils/pandoc.js @@ -1,7 +1,7 @@ // Copy from https://github.com/utatti/simple-pandoc/blob/master/index.js import { spawn } from 'child_process' import commandExists from 'command-exists' -import { isFile2 } from 'common/filesystem' +import { isFile2 } from '../../common/filesystem' const pandocCommand = 'pandoc' diff --git a/src/main/utils/static.js b/src/main/utils/static.js new file mode 100644 index 000000000..433aaa219 --- /dev/null +++ b/src/main/utils/static.js @@ -0,0 +1,7 @@ +import { app } from 'electron' +import path from 'path' + +export default function __static () { + console.log(app.getAppPath()) + return path.join(app.getAppPath(), '/static').replace(/\\/g, '\\\\') +} diff --git a/src/main/windows/editor.js b/src/main/windows/editor.js index c35294e13..d5c1f761c 100644 --- a/src/main/windows/editor.js +++ b/src/main/windows/editor.js @@ -3,13 +3,14 @@ import { BrowserWindow, dialog, ipcMain } from 'electron' import { enable as remoteEnable } from '@electron/remote/main' import log from 'electron-log' import windowStateKeeper from 'electron-window-state' -import { isChildOfDirectory, isSamePathSync } from 'common/filesystem/paths' +import { isChildOfDirectory, isSamePathSync } from '../../common/filesystem/paths' import BaseWindow, { WindowLifecycle, WindowType } from './base' import { ensureWindowPosition, zoomIn, zoomOut } from './utils' import { TITLE_BAR_HEIGHT, editorWinOptions, isLinux, isOsx } from '../config' import { showEditorContextMenu } from '../contextMenu/editor' import { loadMarkdownFile } from '../filesystem/markdown' import { switchLanguage } from '../spellchecker' +import __static from '../utils/static' class EditorWindow extends BaseWindow { /** @@ -50,7 +51,7 @@ class EditorWindow extends BaseWindow { const { x, y, width, height } = ensureWindowPosition(mainWindowState) const winOptions = Object.assign({ x, y, width, height }, editorWinOptions, options) if (isLinux) { - winOptions.icon = path.join(__static, 'logo-96px.png') + winOptions.icon = path.join(__static(), 'logo-96px.png') } const { diff --git a/src/main/windows/setting.js b/src/main/windows/setting.js index a1add9bed..e13c3fe7c 100644 --- a/src/main/windows/setting.js +++ b/src/main/windows/setting.js @@ -5,6 +5,7 @@ import { electronLocalshortcut } from '@hfelix/electron-localshortcut' import BaseWindow, { WindowLifecycle, WindowType } from './base' import { centerWindowOptions } from './utils' import { TITLE_BAR_HEIGHT, preferencesWinOptions, isLinux, isOsx } from '../config' +import __static from '../utils/static' class SettingWindow extends BaseWindow { /** @@ -25,7 +26,7 @@ class SettingWindow extends BaseWindow { const winOptions = Object.assign({}, preferencesWinOptions) centerWindowOptions(winOptions) if (isLinux) { - winOptions.icon = path.join(__static, 'logo-96px.png') + winOptions.icon = path.join(__static(), 'logo-96px.png') } // WORKAROUND: Electron has issues with different DPI per monitor when diff --git a/src/renderer/commands/fileEncoding.js b/src/renderer/commands/fileEncoding.js index 0c8d833f3..b490d64e9 100644 --- a/src/renderer/commands/fileEncoding.js +++ b/src/renderer/commands/fileEncoding.js @@ -1,6 +1,6 @@ import { ipcRenderer } from 'electron' -import { ENCODING_NAME_MAP, getEncodingName } from 'common/encoding' -import { delay } from '@/util' +import { ENCODING_NAME_MAP, getEncodingName } from '../../common/encoding' +import { delay } from '../util' import bus from '../bus' class FileEncodingCommand { diff --git a/src/renderer/commands/index.js b/src/renderer/commands/index.js index 1c9b15d19..935506901 100644 --- a/src/renderer/commands/index.js +++ b/src/renderer/commands/index.js @@ -2,7 +2,7 @@ import { ipcRenderer, shell } from 'electron' import { getCurrentWindow } from '@electron/remote' import bus from '../bus' -import { delay, isOsx } from '@/util' +import { delay, isOsx } from '../util' import { isUpdatable } from './utils' import getCommandDescriptionById from './descriptions' diff --git a/src/renderer/commands/lineEnding.js b/src/renderer/commands/lineEnding.js index 4f596b634..7d9ee4e88 100644 --- a/src/renderer/commands/lineEnding.js +++ b/src/renderer/commands/lineEnding.js @@ -1,5 +1,5 @@ import { ipcRenderer } from 'electron' -import { delay } from '@/util' +import { delay } from '../util' import bus from '../bus' const crlfDescription = 'Carriage return and line feed (CRLF)' diff --git a/src/renderer/commands/quickOpen.js b/src/renderer/commands/quickOpen.js index 32ea3b05f..6dc400dfd 100644 --- a/src/renderer/commands/quickOpen.js +++ b/src/renderer/commands/quickOpen.js @@ -2,8 +2,8 @@ import path from 'path' import { ipcRenderer } from 'electron' import { isChildOfDirectory, hasMarkdownExtension, MARKDOWN_INCLUSIONS } from '../../common/filesystem/paths' import bus from '../bus' -import { delay } from '@/util' -import FileSearcher from '@/node/fileSearcher' +import { delay } from '../util' +import FileSearcher from '../node/fileSearcher' const SPECIAL_CHARS = /[\[\]\\^$.\|\?\*\+\(\)\/]{1}/g // eslint-disable-line no-useless-escape diff --git a/src/renderer/commands/spellcheckerLanguage.js b/src/renderer/commands/spellcheckerLanguage.js index 81a84a178..1d3d4a667 100644 --- a/src/renderer/commands/spellcheckerLanguage.js +++ b/src/renderer/commands/spellcheckerLanguage.js @@ -1,8 +1,8 @@ import bus from '../bus' -import notice from '@/services/notification' -import { delay } from '@/util' -import { SpellChecker } from '@/spellchecker' -import { getLanguageName } from '@/spellchecker/languageMap' +import notice from '../services/notification' +import { delay } from '../util' +import { SpellChecker } from '../spellchecker' +import { getLanguageName } from '../spellchecker/languageMap' // Command to switch the spellchecker language class SpellcheckerLanguageCommand { diff --git a/src/renderer/commands/trailingNewline.js b/src/renderer/commands/trailingNewline.js index b45df714f..b85840a34 100644 --- a/src/renderer/commands/trailingNewline.js +++ b/src/renderer/commands/trailingNewline.js @@ -1,5 +1,5 @@ import { ipcRenderer } from 'electron' -import { delay } from '@/util' +import { delay } from '../util' import bus from '../bus' const descriptions = [ diff --git a/src/renderer/components/editorWithTabs/editor.vue b/src/renderer/components/editorWithTabs/editor.vue index 293226320..e57132faa 100644 --- a/src/renderer/components/editorWithTabs/editor.vue +++ b/src/renderer/components/editorWithTabs/editor.vue @@ -80,36 +80,36 @@ import { mapState } from 'vuex' // import ViewImage from 'view-image' import { isChildOfDirectory } from 'common/filesystem/paths' import Muya from 'muya/lib' -import TablePicker from 'muya/lib/ui/tablePicker' -import QuickInsert from 'muya/lib/ui/quickInsert' -import CodePicker from 'muya/lib/ui/codePicker' -import EmojiPicker from 'muya/lib/ui/emojiPicker' -import ImagePathPicker from 'muya/lib/ui/imagePicker' -import ImageSelector from 'muya/lib/ui/imageSelector' -import ImageToolbar from 'muya/lib/ui/imageToolbar' -import Transformer from 'muya/lib/ui/transformer' -import FormatPicker from 'muya/lib/ui/formatPicker' -import LinkTools from 'muya/lib/ui/linkTools' -import FootnoteTool from 'muya/lib/ui/footnoteTool' -import TableBarTools from 'muya/lib/ui/tableTools' -import FrontMenu from 'muya/lib/ui/frontMenu' +import TablePicker from '../../../muya/lib/ui/tablePicker' +import QuickInsert from '../../../muya/lib/ui/quickInsert' +import CodePicker from '../../../muya/lib/ui/codePicker' +import EmojiPicker from '../../../muya/lib/ui/emojiPicker' +import ImagePathPicker from '../../../muya/lib/ui/imagePicker' +import ImageSelector from '../../../muya/lib/ui/imageSelector' +import ImageToolbar from '../../../muya/lib/ui/imageToolbar' +import Transformer from '../../../muya/lib/ui/transformer' +import FormatPicker from '../../../muya/lib/ui/formatPicker' +import LinkTools from '../../../muya/lib/ui/linkTools' +import FootnoteTool from '../../../muya/lib/ui/footnoteTool' +import TableBarTools from '../../../muya/lib/ui/tableTools' +import FrontMenu from '../../../muya/lib/ui/frontMenu' import Search from '../search' -import bus from '@/bus' -import { DEFAULT_EDITOR_FONT_FAMILY } from '@/config' -import notice from '@/services/notification' -import Printer from '@/services/printService' -import { SpellcheckerLanguageCommand } from '@/commands' -import { SpellChecker } from '@/spellchecker' -import { isOsx, animatedScrollTo } from '@/util' -import { moveImageToFolder, moveToRelativeFolder, uploadImage } from '@/util/fileSystem' -import { guessClipboardFilePath } from '@/util/clipboard' -import { getCssForOptions, getHtmlToc } from '@/util/pdf' -import { addCommonStyle, setEditorWidth, setWrapCodeBlocks } from '@/util/theme' - -import 'muya/themes/default.css' -import '@/assets/themes/codemirror/one-dark.css' +import bus from '../../bus' +import { DEFAULT_EDITOR_FONT_FAMILY } from '../../config' +import notice from '../../services/notification' +import Printer from '../../services/printService' +import { SpellcheckerLanguageCommand } from '../../commands' +import { SpellChecker } from '../../spellchecker' +import { isOsx, animatedScrollTo } from '../../util' +import { moveImageToFolder, moveToRelativeFolder, uploadImage } from '../../util/fileSystem' +import { guessClipboardFilePath } from '../../util/clipboard' +import { getCssForOptions, getHtmlToc } from '../../util/pdf' +import { addCommonStyle, setEditorWidth, setWrapCodeBlocks } from '../../util/theme' + +import '../../../muya/themes/default.css' +import '../../assets/themes/codemirror/one-dark.css' // import 'view-image/lib/imgViewer.css' -import CloseIcon from '@/assets/icons/close.svg' +import CloseIcon from '../../assets/icons/close.svg' const STANDAR_Y = 320 diff --git a/src/renderer/components/editorWithTabs/sourceCode.vue b/src/renderer/components/editorWithTabs/sourceCode.vue index 687a505d6..65cebae73 100644 --- a/src/renderer/components/editorWithTabs/sourceCode.vue +++ b/src/renderer/components/editorWithTabs/sourceCode.vue @@ -8,11 +8,11 @@ - - diff --git a/package.json b/package.json index f9cbf224f..ba70d4112 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,6 @@ "element-ui": "^2.15.7", "execall": "^2.0.0", "flowchart.js": "^1.17.1", - "fs-extra": "^10.0.1", "fuzzaldrin": "^2.1.0", "github-markdown-css": "^3.0.1", "html-tags": "^3.1.0", @@ -55,6 +54,7 @@ "keytar": "^7.9.0", "mermaid": "^9.2.2", "minizlib": "^2.1.2", + "mkdirp": "^3.0.1", "native-keymap": "^3.3.0", "node-system-fonts": "^1.0.1", "plist": "^3.0.4", @@ -127,7 +127,8 @@ "require-dir": "^1.2.0", "stacktrace-parser": "^0.1.10", "svgo": "^2.8.0", - "vite": "^4.3.9" + "vite": "^4.3.9", + "vite-plugin-electron-renderer": "^0.14.5" }, "resolutions": { "node-abi": "^3.8.0", diff --git a/src/common/filesystem/index.js b/src/common/filesystem/index.js index 02507adb3..abe11a085 100644 --- a/src/common/filesystem/index.js +++ b/src/common/filesystem/index.js @@ -1,6 +1,7 @@ -import fs from 'fs-extra' +import fs from 'fs' import fsPromises from 'fs/promises' import path from 'path' +import { mkdirpSync } from 'mkdirp' /** * Test whether or not the given path exists. @@ -24,7 +25,7 @@ export const exists = async p => { */ export const ensureDirSync = dirPath => { try { - fs.ensureDirSync(dirPath) + mkdirpSync(dirPath) } catch (e) { if (e.code !== 'EEXIST') { throw e diff --git a/src/main/filesystem/index.js b/src/main/filesystem/index.js index adc983b30..6f96eb81d 100644 --- a/src/main/filesystem/index.js +++ b/src/main/filesystem/index.js @@ -1,6 +1,7 @@ -import fs from 'fs-extra' -import path from 'path' +import fs from 'fs/promises' +import path, { dirname } from 'path' import { isDirectory, isFile, isSymbolicLink } from '../../common/filesystem' +import { mkdirp } from 'mkdirp' /** * Normalize the path into an absolute path and resolves the link target if needed. @@ -22,11 +23,12 @@ export const normalizeAndResolvePath = pathname => { return path.resolve(pathname) } -export const writeFile = (pathname, content, extension, options = 'utf-8') => { +export const writeFile = async (pathname, content, extension, options = 'utf-8') => { if (!pathname) { return Promise.reject(new Error('[ERROR] Cannot save file without path.')) } pathname = !extension || pathname.endsWith(extension) ? pathname : `${pathname}${extension}` - return fs.outputFile(pathname, content, options) + await mkdirp(dirname(pathname)) + return fs.writeFile(pathname, content, options) } diff --git a/src/main/menu/actions/file.js b/src/main/menu/actions/file.js index 78200bc9d..2e0386e1b 100644 --- a/src/main/menu/actions/file.js +++ b/src/main/menu/actions/file.js @@ -1,4 +1,4 @@ -import fs from 'fs-extra' +import fs from 'fs' import path from 'path' import { BrowserWindow, app, dialog, ipcMain, shell } from 'electron' import log from 'electron-log' diff --git a/src/renderer/util/fileSystem.js b/src/renderer/util/fileSystem.js index 62bfd80cd..406832a88 100644 --- a/src/renderer/util/fileSystem.js +++ b/src/renderer/util/fileSystem.js @@ -1,28 +1,32 @@ -import path from 'path' +import path, { dirname } from 'path' import crypto from 'crypto' -import fs from 'fs-extra' -import { statSync, constants } from 'fs' +import { statSync } from 'fs' +import fs, { constants } from 'fs/promises' import cp from 'child_process' import { tmpdir } from 'os' import dayjs from 'dayjs' import { Octokit } from '@octokit/rest' import { isImageFile } from '../../common/filesystem/paths' import { isWindows } from './index' +import { mkdirp } from 'mkdirp' export const create = async (pathname, type) => { - return type === 'directory' - ? fs.ensureDir(pathname) - : fs.outputFile(pathname, '') + if (type === 'directory') { + await mkdirp(pathname) + } else { + await mkdirp(dirname(pathname)) + return fs.writeFile(pathname, '') + } } export const paste = async ({ src, dest, type }) => { return type === 'cut' - ? fs.move(src, dest) - : fs.copy(src, dest) + ? fs.rename(src, dest) + : fs.cp(src, dest) } export const rename = async (src, dest) => { - return fs.move(src, dest) + return fs.rename(src, dest) } export const getHash = (content, encoding, type) => { @@ -55,8 +59,8 @@ export const moveToRelativeFolder = async (cwd, relativeName, filePath, imagePat // - root directory + relative directory name const absPath = path.resolve(cwd, relativeName) const dstPath = path.resolve(absPath, path.basename(imagePath)) - await fs.ensureDir(absPath) - await fs.move(imagePath, dstPath, { overwrite: true }) + await mkdirp(absPath) + await fs.mv(imagePath, dstPath, { overwrite: true }) // Find relative path between given file and saved image. const dstRelPath = path.relative(path.dirname(filePath), dstPath) @@ -69,7 +73,7 @@ export const moveToRelativeFolder = async (cwd, relativeName, filePath, imagePat } export const moveImageToFolder = async (pathname, image, outputDir) => { - await fs.ensureDir(outputDir) + await mkdirp(outputDir) const isPath = typeof image === 'string' if (isPath) { const dirname = path.dirname(pathname) @@ -85,7 +89,7 @@ export const moveImageToFolder = async (pathname, image, outputDir) => { const hash = getContentHash(imagePath) // To avoid name conflict. const hashFilePath = path.join(outputDir, `${hash}${extname}`) - await fs.copy(imagePath, hashFilePath) + await fs.cp(imagePath, hashFilePath) return hashFilePath } else { return Promise.resolve(image) @@ -237,7 +241,7 @@ export const uploadImage = async (pathname, image, preferences) => { return promise } -export const isFileExecutableSync = (filepath) => { +export const isFileExecutableSync = async (filepath) => { try { const stat = statSync(filepath) if (process.platform === 'win32') { diff --git a/vite.renderer.config.mjs b/vite.renderer.config.mjs index 652e7f1b0..198469672 100644 --- a/vite.renderer.config.mjs +++ b/vite.renderer.config.mjs @@ -1,13 +1,12 @@ -import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue2' -import { builtinModules } from 'module' +import { defineConfig, splitVendorChunkPlugin } from 'vite' +import renderer from 'vite-plugin-electron-renderer' // https://vitejs.dev/config export default defineConfig({ - plugins: [vue()], - build: { - rollupOptions: { - external: builtinModules - } - } + plugins: [ + vue(), + splitVendorChunkPlugin(), + renderer() + ] }) diff --git a/yarn.lock b/yarn.lock index 728e49143..edc1ec4b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5367,7 +5367,7 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^10.0.0, fs-extra@npm:^10.0.1, fs-extra@npm:^10.1.0": +"fs-extra@npm:^10.0.0, fs-extra@npm:^10.1.0": version: 10.1.0 resolution: "fs-extra@npm:10.1.0" dependencies: @@ -7602,7 +7602,6 @@ __metadata: eslint-plugin-vue: latest execall: ^2.0.0 flowchart.js: ^1.17.1 - fs-extra: ^10.0.1 fuzzaldrin: ^2.1.0 github-markdown-css: ^3.0.1 html-tags: ^3.1.0 @@ -7623,6 +7622,7 @@ __metadata: marked: ^1.2.9 mermaid: ^9.2.2 minizlib: ^2.1.2 + mkdirp: ^3.0.1 mocha: ^9.2.2 native-keymap: ^3.3.0 node-fetch: ^2.6.7 @@ -7648,6 +7648,7 @@ __metadata: vega-embed: ^6.20.8 vega-lite: ^5.2.0 vite: ^4.3.9 + vite-plugin-electron-renderer: ^0.14.5 vscode-ripgrep: ^1.12.1 vue: ^2.7.0 vue-electron: ^1.0.6 @@ -7971,6 +7972,15 @@ __metadata: languageName: node linkType: hard +"mkdirp@npm:^3.0.1": + version: 3.0.1 + resolution: "mkdirp@npm:3.0.1" + bin: + mkdirp: dist/cjs/src/bin.js + checksum: 972deb188e8fb55547f1e58d66bd6b4a3623bf0c7137802582602d73e6480c1c2268dcbafbfb1be466e00cc7e56ac514d7fd9334b7cf33e3e2ab547c16f83a8d + languageName: node + linkType: hard + "mocha@npm:^9.2.2": version: 9.2.2 resolution: "mocha@npm:9.2.2" @@ -11569,6 +11579,13 @@ __metadata: languageName: node linkType: hard +"vite-plugin-electron-renderer@npm:^0.14.5": + version: 0.14.5 + resolution: "vite-plugin-electron-renderer@npm:0.14.5" + checksum: 50628357bcf4cd54c7b804565878ee45f57cfabeb6466dbc5330e2b48c9282f187618476fd998948cf4965332af3fbab58dbe01b6c27debdb0994f52e5a1c2b9 + languageName: node + linkType: hard + "vite@npm:^4.1.1, vite@npm:^4.3.9": version: 4.3.9 resolution: "vite@npm:4.3.9" From 0d9ec833c8afa5ac7841f90becbaa7da0b2cf196 Mon Sep 17 00:00:00 2001 From: Axel Rindle Date: Sat, 8 Jul 2023 22:46:08 +0200 Subject: [PATCH 09/10] Remove log --- src/main/utils/static.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/utils/static.js b/src/main/utils/static.js index 433aaa219..25269bc13 100644 --- a/src/main/utils/static.js +++ b/src/main/utils/static.js @@ -2,6 +2,5 @@ import { app } from 'electron' import path from 'path' export default function __static () { - console.log(app.getAppPath()) return path.join(app.getAppPath(), '/static').replace(/\\/g, '\\\\') } From 6592ac10e2f9f062f7b127c1a6dea61322c9f2dc Mon Sep 17 00:00:00 2001 From: Axel Rindle Date: Sat, 8 Jul 2023 22:51:42 +0200 Subject: [PATCH 10/10] Replace resolvePath with resolvePathFn --- src/main/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/index.js b/src/main/index.js index bcb56d91d..99e9e5953 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -12,7 +12,7 @@ import { getLogLevel } from './utils' const initializeLogger = appEnvironment => { log.transports.console.level = process.env.NODE_ENV === 'development' ? 'info' : 'error' log.transports.rendererConsole = null - log.transports.file.resolvePath = () => path.join(appEnvironment.paths.logPath, 'main.log') + log.transports.file.resolvePathFn = () => path.join(appEnvironment.paths.logPath, 'main.log') log.transports.file.level = getLogLevel() log.transports.file.sync = true initExceptionLogger()