From 3a7e4a05ccf15bb37be6a29ac3d8df5bd2d5b695 Mon Sep 17 00:00:00 2001 From: kuaifan Date: Fri, 9 Jul 2021 13:51:29 +0800 Subject: [PATCH] no message --- cmd | 4 +- electron/build.js | 190 +++++++++++++++++++++++++++++++++++++ package.json | 14 +-- resources/assets/js/app.js | 3 +- webpack.mix.js | 51 ++++++---- 5 files changed, 228 insertions(+), 34 deletions(-) create mode 100644 electron/build.js diff --git a/cmd b/cmd index d75d8d4a..1f726442 100755 --- a/cmd +++ b/cmd @@ -138,14 +138,14 @@ if [ $# -gt 0 ];then check_node $COMPOSE exec php /bin/bash -c "php bin/run --mode=dev" supervisorctl_restart php - npm run hot + mix watch --hot elif [[ "$1" == "prod" ]]; then shift 1 check_node $COMPOSE exec php /bin/bash -c "php bin/run --mode=prod" supervisorctl_restart php rm -rf "./public/js/build" - npm run prod + mix --production elif [[ "$1" == "super" ]]; then shift 1 supervisorctl_restart "$@" diff --git a/electron/build.js b/electron/build.js new file mode 100644 index 00000000..8ff025a1 --- /dev/null +++ b/electron/build.js @@ -0,0 +1,190 @@ +const fs = require('fs'); +const path = require('path') +const inquirer = require('inquirer'); +const child_process = require('child_process'); +const config = require('../package.json') + +// 删除 +function deleteFile(path) { + let files = []; + if( fs.existsSync(path) ) { + files = fs.readdirSync(path); + files.forEach(function(file,index){ + let curPath = path + "/" + file; + if(fs.statSync(curPath).isDirectory()) { + deleteFile(curPath); + } else { + fs.unlinkSync(curPath); + } + }); + fs.rmdirSync(path); + } +} + +// 复制文件 +function copyFile(srcPath, tarPath, cb) { + let rs = fs.createReadStream(srcPath) + rs.on('error', function (err) { + if (err) { + console.log('read error', srcPath) + } + cb && cb(err) + }) + let ws = fs.createWriteStream(tarPath) + ws.on('error', function (err) { + if (err) { + console.log('write error', tarPath) + } + cb && cb(err) + }) + ws.on('close', function (ex) { + cb && cb(ex) + }) + rs.pipe(ws) +} + +// 复制文件夹所有 +function copyDir(srcDir, tarDir, cb) { + if (fs.existsSync(tarDir)) { + fs.readdir(srcDir, function (err, files) { + let count = 0 + let checkEnd = function () { + ++count == files.length && cb && cb() + } + if (err) { + checkEnd() + return + } + files.forEach(function (file) { + let srcPath = path.join(srcDir, file) + let tarPath = path.join(tarDir, file) + fs.stat(srcPath, function (err, stats) { + if (stats.isDirectory()) { + fs.mkdir(tarPath, function (err) { + if (err) { + return + } + copyDir(srcPath, tarPath, checkEnd) + }) + } else { + copyFile(srcPath, tarPath, checkEnd) + } + }) + }) + //为空时直接回调 + files.length === 0 && cb && cb() + }) + } else { + fs.mkdir(tarDir, function (err) { + if (err) { + return + } + copyDir(srcDir, tarDir, cb) + }) + } +} + +// 给地址加上前后 +function formatUrl(str) { + let url; + if (str.substring(0, 7) === "http://" || + str.substring(0, 8) === "https://") { + url = str.trim(); + } else { + url = "http://" + str.trim(); + } + if (url.substring(url.length - 1) != "/") { + url+= "/" + } + return url; +} + +// 运行命令 +function exec(command, quiet) { + return new Promise((resolve, reject) => { + try { + let child = child_process.exec(command, {encoding: 'utf8'}, () => { + resolve(); + }); + if (!quiet) { + child.stdout.pipe(process.stdout); + } + child.stderr.pipe(process.stderr); + } catch (e) { + console.error('execute command failed :', command); + reject(e); + } + }) +} + +/** ***************************************************************************************************/ +/** ***************************************************************************************************/ +/** ***************************************************************************************************/ + +const electronDir = path.resolve(__dirname, "public"); +const nativeCachePath = path.resolve(__dirname, ".native"); +if (fs.existsSync(electronDir)) { + deleteFile(electronDir); +} +fs.mkdirSync(electronDir); +copyFile(path.resolve(__dirname, "index.html"), electronDir + "/index.html") + +const platform = ["build-mac-intel", "build-mac-m1", "build-win"]; +const questions = [ + { + type: 'input', + name: 'targetUrl', + message: "请输入网站地址", + default: () => { + if (fs.existsSync(nativeCachePath)) { + return fs.readFileSync(nativeCachePath, 'utf8'); + } + return undefined; + }, + validate: function (value) { + return value !== '' + } + }, + { + type: 'list', + name: 'platform', + message: "选择编译系统平台", + choices: [{ + name: "MacOS Intel", + value: [platform[0]] + }, { + name: "MacOS M1", + value: [platform[1]] + }, { + name: "Window x86_64", + value: [platform[2]] + }, { + name: "All platforms", + value: platform + }] + } +]; + +inquirer.prompt(questions).then(answers => { + let data = `window.systemInformation = { + version: "${config.version}", + origin: "./", + apiUrl: "${formatUrl(answers.targetUrl)}api/" + }`; + fs.writeFileSync(nativeCachePath, formatUrl(answers.targetUrl)); + fs.writeFileSync(electronDir + "/config.js", data, 'utf8'); + // + let packageFile = path.resolve(__dirname, "package.json"); + let packageString = fs.readFileSync(packageFile, 'utf8'); + packageString = packageString.replace(/"version":\s*"(.*?)"/, `"version": "${config.version}"`); + packageString = packageString.replace(/"name":\s*"(.*?)"/, `"name": "${config.name}"`); + fs.writeFileSync(packageFile, packageString, 'utf8'); + // + child_process.spawnSync("mix", ["--production", "--", "--env", "--electron"], {stdio: "inherit"}); + answers.platform.forEach(item => { + child_process.spawn("npm", ["run", item], {stdio: "inherit", cwd: "electron"}); + }) +}); + + + diff --git a/package.json b/package.json index 21aa0433..d02033b0 100644 --- a/package.json +++ b/package.json @@ -3,16 +3,10 @@ "version": "0.2.71", "description": "DooTask is task management system.", "scripts": { - "dev": "npm run development", - "development": "mix", - "watch": "mix watch", - "watch-poll": "mix watch -- --watch-options-poll=1000", - "hot": "mix watch --hot", - "prod": "npm run production", - "production": "mix --production", - "version": "node ./version.js", - "electron-start": "node ./electron/index.js start", - "electron-build": "node ./electron/index.js build" + "start": "./cmd dev", + "build": "./cmd prod", + "build-electron": "node ./electron/build.js", + "version": "node ./version.js" }, "devDependencies": { "axios": "^0.21", diff --git a/resources/assets/js/app.js b/resources/assets/js/app.js index f10629d6..a49225f9 100644 --- a/resources/assets/js/app.js +++ b/resources/assets/js/app.js @@ -50,8 +50,9 @@ const originalPush = VueRouter.prototype.push VueRouter.prototype.push = function push(location) { return originalPush.call(this, location).catch(err => err) } + const router = new VueRouter({ - mode: 'hash', + mode: __PLATFORM === "web" ? 'history' : 'hash', routes }); diff --git a/webpack.mix.js b/webpack.mix.js index 973f0230..988bdf05 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -1,7 +1,8 @@ const mix = require('laravel-mix'); const ipv4 = require('internal-ip').v4.sync(); +const argv = process.argv; -const mixBuildName = function (str) { +let mixBuildName = function (str) { if (typeof str !== "string") { return str; } @@ -11,28 +12,36 @@ const mixBuildName = function (str) { return str.replace(/_/g, '/'); } -/* - |-------------------------------------------------------------------------- - | Mix Asset Management - |-------------------------------------------------------------------------- - | - | Mix provides a clean, fluent API for defining some Webpack build steps - | for your Laravel applications. By default, we are compiling the CSS - | file for the application as well as bundling up all the JS files. - | - */ +let output = { + chunkFilename: function ({chunk}) { + return `js/build/${mixBuildName(chunk.id)}.js` + } +}; +if (!['--watch', '--hot'].includes(argv[3])) { + output.publicPath = './'; +} + +let platform = "web"; +let publicPath = 'public' +if (argv[4] === '--electron') { + platform = "electron" + publicPath = 'electron/public'; +} mix - .copy('resources/assets/statics/public', 'public') - .js('resources/assets/js/app.js', 'public/js') - .sass('resources/assets/sass/app.scss', 'public/css') - .webpackConfig({ - output: { - publicPath: './', - chunkFilename: function ({chunk}) { - return `js/build/${mixBuildName(chunk.id)}.js` - } - }, + .copy('resources/assets/statics/public', publicPath) + .js('resources/assets/js/app.js', 'js') + .sass('resources/assets/sass/app.scss', 'css') + .setPublicPath(publicPath) + .webpackConfig(webpack => { + return { + output, + plugins: [ + new webpack.DefinePlugin({ + '__PLATFORM': platform + }) + ] + } }) .options({ processCssUrls: false,