├── static ├── .gitkeep └── logo.png ├── .eslintignore ├── config ├── prod.env.js ├── setup.iss ├── dev.env.js └── index.js ├── docs ├── assets │ ├── dev.gif │ ├── build.gif │ ├── upgrade.gif │ └── win-setup.gif └── README_ZH.md ├── .gitignore ├── .editorconfig ├── .postcssrc.js ├── .babelrc ├── index.html ├── src ├── router │ └── index.js ├── App.vue ├── main.js ├── components │ ├── Hello.vue │ └── Update.vue └── utils │ └── update.js ├── .eslintrc.js ├── README.md └── package.json /static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /config/setup.iss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anchengjian/vue-nw-seed/HEAD/config/setup.iss -------------------------------------------------------------------------------- /static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anchengjian/vue-nw-seed/HEAD/static/logo.png -------------------------------------------------------------------------------- /docs/assets/dev.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anchengjian/vue-nw-seed/HEAD/docs/assets/dev.gif -------------------------------------------------------------------------------- /docs/assets/build.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anchengjian/vue-nw-seed/HEAD/docs/assets/build.gif -------------------------------------------------------------------------------- /docs/assets/upgrade.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anchengjian/vue-nw-seed/HEAD/docs/assets/upgrade.gif -------------------------------------------------------------------------------- /docs/assets/win-setup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anchengjian/vue-nw-seed/HEAD/docs/assets/win-setup.gif -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | output/ 5 | releases/ 6 | npm-debug.log 7 | yarn-error.log 8 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | // to edit target browsers: use "browserlist" field in package.json 6 | "autoprefixer": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { "modules": false }], 4 | "stage-2" 5 | ], 6 | "plugins": ["transform-runtime"], 7 | "comments": false, 8 | "env": { 9 | "test": { 10 | "presets": ["env", "stage-2"], 11 | "plugins": [ "istanbul" ] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vue-nw-seed 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import Hello from '@/components/Hello' 4 | import Update from '@/components/Update' 5 | 6 | Vue.use(Router) 7 | 8 | export default new Router({ 9 | routes: [ 10 | { 11 | path: '/', 12 | name: 'Hello', 13 | component: Hello 14 | }, 15 | { 16 | path: '/update', 17 | name: 'Update', 18 | component: Update 19 | } 20 | ] 21 | }) 22 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | 14 | 24 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import App from './App' 5 | import router from './router' 6 | 7 | Vue.config.productionTip = false 8 | 9 | // for auto update 10 | import { checkUpdate } from '@/utils/update.js' 11 | checkUpdate() 12 | 13 | /* eslint-disable no-new */ 14 | new Vue({ 15 | el: '#app', 16 | router, 17 | template: '', 18 | components: { App } 19 | }) 20 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | // http://eslint.org/docs/user-guide/configuring 2 | 3 | module.exports = { 4 | root: true, 5 | parser: 'babel-eslint', 6 | parserOptions: { 7 | sourceType: 'module' 8 | }, 9 | env: { 10 | browser: true, 11 | }, 12 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 13 | extends: 'standard', 14 | // required to lint *.vue files 15 | plugins: [ 16 | 'html' 17 | ], 18 | // add your custom rules here 19 | 'rules': { 20 | // allow paren-less arrow functions 21 | 'arrow-parens': 0, 22 | // allow async-await 23 | 'generator-star-spacing': 0, 24 | // allow debugger during development 25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-nw-seed 2 | 3 | > A seed project with Vue.js and Nw.js 4 | 5 | [english](/README.md) | [中文](/docs/README_ZH.md) 6 | 7 | ## Build Setup 8 | 9 | ``` bash 10 | # install dependencies 11 | npm install 12 | 13 | # serve with hot reload at localhost:8080 14 | npm run dev 15 | 16 | # build for production with minification 17 | npm run build 18 | 19 | # build for production and view the bundle analyzer report 20 | npm run build --report 21 | 22 | # only build nw 23 | npm run build --onlyNW 24 | 25 | # default is build `setup.exe` in windows 26 | npm run build --noSetup 27 | ``` 28 | 29 | For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 30 | 31 | ## Demo 32 | ### `npm run dev` 33 | ![dev](/docs/assets/dev.gif) 34 | 35 | ### `npm run build` 36 | ![build](/docs/assets/build.gif) 37 | 38 | ### `for upgrade` 39 | ![upgrade](/docs/assets/upgrade.gif) 40 | 41 | ### Build a beautiful setup for windows 42 | This feature in [vue-nw-seed/origin/win-beautiful-setup](https://github.com/anchengjian/vue-nw-seed/tree/win-beautiful-setup) branch. 43 | ![win-setup](/docs/assets/win-setup.gif) 44 | 45 | ## FAQ 46 | ### Why nw@0.14.7 ? 47 | Not all of NW.js support `XP`, because from the beginning of `Chromium50` does not support the XP, so if your client want to support XP, the best of version is `0.14.7`. See NW.js's blog: [NW.js v0.14.7 (LTS) Released](https://nwjs.io/blog/v0.14.7/) 48 | -------------------------------------------------------------------------------- /src/components/Hello.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 33 | 34 | 35 | 54 | -------------------------------------------------------------------------------- /docs/README_ZH.md: -------------------------------------------------------------------------------- 1 | # vue-nw-seed 2 | 3 | > 一个 Vue.js 和 Nw.js 的种子项目 4 | 5 | [english](/README.md) | [中文](/docs/README_ZH.md) 6 | 7 | ## Build Setup 8 | 9 | ``` bash 10 | # install dependencies 11 | npm install 12 | 13 | # serve with hot reload at localhost:8080 14 | npm run dev 15 | 16 | # build for production with minification 17 | npm run build 18 | 19 | # build for production and view the bundle analyzer report 20 | npm run build --report 21 | 22 | # 有了 `dist` 的情况下,仅仅打包 NW 23 | npm run build --onlyNW 24 | 25 | # windows 下不打包 setup 文件 26 | npm run build --noSetup 27 | ``` 28 | 29 | For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 30 | 31 | ## Demo 32 | ### `npm run dev` 33 | ![dev](/docs/assets/dev.gif) 34 | 35 | ### `npm run build` 36 | ![build](/docs/assets/build.gif) 37 | 38 | ### 升级更新 39 | ![update](/docs/assets/upgrade.gif) 40 | 41 | ### 制作一个更漂亮的 windows 安装程序 42 | 这个功能目前在 [vue-nw-seed/origin/win-beautiful-setup](https://github.com/anchengjian/vue-nw-seed/tree/win-beautiful-setup) 分支上。 43 | ![win-setup](/docs/assets/win-setup.gif) 44 | 45 | ## 常见问答 46 | ### 为啥要固定 nw 版本为 0.14.7 ? 47 | NW.js 不是全版本都支持 XP,由于 Chromium50 开始就不支持XP了,所以如果你的客户端要支持 XP,目前最佳的版本选择是 `0.14.7` 。参见 NW.js 的博客 [NW.js v0.14.7 (LTS) Released](https://nwjs.io/blog/v0.14.7/) 48 | ### 国内用 NPM 安装 NW 很慢很卡! 49 | 可以先想办法把包体下下来到本地,再进行安装。在我之前的一篇文章中介绍过: [用 vue2 和 webpack 快速建构 NW.js 项目](https://github.com/anchengjian/anchengjian.github.io/blob/master/posts/2017/vuejs-webpack-nwjs.md) 50 | 51 | ### 安装包默认是英文? 52 | 如果您不做任何更改,则默认是英文的。 53 | 汉化的话,我提供了一个中文语言包。请手动打开 `./config/setup.iss` 中关于 `Languages` 的注释。 -------------------------------------------------------------------------------- /src/utils/update.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import { App } from 'nw.gui' 4 | import fs from 'fs' 5 | import path from 'path' 6 | import http from 'http' 7 | const events = require('events') 8 | 9 | const { manifest } = App 10 | const platform = (/^win/.test(process.platform) ? 'win' : /^darwin/.test(process.platform) ? 'osx' : 'linux') + (process.arch === 'ia32' ? '32' : '64') 11 | 12 | const options = { method: 'GET', mode: 'cors', credentials: 'include' } 13 | let tmpUpdateJson = null 14 | 15 | // get update.json 16 | export function getUpdateJson (noCache) { 17 | // if (!noCache && tmpUpdateJson) return new Promise((resolve, reject) => resolve(tmpUpdateJson)) 18 | if (!noCache && tmpUpdateJson) return Promise.resolve(tmpUpdateJson) 19 | return window.fetch(manifest.manifestUrl + '?' + new Date().getTime(), options) 20 | .then(resp => resp.json()) 21 | .then(json => { 22 | tmpUpdateJson = json 23 | return tmpUpdateJson 24 | }) 25 | } 26 | 27 | export function parseName (json) { 28 | if (!json) return 29 | const pkg = json.packages[platform] 30 | if (!pkg) return 31 | return path.parse(pkg.url).base 32 | } 33 | 34 | // check version 35 | export function checkUpdate () { 36 | getUpdateJson().then(json => { 37 | if (json.version === App.manifest.version) return 38 | window.location.hash = '/update' 39 | }) 40 | } 41 | 42 | export function downloadHandle (savePath, json) { 43 | const ev = new events.EventEmitter() 44 | 45 | const uri = json.packages[platform].url 46 | const totalSize = json.packages[platform].size 47 | const loadFile = fs.createWriteStream(savePath) 48 | let loaded = 0 49 | 50 | http 51 | .get(uri, res => { 52 | if (res.statusCode < 200 || res.statusCode >= 300) return ev.emit('error', res.statusCode) 53 | res.on('end', () => { 54 | loadFile.end() 55 | loadFile.destroySoon() 56 | ev.emit('end', savePath) 57 | }) 58 | res.on('error', err => ev.emit('error', err.message)) 59 | res.on('data', chunk => { 60 | loadFile.write(chunk) 61 | loaded += chunk.length 62 | ev.emit('data', loaded / totalSize) 63 | }) 64 | }) 65 | .on('error', err => ev.emit('error', err.message)) 66 | 67 | return ev 68 | } 69 | -------------------------------------------------------------------------------- /src/components/Update.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 68 | 92 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-nw-seed", 3 | "appName": "应用的中文别名", 4 | "version": "0.1.1", 5 | "description": "A seed project with Vue.js and Nw.js", 6 | "author": "anchengjian ", 7 | "private": true, 8 | "scripts": { 9 | "dev": "node build/dev-server.js", 10 | "build": "node build/build.js", 11 | "lint": "eslint --ext .js,.vue src" 12 | }, 13 | "dependencies": { 14 | "node-webkit-updater": "^0.3.3", 15 | "nw": "0.14.7-sdk", 16 | "vue": "^2.2.2", 17 | "vue-router": "^2.2.0" 18 | }, 19 | "devDependencies": { 20 | "autoprefixer": "^6.7.2", 21 | "babel-core": "^6.22.1", 22 | "babel-eslint": "^7.1.1", 23 | "babel-loader": "^6.2.10", 24 | "babel-plugin-transform-runtime": "^6.22.0", 25 | "babel-preset-env": "^1.2.1", 26 | "babel-preset-stage-2": "^6.22.0", 27 | "babel-register": "^6.22.0", 28 | "chalk": "^1.1.3", 29 | "connect-history-api-fallback": "^1.3.0", 30 | "copy-webpack-plugin": "^4.0.1", 31 | "css-loader": "^0.26.1", 32 | "eslint": "^3.14.1", 33 | "eslint-config-standard": "^6.2.1", 34 | "eslint-friendly-formatter": "^2.0.7", 35 | "eslint-loader": "^1.6.1", 36 | "eslint-plugin-html": "^2.0.0", 37 | "eslint-plugin-promise": "^3.4.0", 38 | "eslint-plugin-standard": "^2.0.1", 39 | "eventsource-polyfill": "^0.9.6", 40 | "express": "^4.14.1", 41 | "extract-text-webpack-plugin": "^2.0.0", 42 | "file-loader": "^0.10.0", 43 | "friendly-errors-webpack-plugin": "^1.1.3", 44 | "html-webpack-plugin": "^2.28.0", 45 | "http-proxy-middleware": "^0.17.3", 46 | "iconv-lite": "^0.4.15", 47 | "innosetup-compiler": "^5.5.9", 48 | "nw-builder": "^3.4.1", 49 | "optimize-css-assets-webpack-plugin": "^1.3.0", 50 | "ora": "^1.1.0", 51 | "rimraf": "^2.6.0", 52 | "semver": "^5.3.0", 53 | "url-loader": "^0.5.7", 54 | "vue-loader": "^11.1.4", 55 | "vue-style-loader": "^2.0.0", 56 | "vue-template-compiler": "^2.2.4", 57 | "webpack": "^2.2.1", 58 | "webpack-bundle-analyzer": "^2.2.1", 59 | "webpack-dev-middleware": "^1.10.0", 60 | "webpack-hot-middleware": "^2.16.1", 61 | "webpack-merge": "^2.6.1" 62 | }, 63 | "engines": { 64 | "node": ">= 4.0.0", 65 | "npm": ">= 3.0.0" 66 | }, 67 | "browserslist": [ 68 | "last 2 Chrome versions" 69 | ], 70 | "main": "http://localhost:8080", 71 | "manifestUrl": "http://localhost:8080/releases/upgrade.json", 72 | "window": { 73 | "title": "vue-nw-seed", 74 | "toolbar": false, 75 | "width": 800, 76 | "height": 500, 77 | "min_width": 800, 78 | "min_height": 500, 79 | "resizable": true, 80 | "frame": true, 81 | "kiosk": false, 82 | "icon": "/static/logo.png", 83 | "show_in_taskbar": true 84 | }, 85 | "nodejs": true, 86 | "js-flags": "--harmony", 87 | "node-remote": "" 88 | } -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | function resolve() { 5 | return path.resolve.apply(path, [__dirname, '..'].concat(...arguments)) 6 | } 7 | 8 | // `./package.json` 9 | var tmpJson = require(resolve('./package.json')) 10 | 11 | // var curReleasesPath = resolve('./releases', tmpJson.name + '-v' + tmpJson.version) 12 | var curReleasesPath = resolve('./releases', tmpJson.version) 13 | 14 | module.exports = { 15 | build: { 16 | env: require('./prod.env'), 17 | index: resolve('./dist/index.html'), 18 | assetsRoot: resolve('./dist'), 19 | assetsSubDirectory: 'static', 20 | assetsPublicPath: '/', 21 | productionSourceMap: false, 22 | // Gzip off by default as many popular static hosts such as 23 | // Surge or Netlify already gzip all static assets for you. 24 | // Before setting to `true`, make sure to: 25 | // npm install --save-dev compression-webpack-plugin 26 | productionGzip: false, 27 | productionGzipExtensions: ['js', 'css'], 28 | // Run the build command with an extra argument to 29 | // View the bundle analyzer report after build finishes: 30 | // `npm run build --report` 31 | // Set to `true` or `false` to always turn it on or off 32 | bundleAnalyzerReport: process.env.npm_config_report, 33 | // only build nw 34 | onlyNW: process.env.npm_config_onlyNW, 35 | // only build nw 36 | noSetup: process.env.npm_config_noSetup, 37 | nw: { 38 | // manifest for nw 39 | // the fileds will merge with `./package.json` and build to `./dist/package.json` for NW.js 40 | // Manifest Format: http://docs.nwjs.io/en/latest/References/Manifest%20Format/ 41 | manifest: ['name', 'appName', 'version', 'description', 'author', { main: './index.html' }, 'manifestUrl', 'window', 'nodejs', 'js-flags', 'node-remote'], 42 | // see document: https://github.com/nwjs/nw-builder 43 | builder: { 44 | files: [resolve('./dist/**')], 45 | // platforms: ['win32', 'win64', 'osx64'], 46 | platforms: ['win32', 'win64'], 47 | version: '0.14.7', 48 | flavor: 'normal', 49 | cacheDir: resolve('./node_modules/_nw-builder-cache/'), 50 | buildDir: resolve('./releases'), 51 | winIco: resolve('./build/setup_resources/logo.ico'), 52 | macIcns: resolve('./build/setup_resources/logo.icns'), 53 | buildType: function () { 54 | return this.appVersion 55 | } 56 | }, 57 | setup: { 58 | issPath: resolve('./config/setup.iss'), 59 | // only one version path 60 | files: curReleasesPath, 61 | resourcesPath: resolve('./build/setup_resources'), 62 | appPublisher: 'vue-nw-seed, Inc.', 63 | appURL: 'https://github.com/anchengjian/vue-nw-seed', 64 | appId: '{{A448363D-3A2F-4800-B62D-8A1C4D8F1115}}', 65 | // data: { name, version, platform } 66 | outputFileName: function (data) { 67 | return data.name + '-' + data.version 68 | } 69 | }, 70 | upgrade: { 71 | outputFile: resolve('./releases/upgrade.json'), 72 | publicPath: 'http://localhost:8080/releases/', 73 | files: [curReleasesPath] 74 | } 75 | } 76 | }, 77 | dev: { 78 | env: require('./dev.env'), 79 | port: 8080, 80 | autoOpenBrowser: true, 81 | assetsSubDirectory: 'static', 82 | assetsPublicPath: '/', 83 | proxyTable: {}, 84 | // CSS Sourcemaps off by default because relative paths are "buggy" 85 | // with this option, according to the CSS-Loader README 86 | // (https://github.com/webpack/css-loader#sourcemaps) 87 | // In our experience, they generally work as expected, 88 | // just be aware of this issue when enabling this option. 89 | cssSourceMap: false, 90 | upgrade: { 91 | publicPath: '/releases', 92 | directory: 'releases' 93 | } 94 | } 95 | } 96 | --------------------------------------------------------------------------------