From 66831f8ef9a30d5a18fc242d7de0e97ede40cdc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=89=9B=E5=8D=8E=E4=BC=9F?= Date: Wed, 28 Feb 2018 10:19:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E4=B8=AD=E5=8D=88?= =?UTF-8?q?=E5=90=83=E4=BB=80=E4=B9=88app?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .babelrc | 5 + .editorconfig | 9 ++ .eslintignore | 3 + .eslintrc.js | 39 ++++++ .gitignore | 7 + .stylintrc | 35 +++++ README.md | 19 +++ build/css-utils.js | 91 +++++++++++++ build/env-utils.js | 13 ++ build/hot-reload.js | 3 + build/script.build.js | 55 ++++++++ build/script.clean.js | 7 + build/script.dev.js | 86 ++++++++++++ build/webpack.base.conf.js | 108 +++++++++++++++ build/webpack.dev.conf.js | 43 ++++++ build/webpack.prod.conf.js | 78 +++++++++++ config/dev.env.js | 6 + config/index.js | 64 +++++++++ config/prod.env.js | 3 + package.json | 68 ++++++++++ src/App.vue | 15 +++ src/assets/quasar-logo-full.svg | 191 ++++++++++++++++++++++++++ src/components/Error404.vue | 77 +++++++++++ src/components/Hello.vue | 221 +++++++++++++++++++++++++++++++ src/components/Lunch.vue | 55 ++++++++ src/index.html | 16 +++ src/main.js | 35 +++++ src/router.js | 34 +++++ src/statics/quasar-logo.png | Bin 0 -> 7197 bytes src/themes/app.ios.styl | 14 ++ src/themes/app.mat.styl | 14 ++ src/themes/app.variables.styl | 27 ++++ src/themes/quasar.variables.styl | 24 ++++ templates/component.vue | 14 ++ templates/layout.vue | 73 ++++++++++ templates/page.vue | 17 +++ 36 files changed, 1569 insertions(+) create mode 100644 .babelrc create mode 100644 .editorconfig create mode 100644 .eslintignore create mode 100644 .eslintrc.js create mode 100644 .gitignore create mode 100644 .stylintrc create mode 100644 README.md create mode 100644 build/css-utils.js create mode 100644 build/env-utils.js create mode 100644 build/hot-reload.js create mode 100644 build/script.build.js create mode 100644 build/script.clean.js create mode 100644 build/script.dev.js create mode 100644 build/webpack.base.conf.js create mode 100644 build/webpack.dev.conf.js create mode 100644 build/webpack.prod.conf.js create mode 100644 config/dev.env.js create mode 100644 config/index.js create mode 100644 config/prod.env.js create mode 100644 package.json create mode 100644 src/App.vue create mode 100644 src/assets/quasar-logo-full.svg create mode 100644 src/components/Error404.vue create mode 100644 src/components/Hello.vue create mode 100644 src/components/Lunch.vue create mode 100644 src/index.html create mode 100644 src/main.js create mode 100644 src/router.js create mode 100644 src/statics/quasar-logo.png create mode 100644 src/themes/app.ios.styl create mode 100644 src/themes/app.mat.styl create mode 100644 src/themes/app.variables.styl create mode 100644 src/themes/quasar.variables.styl create mode 100644 templates/component.vue create mode 100644 templates/layout.vue create mode 100644 templates/page.vue diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..d192e91 --- /dev/null +++ b/.babelrc @@ -0,0 +1,5 @@ +{ + "presets": [["es2015", {"modules": false}], "stage-2"], + "plugins": ["transform-runtime"], + "comments": false +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..9d08a1a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..2fece73 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +build/*.js +config/*.js +dist/*.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..414fba3 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,39 @@ +module.exports = { + root: true, + parser: 'babel-eslint', + parserOptions: { + sourceType: 'module' + }, + env: { + browser: true + }, + // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style + extends: [ + 'standard' + ], + // required to lint *.vue files + plugins: [ + 'html', + 'import' + ], + globals: { + 'cordova': true, + 'DEV': true, + 'PROD': true, + '__THEME': true + }, + // add your custom rules here + 'rules': { + // allow paren-less arrow functions + 'arrow-parens': 0, + 'one-var': 0, + 'import/first': 0, + 'import/named': 2, + 'import/namespace': 2, + 'import/default': 2, + 'import/export': 2, + // allow debugger during development + 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, + 'brace-style': [2, 'stroustrup', { 'allowSingleLine': true }] + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f793da7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +.thumbs.db +node_modules/ +dist/ +npm-debug.log* +cordova/platforms +cordova/plugins diff --git a/.stylintrc b/.stylintrc new file mode 100644 index 0000000..ce38d77 --- /dev/null +++ b/.stylintrc @@ -0,0 +1,35 @@ +{ + "blocks": "never", + "brackets": "never", + "colons": "never", + "colors": "always", + "commaSpace": "always", + "commentSpace": "always", + "cssLiteral": "never", + "depthLimit": false, + "duplicates": true, + "efficient": "always", + "extendPref": false, + "globalDupe": true, + "indentPref": 2, + "leadingZero": "never", + "maxErrors": false, + "maxWarnings": false, + "mixed": false, + "namingConvention": false, + "namingConventionStrict": false, + "none": "never", + "noImportant": false, + "parenSpace": "never", + "placeholder": false, + "prefixVarsWithDollar": "always", + "quotePref": "single", + "semicolons": "never", + "sortOrder": false, + "stackedProperties": "never", + "trailingWhitespace": "never", + "universal": "never", + "valid": true, + "zeroUnits": "never", + "zIndexNormalize": false +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..f7a1c4f --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# Quasar App + +> A Quasar project + +## Build Setup + +``` bash +# install dependencies +$ npm install + +# serve with hot reload at localhost:8080 +$ quasar dev + +# build for production with minification +$ quasar build + +# lint code +$ quasar lint +``` diff --git a/build/css-utils.js b/build/css-utils.js new file mode 100644 index 0000000..76717e4 --- /dev/null +++ b/build/css-utils.js @@ -0,0 +1,91 @@ +var + ExtractTextPlugin = require('extract-text-webpack-plugin'), + autoprefixer = require('autoprefixer'), + purify = require('purify-css'), + glob = require('glob'), + path = require('path'), + fs = require('fs') + +module.exports.postcss = [autoprefixer()] + +module.exports.styleLoaders = function (options) { + options = options || {} + + function generateLoaders (loaders) { + if (options.postcss) { + loaders.splice(1, 0, 'postcss') + } + + var sourceLoader = loaders.map(function (loader) { + var extraParamChar + if (/\?/.test(loader)) { + loader = loader.replace(/\?/, '-loader?') + extraParamChar = '&' + } + else { + loader = loader + '-loader' + extraParamChar = '?' + } + return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '') + }).join('!') + + if (options.extract) { + return ExtractTextPlugin.extract({ + use: sourceLoader, + fallback: 'vue-style-loader' + }) + } + else { + return ['vue-style-loader', sourceLoader].join('!') + } + } + + return { + css: generateLoaders(['css']), + less: generateLoaders(['css', 'less']), + sass: generateLoaders(['css', 'sass?indentedSyntax']), + scss: generateLoaders(['css', 'sass']), + styl: generateLoaders(['css', 'stylus']), + stylus: generateLoaders(['css', 'stylus']) + } +} + +module.exports.styleRules = function (options) { + var output = [] + var loaders = exports.styleLoaders(options) + for (var extension in loaders) { + var loader = loaders[extension] + output.push({ + test: new RegExp('\\.' + extension + '$'), + loader: loader + }) + } + return output +} + +function getSize (size) { + return (size / 1024).toFixed(2) + 'kb' +} + +module.exports.purify = function(cb) { + var css = glob.sync(path.join(__dirname, '../dist/**/*.css')) + var js = glob.sync(path.join(__dirname, '../dist/**/*.js')) + + Promise.all(css.map(function (file) { + return new Promise(function (resolve) { + console.log('\n Purifying ' + path.relative(path.join(__dirname, '../dist'), file).bold + '...') + purify(js, [file], {minify: true}, function (purified) { + var oldSize = fs.statSync(file).size + fs.writeFileSync(file, purified) + var newSize = fs.statSync(file).size + + console.log( + ' * Reduced size by ' + ((1 - newSize / oldSize) * 100).toFixed(2) + '%, from ' + + getSize(oldSize) + ' to ' + getSize(newSize) + '.' + ) + resolve() + }) + }) + })) + .then(cb) +} diff --git a/build/env-utils.js b/build/env-utils.js new file mode 100644 index 0000000..fe0c4eb --- /dev/null +++ b/build/env-utils.js @@ -0,0 +1,13 @@ +var + config = require('../config'), + theme = process.argv[2] || config.defaultTheme + +module.exports = { + dev: process.env.NODE_ENV === 'development', + prod: process.env.NODE_ENV === 'production', + + platform: { + theme: theme, + cordovaAssets: './cordova/platforms/' + (theme === 'mat' ? 'android' : 'ios') + '/platform_www' + } +} diff --git a/build/hot-reload.js b/build/hot-reload.js new file mode 100644 index 0000000..519350a --- /dev/null +++ b/build/hot-reload.js @@ -0,0 +1,3 @@ +/* eslint-disable */ +require('eventsource-polyfill') +require('webpack-hot-middleware/client?noInfo=true&reload=true') diff --git a/build/script.build.js b/build/script.build.js new file mode 100644 index 0000000..31758c0 --- /dev/null +++ b/build/script.build.js @@ -0,0 +1,55 @@ +process.env.NODE_ENV = 'production' + +require('colors') + +var + shell = require('shelljs'), + path = require('path'), + env = require('./env-utils'), + css = require('./css-utils'), + config = require('../config'), + webpack = require('webpack'), + webpackConfig = require('./webpack.prod.conf'), + targetPath = path.join(__dirname, '../dist') + +console.log(' WARNING!'.bold) +console.log(' Do NOT use VueRouter\'s "history" mode if') +console.log(' building for Cordova or Electron.\n') + +require('./script.clean.js') +console.log((' Building Quasar App with "' + env.platform.theme + '" theme...\n').bold) + +shell.mkdir('-p', targetPath) +shell.cp('-R', 'src/statics', targetPath) + +function finalize () { + console.log(( + '\n Build complete with "' + env.platform.theme.bold + '" theme in ' + + '"/dist"'.bold + ' folder.\n').cyan) + + console.log(' Built files are meant to be served over an HTTP server.'.bold) + console.log(' Opening index.html over file:// won\'t work.'.bold) +} + +webpack(webpackConfig, function (err, stats) { + if (err) throw err + + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, + chunks: false, + chunkModules: false + }) + '\n') + + if (stats.hasErrors()) { + process.exit(1) + } + + if (config.build.purifyCSS) { + css.purify(finalize) + } + else { + finalize() + } +}) diff --git a/build/script.clean.js b/build/script.clean.js new file mode 100644 index 0000000..00472bd --- /dev/null +++ b/build/script.clean.js @@ -0,0 +1,7 @@ +var + shell = require('shelljs'), + path = require('path') + +shell.rm('-rf', path.resolve(__dirname, '../dist/*')) +shell.rm('-rf', path.resolve(__dirname, '../dist/.*')) +console.log(' Cleaned build artifacts.\n') diff --git a/build/script.dev.js b/build/script.dev.js new file mode 100644 index 0000000..62fa484 --- /dev/null +++ b/build/script.dev.js @@ -0,0 +1,86 @@ +process.env.NODE_ENV = 'development' + +require('colors') + +var + path = require('path'), + express = require('express'), + webpack = require('webpack'), + env = require('./env-utils'), + config = require('../config'), + opn = require('opn'), + proxyMiddleware = require('http-proxy-middleware'), + webpackConfig = require('./webpack.dev.conf'), + app = express(), + port = process.env.PORT || config.dev.port, + uri = 'http://localhost:' + port + +console.log(' Starting dev server with "' + (process.argv[2] || env.platform.theme).bold + '" theme...') +console.log(' Will listen at ' + uri.bold) +if (config.dev.openBrowser) { + console.log(' Browser will open when build is ready.\n') +} + +var compiler = webpack(webpackConfig) + +// Define HTTP proxies to your custom API backend +// https://github.com/chimurai/http-proxy-middleware +var proxyTable = config.dev.proxyTable + +var devMiddleware = require('webpack-dev-middleware')(compiler, { + publicPath: webpackConfig.output.publicPath, + quiet: true +}) + +var hotMiddleware = require('webpack-hot-middleware')(compiler, { + log: function () {} +}) + +// force page reload when html-webpack-plugin template changes +compiler.plugin('compilation', function (compilation) { + compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { + hotMiddleware.publish({ action: 'reload' }) + cb() + }) +}) + +// proxy requests like API. See /config/index.js -> dev.proxyTable +// https://github.com/chimurai/http-proxy-middleware +Object.keys(proxyTable).forEach(function (context) { + var options = proxyTable[context] + if (typeof options === 'string') { + options = { target: options } + } + app.use(proxyMiddleware(context, options)) +}) + +// handle fallback for HTML5 history API +app.use(require('connect-history-api-fallback')()) + +// serve webpack bundle output +app.use(devMiddleware) + +// enable hot-reload and state-preserving +// compilation error display +app.use(hotMiddleware) + +// serve pure static assets +var staticsPath = path.posix.join(webpackConfig.output.publicPath, 'statics/') +app.use(staticsPath, express.static('./src/statics')) + +// try to serve Cordova statics for Play App +app.use(express.static(env.platform.cordovaAssets)) + +module.exports = app.listen(port, function (err) { + if (err) { + console.log(err) + process.exit(1) + } + + // open browser if set so in /config/index.js + if (config.dev.openBrowser) { + devMiddleware.waitUntilValid(function () { + opn(uri) + }) + } +}) diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js new file mode 100644 index 0000000..8fff6ef --- /dev/null +++ b/build/webpack.base.conf.js @@ -0,0 +1,108 @@ +var + path = require('path'), + webpack = require('webpack'), + config = require('../config'), + cssUtils = require('./css-utils'), + env = require('./env-utils'), + merge = require('webpack-merge'), + projectRoot = path.resolve(__dirname, '../'), + ProgressBarPlugin = require('progress-bar-webpack-plugin'), + useCssSourceMap = + (env.dev && config.dev.cssSourceMap) || + (env.prod && config.build.productionSourceMap) + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +module.exports = { + entry: { + app: './src/main.js' + }, + output: { + path: path.resolve(__dirname, '../dist'), + publicPath: config[env.prod ? 'build' : 'dev'].publicPath, + filename: 'js/[name].js', + chunkFilename: 'js/[id].[chunkhash].js' + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + modules: [ + resolve('src'), + resolve('node_modules') + ], + alias: config.aliases + }, + module: { + rules: [ + { // eslint + enforce: 'pre', + test: /\.(vue|js)$/, + loader: 'eslint-loader', + include: projectRoot, + exclude: /node_modules/, + options: { + formatter: require('eslint-friendly-formatter') + } + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: projectRoot, + exclude: /node_modules/ + }, + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + postcss: cssUtils.postcss, + loaders: merge({js: 'babel-loader'}, cssUtils.styleLoaders({ + sourceMap: useCssSourceMap, + extract: env.prod + })) + } + }, + { + test: /\.json$/, + loader: 'json-loader' + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: 'img/[name].[hash:7].[ext]' + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: 'fonts/[name].[hash:7].[ext]' + } + } + ] + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': config[env.prod ? 'build' : 'dev'].env, + 'DEV': env.dev, + 'PROD': env.prod, + '__THEME': '"' + env.platform.theme + '"' + }), + new webpack.LoaderOptionsPlugin({ + minimize: env.prod, + options: { + context: path.resolve(__dirname, '../src'), + postcss: cssUtils.postcss + } + }), + new ProgressBarPlugin({ + format: config.progressFormat + }) + ], + performance: { + hints: false + } +} diff --git a/build/webpack.dev.conf.js b/build/webpack.dev.conf.js new file mode 100644 index 0000000..b4dd19e --- /dev/null +++ b/build/webpack.dev.conf.js @@ -0,0 +1,43 @@ +var + config = require('../config'), + webpack = require('webpack'), + merge = require('webpack-merge'), + cssUtils = require('./css-utils'), + baseWebpackConfig = require('./webpack.base.conf'), + HtmlWebpackPlugin = require('html-webpack-plugin'), + FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') + +// add hot-reload related code to entry chunks +Object.keys(baseWebpackConfig.entry).forEach(function (name) { + baseWebpackConfig.entry[name] = ['./build/hot-reload.js', baseWebpackConfig.entry[name]] +}) + +module.exports = merge(baseWebpackConfig, { + // eval-source-map is faster for development + devtool: '#cheap-module-eval-source-map', + devServer: { + historyApiFallback: true, + noInfo: true + }, + module: { + rules: cssUtils.styleRules({ + sourceMap: config.dev.cssSourceMap, + postcss: true + }) + }, + plugins: [ + new webpack.HotModuleReplacementPlugin(), + new webpack.NoEmitOnErrorsPlugin(), + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'src/index.html', + inject: true + }), + new FriendlyErrorsPlugin({ + clearConsole: config.dev.clearConsoleOnRebuild + }) + ], + performance: { + hints: false + } +}) diff --git a/build/webpack.prod.conf.js b/build/webpack.prod.conf.js new file mode 100644 index 0000000..c25411b --- /dev/null +++ b/build/webpack.prod.conf.js @@ -0,0 +1,78 @@ +var + path = require('path'), + config = require('../config'), + cssUtils = require('./css-utils'), + webpack = require('webpack'), + merge = require('webpack-merge'), + baseWebpackConfig = require('./webpack.base.conf'), + ExtractTextPlugin = require('extract-text-webpack-plugin'), + HtmlWebpackPlugin = require('html-webpack-plugin'), + OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') + +module.exports = merge(baseWebpackConfig, { + module: { + rules: cssUtils.styleRules({ + sourceMap: config.build.productionSourceMap, + extract: true, + postcss: true + }) + }, + devtool: config.build.productionSourceMap ? '#source-map' : false, + plugins: [ + new webpack.optimize.UglifyJsPlugin({ + sourceMap: config.build.productionSourceMap, + minimize: true, + compress: { + warnings: false + } + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin({ + cssProcessorOptions: { + safe: true + } + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: '[name].[contenthash].css' + }), + new HtmlWebpackPlugin({ + filename: path.resolve(__dirname, '../dist/index.html'), + template: 'src/index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks: function (module, count) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + ( + module.resource.indexOf('quasar') > -1 || + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + chunks: ['vendor'] + }) + ] +}) diff --git a/config/dev.env.js b/config/dev.env.js new file mode 100644 index 0000000..efead7c --- /dev/null +++ b/config/dev.env.js @@ -0,0 +1,6 @@ +var merge = require('webpack-merge') +var prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"development"' +}) diff --git a/config/index.js b/config/index.js new file mode 100644 index 0000000..89c2580 --- /dev/null +++ b/config/index.js @@ -0,0 +1,64 @@ +var path = require('path') + +module.exports = { + // Webpack aliases + aliases: { + quasar: path.resolve(__dirname, '../node_modules/quasar-framework/'), + src: path.resolve(__dirname, '../src'), + assets: path.resolve(__dirname, '../src/assets'), + '@': path.resolve(__dirname, '../src/components'), + variables: path.resolve(__dirname, '../src/themes/quasar.variables.styl') + }, + + // Progress Bar Webpack plugin format + // https://github.com/clessg/progress-bar-webpack-plugin#options + progressFormat: ' [:bar] ' + ':percent'.bold + ' (:msg)', + + // Default theme to build with ('ios' or 'mat') + defaultTheme: 'mat', + + build: { + env: require('./prod.env'), + publicPath: '', + productionSourceMap: false, + + // Remove unused CSS + // Disable it if it has side-effects for your specific app + purifyCSS: true + }, + dev: { + env: require('./dev.env'), + cssSourceMap: true, + // auto open browser or not + openBrowser: true, + publicPath: '/', + port: 8080, + + // If for example you are using Quasar Play + // to generate a QR code then on each dev (re)compilation + // you need to avoid clearing out the console, so set this + // to "false", otherwise you can set it to "true" to always + // have only the messages regarding your last (re)compilation. + clearConsoleOnRebuild: false, + + // Proxy your API if using any. + // Also see /build/script.dev.js and search for "proxy api requests" + // https://github.com/chimurai/http-proxy-middleware + proxyTable: {} + } +} + +/* + * proxyTable example: + * + proxyTable: { + // proxy all requests starting with /api + '/api': { + target: 'https://some.address.com/api', + changeOrigin: true, + pathRewrite: { + '^/api': '' + } + } + } + */ diff --git a/config/prod.env.js b/config/prod.env.js new file mode 100644 index 0000000..773d263 --- /dev/null +++ b/config/prod.env.js @@ -0,0 +1,3 @@ +module.exports = { + NODE_ENV: '"production"' +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..13b4638 --- /dev/null +++ b/package.json @@ -0,0 +1,68 @@ +{ + "name": "quasar-app", + "productName": "Quasar App", + "version": "0.0.1", + "private": true, + "description": "A Quasar App", + "author": "Your Name ", + "scripts": { + "clean": "node build/script.clean.js", + "dev": "node build/script.dev.js", + "build": "node build/script.build.js", + "lint": "eslint --ext .js,.vue src" + }, + "dependencies": { + "babel-runtime": "^6.25.0", + "quasar-extras": "0.x", + "quasar-framework": "0.14.9", + "vue": "^2.5.0", + "vue-router": "^3.0.1" + }, + "devDependencies": { + "autoprefixer": "^6.4.0", + "babel-core": "^6.0.0", + "babel-eslint": "^7.0.0", + "babel-loader": "^7.1.2", + "babel-plugin-transform-runtime": "^6.0.0", + "babel-preset-es2015": "^6.0.0", + "babel-preset-stage-2": "^6.0.0", + "colors": "^1.1.2", + "connect-history-api-fallback": "^1.1.0", + "css-loader": "^0.28.7", + "es6-promise": "^4.1.1", + "eslint": "^4.8.0", + "eslint-config-standard": "^10.2.1", + "eslint-friendly-formatter": "^3.0.0", + "eslint-loader": "^1.9.0", + "eslint-plugin-html": "^3.2.2", + "eslint-plugin-import": "^2.7.0", + "eslint-plugin-node": "^5.2.0", + "eslint-plugin-promise": "^3.5.0", + "eslint-plugin-standard": "^3.0.1", + "eventsource-polyfill": "^0.9.6", + "express": "^4.16.1", + "extract-text-webpack-plugin": "^3.0.0", + "file-loader": "^0.11.1", + "friendly-errors-webpack-plugin": "^1.1.3", + "glob": "^7.1.2", + "html-webpack-plugin": "^2.30.1", + "http-proxy-middleware": "^0.17.0", + "json-loader": "^0.5.7", + "opn": "^5.0.0", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "postcss-loader": "^1.0.0", + "progress-bar-webpack-plugin": "^1.10.0", + "purify-css": "^1.2.6", + "shelljs": "^0.7.0", + "stylus": "^0.54.5", + "stylus-loader": "^3.0.1", + "url-loader": "^0.5.7", + "vue-loader": "^13.0.5", + "vue-style-loader": "^3.0.3", + "vue-template-compiler": "^2.5.0", + "webpack": "^3.6.0", + "webpack-dev-middleware": "^1.12.0", + "webpack-hot-middleware": "^2.19.1", + "webpack-merge": "^4.1.0" + } +} diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..cd2858d --- /dev/null +++ b/src/App.vue @@ -0,0 +1,15 @@ + + + + + diff --git a/src/assets/quasar-logo-full.svg b/src/assets/quasar-logo-full.svg new file mode 100644 index 0000000..281d072 --- /dev/null +++ b/src/assets/quasar-logo-full.svg @@ -0,0 +1,191 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/Error404.vue b/src/components/Error404.vue new file mode 100644 index 0000000..bc5d2ce --- /dev/null +++ b/src/components/Error404.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/src/components/Hello.vue b/src/components/Hello.vue new file mode 100644 index 0000000..1138070 --- /dev/null +++ b/src/components/Hello.vue @@ -0,0 +1,221 @@ + + + + + diff --git a/src/components/Lunch.vue b/src/components/Lunch.vue new file mode 100644 index 0000000..1a439ab --- /dev/null +++ b/src/components/Lunch.vue @@ -0,0 +1,55 @@ + + + + diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..e46faea --- /dev/null +++ b/src/index.html @@ -0,0 +1,16 @@ + + + + + + + + + Lunch Tips App + + + +
+ + + diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..4f0b33a --- /dev/null +++ b/src/main.js @@ -0,0 +1,35 @@ +// === DEFAULT / CUSTOM STYLE === +// WARNING! always comment out ONE of the two require() calls below. +// 1. use next line to activate CUSTOM STYLE (./src/themes) +// require(`./themes/app.${__THEME}.styl`) +// 2. or, use next line to activate DEFAULT QUASAR STYLE +require(`quasar/dist/quasar.${__THEME}.css`) +// ============================== + +// Uncomment the following lines if you need IE11/Edge support +// require(`quasar/dist/quasar.ie`) +// require(`quasar/dist/quasar.ie.${__THEME}.css`) + +import Vue from 'vue' +import Quasar from 'quasar' +import router from './router' + +Vue.config.productionTip = false +Vue.use(Quasar) // Install Quasar Framework + +if (__THEME === 'mat') { + require('quasar-extras/roboto-font') +} +import 'quasar-extras/material-icons' +// import 'quasar-extras/ionicons' +// import 'quasar-extras/fontawesome' +// import 'quasar-extras/animate' + +Quasar.start(() => { + /* eslint-disable no-new */ + new Vue({ + el: '#q-app', + router, + render: h => h(require('./App').default) + }) +}) diff --git a/src/router.js b/src/router.js new file mode 100644 index 0000000..f228eb2 --- /dev/null +++ b/src/router.js @@ -0,0 +1,34 @@ +import Vue from 'vue' +import VueRouter from 'vue-router' + +Vue.use(VueRouter) + +function load (component) { + // '@' is aliased to src/components + return () => import(`@/${component}.vue`) +} + +export default new VueRouter({ + /* + * NOTE! VueRouter "history" mode DOESN'T works for Cordova builds, + * it is only to be used only for websites. + * + * If you decide to go with "history" mode, please also open /config/index.js + * and set "build.publicPath" to something other than an empty string. + * Example: '/' instead of current '' + * + * If switching back to default "hash" mode, don't forget to set the + * build publicPath back to '' so Cordova builds work again. + */ + + mode: 'hash', + scrollBehavior: () => ({ y: 0 }), + + routes: [ + { path: '/', component: load('Hello') }, + { path: '/lunch', component: load('Lunch') }, + + // Always leave this last one + { path: '*', component: load('Error404') } // Not found + ] +}) diff --git a/src/statics/quasar-logo.png b/src/statics/quasar-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..590e8ce5b7ab465c0c3a23d01354b488c900af0b GIT binary patch literal 7197 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 literal 0 HcmV?d00001 diff --git a/src/themes/app.ios.styl b/src/themes/app.ios.styl new file mode 100644 index 0000000..9066fd8 --- /dev/null +++ b/src/themes/app.ios.styl @@ -0,0 +1,14 @@ +// This file is included in the build if src/main.js imports it. +// Otherwise the default iOS CSS file is bundled. +// Check "DEFAULT / CUSTOM STYLE" in src/main.js + +// App Shared Variables +// -------------------------------------------------- +// Shared Stylus variables go in the app.variables.styl file +@import 'app.variables' + +// Quasar iOS Design Stylus +// -------------------------------------------------- +// Custom App variables must be declared before importing Quasar. +// Quasar will use its default values when a custom variable isn't provided. +@import '~quasar-framework/dist/quasar.ios.styl' diff --git a/src/themes/app.mat.styl b/src/themes/app.mat.styl new file mode 100644 index 0000000..6554060 --- /dev/null +++ b/src/themes/app.mat.styl @@ -0,0 +1,14 @@ +// This file is included in the build if src/main.js imports it. +// Otherwise the default Material CSS file is bundled. +// Check "DEFAULT / CUSTOM STYLE" in src/main.js + +// App Shared Variables +// -------------------------------------------------- +// Shared Stylus variables go in the app.variables.styl file +@import 'app.variables' + +// Quasar Material Design Stylus +// -------------------------------------------------- +// Custom App variables must be declared before importing Quasar. +// Quasar will use its default values when a custom variable isn't provided. +@import '~quasar-framework/dist/quasar.mat.styl' diff --git a/src/themes/app.variables.styl b/src/themes/app.variables.styl new file mode 100644 index 0000000..91d5adc --- /dev/null +++ b/src/themes/app.variables.styl @@ -0,0 +1,27 @@ +// This file is included in the build if src/main.js imports +// either app.mat.styl or app.ios.styl. +// Check "DEFAULT / CUSTOM STYLE" in src/main.js + +// App Shared Variables +// -------------------------------------------------- +// To customize the look and feel of this app, you can override +// the Stylus variables found in Quasar's source Stylus files. Setting +// variables before Quasar's Stylus will use these variables rather than +// Quasar's default Stylus variable values. Stylus variables specific +// to the themes belong in either the app.ios.styl or app.mat.styl files. + + +// App Shared Color Variables +// -------------------------------------------------- +// It's highly recommended to change the default colors +// to match your app's branding. + +$primary = #027be3 +$secondary = #26A69A +$tertiary = #555 + +$neutral = #E0E1E2 +$positive = #21BA45 +$negative = #DB2828 +$info = #31CCEC +$warning = #F2C037 diff --git a/src/themes/quasar.variables.styl b/src/themes/quasar.variables.styl new file mode 100644 index 0000000..1532d22 --- /dev/null +++ b/src/themes/quasar.variables.styl @@ -0,0 +1,24 @@ +// +// Webpack alias "variables" points to this file. +// So you can import it in your app's *.vue files +// inside the + + +// First we load app's Stylus variables +@import 'app.variables' + +// Then we load Quasar Stylus variables. +// Any variables defined in "app.variables.styl" +// will override Quasar's ones. +// +// NOTICE that we only import Core Quasar Variables +// like colors, media breakpoints, and so. +// No component variable will be included. +@import '~quasar/dist/core.variables' diff --git a/templates/component.vue b/templates/component.vue new file mode 100644 index 0000000..acdaedc --- /dev/null +++ b/templates/component.vue @@ -0,0 +1,14 @@ + + + + + diff --git a/templates/layout.vue b/templates/layout.vue new file mode 100644 index 0000000..ab8816f --- /dev/null +++ b/templates/layout.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/templates/page.vue b/templates/page.vue new file mode 100644 index 0000000..14561af --- /dev/null +++ b/templates/page.vue @@ -0,0 +1,17 @@ + + + + +