Errors occurred while build effective model from /Users/joylau/.gradle/caches/modules-2/files-2.1/log4j/log4j/1.2.16/88efb1b8d3d993fe339e9e2b201c75eed57d4c65/log4j-1.2.16.pom: 'build.plugins.plugin[io.spring.gradle.dependencymanagement.org.apache.maven.plugins:maven-antrun-plugin].dependencies.dependency.scope'for junit:junit:jar must be one of [compile, runtime, system] but is 'test'. in log4j:log4j:1.2.16
为什么说经过了一系列的折腾呢, 因为前 2 中方式都没有解决我的问题,最后我是自己实现了自动更新的逻辑 没有解决我的问题是因为我需要兼顾到 mac 平台和 Windows 平台,然而 mac 平台比较麻烦,代码需要签名 我自己亲测方式一和方式二在 mac 平台上都需要代码签名, 而签名代码需要注册苹果开发者账号,需要付年费 于是这 2 条路就走不通了
最后我决定自己实现更新的逻辑
更新逻辑分析
自动触发或手动触发软件更新检查
服务器版本号大于本地版本才出现更新提示
对于更新,无非就是卸载之前的版本,安装新下载的安装包
软件的打包我选择的是 Electron Builder, 分别打成 dmg , setup.exe , app.zip
const _request = request(downloadUrl); progress(_request, { // throttle: 2000, // Throttle the progress event to 2000ms, defaults to 1000ms // delay: 1000, // Only start to emit after 1000ms delay, defaults to 0ms // lengthHeader: 'x-transfer-length' // Length header to use, defaults to content-length }) .on('progress', function (state) { // The state is an object that looks like this: // { // percent: 0.5, // Overall percent (between 0 to 1) // speed: 554732, // The download speed in bytes/sec // size: { // total: 90044871, // The total payload size in bytes // transferred: 27610959 // The transferred payload size in bytes // }, // time: { // elapsed: 36.235, // The total elapsed seconds since the start (3 decimals) // remaining: 81.403 // The remaining seconds to finish (3 decimals) // } // } that.setState({downloadState: state}) }) .on('error', function (err) { that.setState({ downloadState:{ error: true } }) }) .on('end', function () { if (that.state.update === 'error') return; that.setState({ update: 'install', });
!macro customInstallMode # set $isForceMachineInstall or $isForceCurrentInstall # to enforce one or the other modes. #set $isForceMachineInstall !macroend
entry: { index: [ // Include an alternative client for WebpackDevServer. A client's job is to // connect to WebpackDevServer by a socket and get notified about changes. // When you save a file, the client will either apply hot updates (in case // of CSS changes), or refresh the page (in case of JS changes). When you // make a syntax error, this client will display a syntax error overlay. // Note: instead of the default WebpackDevServer client, we use a custom one // to bring better experience for Create React App users. You can replace // the line below with these two lines if you prefer the stock client: // require.resolve('webpack-dev-server/client') + '?/', // require.resolve('webpack/hot/dev-server'), isEnvDevelopment && require.resolve('react-dev-utils/webpackHotDevClient'), // Finally, this is your app's code: paths.appIndexJs, // We include the app code last so that if there is a runtime error during // initialization, it doesn't blow up the WebpackDevServer client, and // changing JS code would still trigger a refresh. ].filter(Boolean), update: [ isEnvDevelopment && require.resolve('react-dev-utils/webpackHotDevClient'), paths.appSrc + '/update.js', ].filter(Boolean), },
output: { // The build folder. path: isEnvProduction ? paths.appBuild : undefined, // Add /* filename */ comments to generated require()s in the output. pathinfo: isEnvDevelopment, // There will be one main bundle, and one file per asynchronous chunk. // In development, it does not produce real files. filename: isEnvProduction ? 'static/js/[name].[contenthash:8].js' : isEnvDevelopment && 'static/js/[name]bundle.js', // There are also additional JS chunk files if you use code splitting. chunkFilename: isEnvProduction ? 'static/js/[name].[contenthash:8].chunk.js' : isEnvDevelopment && 'static/js/[name].chunk.js', // We inferred the "public path" (such as / or /my-project) from homepage. // We use "/" in development. publicPath: publicPath, // Point sourcemap entries to original disk location (format as URL on Windows) devtoolModuleFilenameTemplate: isEnvProduction ? info => path .relative(paths.appSrc, info.absoluteResourcePath) .replace(/\\/g, '/') : isEnvDevelopment && (info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')), },