First Commit with Quasar
This commit is contained in:
commit
b679575e0f
38 changed files with 1174 additions and 0 deletions
5
.babelrc
Normal file
5
.babelrc
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"presets": [["es2015", {"modules": false}], "stage-2"],
|
||||
"plugins": ["transform-runtime"],
|
||||
"comments": false
|
||||
}
|
9
.editorconfig
Normal file
9
.editorconfig
Normal file
|
@ -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
|
3
.eslintignore
Normal file
3
.eslintignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
build/*.js
|
||||
config/*.js
|
||||
dist/*.js
|
31
.eslintrc.js
Normal file
31
.eslintrc.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
parserOptions: {
|
||||
sourceType: 'module'
|
||||
},
|
||||
env: {
|
||||
browser: true
|
||||
},
|
||||
globals: {
|
||||
'cordova': true,
|
||||
'DEV': true,
|
||||
'PROD': true,
|
||||
'__THEME': true
|
||||
},
|
||||
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
|
||||
extends: 'standard',
|
||||
// required to lint *.vue files
|
||||
plugins: [
|
||||
'html'
|
||||
],
|
||||
// add your custom rules here
|
||||
'rules': {
|
||||
// allow paren-less arrow functions
|
||||
'arrow-parens': 0,
|
||||
'one-var': 0,
|
||||
'import/first': 0,
|
||||
// allow debugger during development
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
|
||||
'brace-style': [2, 'stroustrup', { 'allowSingleLine': true }]
|
||||
}
|
||||
}
|
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
.DS_Store
|
||||
node_modules/
|
||||
dist/
|
||||
npm-debug.log
|
||||
npm-debug.log.*
|
||||
selenium-debug.log
|
||||
test/unit/coverage
|
||||
test/e2e/reports
|
||||
cordova/platforms
|
||||
cordova/plugins
|
||||
thumbs.db
|
||||
!.gitkeep
|
35
.stylintrc
Normal file
35
.stylintrc
Normal file
|
@ -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
|
||||
}
|
19
README.md
Normal file
19
README.md
Normal file
|
@ -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
|
||||
```
|
91
build/css-utils.js
Normal file
91
build/css-utils.js
Normal file
|
@ -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)
|
||||
}
|
13
build/env-utils.js
Normal file
13
build/env-utils.js
Normal file
|
@ -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'
|
||||
}
|
||||
}
|
9
build/hot-reload.js
Normal file
9
build/hot-reload.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
/* eslint-disable */
|
||||
require('eventsource-polyfill')
|
||||
var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
|
||||
|
||||
hotClient.subscribe(function (event) {
|
||||
if (event.action === 'reload') {
|
||||
window.location.reload()
|
||||
}
|
||||
})
|
50
build/script.build.js
Normal file
50
build/script.build.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
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 (config.build.purifyCSS) {
|
||||
css.purify(finalize)
|
||||
}
|
||||
else {
|
||||
finalize()
|
||||
}
|
||||
})
|
6
build/script.clean.js
Normal file
6
build/script.clean.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
var
|
||||
shell = require('shelljs'),
|
||||
path = require('path')
|
||||
|
||||
shell.rm('-rf', path.resolve(__dirname, '../dist'))
|
||||
console.log(' Cleaned build artifacts.\n')
|
86
build/script.dev.js
Normal file
86
build/script.dev.js
Normal file
|
@ -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)
|
||||
return
|
||||
}
|
||||
|
||||
// open browser if set so in /config/index.js
|
||||
if (config.dev.openBrowser) {
|
||||
devMiddleware.waitUntilValid(function () {
|
||||
opn(uri)
|
||||
})
|
||||
}
|
||||
})
|
115
build/webpack.base.conf.js
Normal file
115
build/webpack.base.conf.js
Normal file
|
@ -0,0 +1,115 @@
|
|||
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: [
|
||||
/*
|
||||
Take note!
|
||||
Uncomment if you wish to load only one Moment locale:
|
||||
|
||||
new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/),
|
||||
*/
|
||||
|
||||
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
|
||||
}
|
||||
}
|
43
build/webpack.dev.conf.js
Normal file
43
build/webpack.dev.conf.js
Normal file
|
@ -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'].concat(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
|
||||
}
|
||||
})
|
75
build/webpack.prod.conf.js
Normal file
75
build/webpack.prod.conf.js
Normal file
|
@ -0,0 +1,75 @@
|
|||
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: config.build.index,
|
||||
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(
|
||||
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']
|
||||
})
|
||||
]
|
||||
})
|
6
config/dev.env.js
Normal file
6
config/dev.env.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
var merge = require('webpack-merge')
|
||||
var prodEnv = require('./prod.env')
|
||||
|
||||
module.exports = merge(prodEnv, {
|
||||
NODE_ENV: '"development"'
|
||||
})
|
64
config/index.js
Normal file
64
config/index.js
Normal file
|
@ -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'),
|
||||
components: path.resolve(__dirname, '../src/components')
|
||||
},
|
||||
|
||||
// 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'),
|
||||
index: path.resolve(__dirname, '../dist/index.html'),
|
||||
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': ''
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
3
config/prod.env.js
Normal file
3
config/prod.env.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
NODE_ENV: '"production"'
|
||||
}
|
13
docker-compose.yml
Normal file
13
docker-compose.yml
Normal file
|
@ -0,0 +1,13 @@
|
|||
version: '2'
|
||||
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
image: your-docker-org/your-app-name
|
||||
command: sh
|
||||
volumes:
|
||||
- .:/opt/app
|
||||
- /opt/app/node_modules
|
||||
ports:
|
||||
- 8080:8080
|
||||
tty: true
|
15
dockerfile
Normal file
15
dockerfile
Normal file
|
@ -0,0 +1,15 @@
|
|||
#change this to your own repo, should you have uploaded your image!
|
||||
FROM quasarframework/client-dev:latest
|
||||
|
||||
MAINTAINER Your Name <your.email@your-sites-address.com>
|
||||
|
||||
WORKDIR /opt/app
|
||||
|
||||
COPY package.json /opt/app/
|
||||
RUN npm install
|
||||
|
||||
COPY . /opt/app
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
CMD /bin/sh
|
67
package.json
Normal file
67
package.json
Normal file
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"name": "quasar-app",
|
||||
"version": "0.0.1",
|
||||
"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.0.0",
|
||||
"fastclick": "^1.0.6",
|
||||
"material-design-icons": "^3.0.1",
|
||||
"moment": "^2.15.0",
|
||||
"quasar-framework": "^0.13.4",
|
||||
"roboto-fontface": "^0.7.0",
|
||||
"vue": "^2.3.0",
|
||||
"vue-router": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^6.4.0",
|
||||
"babel-core": "^6.0.0",
|
||||
"babel-eslint": "^7.0.0",
|
||||
"babel-loader": "^7.0.0",
|
||||
"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.0",
|
||||
"eslint": "^3.0.1",
|
||||
"eslint-config-standard": "^10.2.1",
|
||||
"eslint-friendly-formatter": "^2.0.5",
|
||||
"eslint-loader": "^1.3.0",
|
||||
"eslint-plugin-html": "^2.0.1",
|
||||
"eslint-plugin-import": "^2.2.0",
|
||||
"eslint-plugin-node": "^4.2.2",
|
||||
"eslint-plugin-promise": "^3.3.0",
|
||||
"eslint-plugin-standard": "^3.0.1",
|
||||
"eventsource-polyfill": "^0.9.6",
|
||||
"express": "^4.13.3",
|
||||
"extract-text-webpack-plugin": "^2.0.0-beta.4",
|
||||
"file-loader": "^0.11.1",
|
||||
"friendly-errors-webpack-plugin": "^1.1.3",
|
||||
"html-webpack-plugin": "^2.8.1",
|
||||
"http-proxy-middleware": "^0.17.0",
|
||||
"json-loader": "^0.5.4",
|
||||
"opn": "^5.0.0",
|
||||
"optimize-css-assets-webpack-plugin": "^1.3.1",
|
||||
"postcss-loader": "^1.0.0",
|
||||
"progress-bar-webpack-plugin": "^1.9.0",
|
||||
"purify-css": "^1.1.9",
|
||||
"shelljs": "^0.7.0",
|
||||
"stylus": "^0.54.5",
|
||||
"stylus-loader": "^3.0.1",
|
||||
"url-loader": "^0.5.7",
|
||||
"vue-loader": "^12.0.2",
|
||||
"vue-style-loader": "^3.0.1",
|
||||
"vue-template-compiler": "^2.3.0",
|
||||
"webpack": "^2.2.1",
|
||||
"webpack-dev-middleware": "^1.8.4",
|
||||
"webpack-hot-middleware": "^2.17.0",
|
||||
"webpack-merge": "^4.0.0"
|
||||
}
|
||||
}
|
15
src/App.vue
Normal file
15
src/App.vue
Normal file
|
@ -0,0 +1,15 @@
|
|||
<template>
|
||||
<!-- Don't drop "q-app" class -->
|
||||
<div id="q-app">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* Root component
|
||||
*/
|
||||
export default {}
|
||||
</script>
|
||||
|
||||
<style></style>
|
BIN
src/assets/quasar-logo.png
Normal file
BIN
src/assets/quasar-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
58
src/components/Error404.vue
Normal file
58
src/components/Error404.vue
Normal file
|
@ -0,0 +1,58 @@
|
|||
<template>
|
||||
<div class="error-page window-height window-width bg-light column items-center">
|
||||
<div class="error-code bg-primary flex items-center justify-center">
|
||||
404
|
||||
</div>
|
||||
<div>
|
||||
<div class="error-card card bg-white column items-center justify-center">
|
||||
<i class="text-grey-5">error_outline</i>
|
||||
<p class="caption text-center">Oops. Nothing here...</p>
|
||||
<p class="text-center group">
|
||||
<button v-if="canGoBack" class="grey push small" @click="goBack">
|
||||
<i class="on-left">keyboard_arrow_left</i>
|
||||
Go back
|
||||
</button>
|
||||
<router-link to="/">
|
||||
<button class="grey push small">
|
||||
Go home
|
||||
<i class="on-right">home</i>
|
||||
</button>
|
||||
</router-link>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
canGoBack: window.history.length > 1
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goBack () {
|
||||
window.history.go(-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus">
|
||||
.error-page
|
||||
.error-code
|
||||
height 50vh
|
||||
width 100%
|
||||
padding-top 15vh
|
||||
font-size 30vmax
|
||||
color rgba(255, 255, 255, .2)
|
||||
overflow hidden
|
||||
.error-card
|
||||
margin-top -25px
|
||||
width 90vw
|
||||
max-width 600px
|
||||
padding 50px
|
||||
i
|
||||
font-size 5rem
|
||||
</style>
|
34
src/components/Index.vue
Normal file
34
src/components/Index.vue
Normal file
|
@ -0,0 +1,34 @@
|
|||
<template>
|
||||
<q-layout>
|
||||
<div slot="header" class="toolbar">
|
||||
<q-toolbar-title :padding="0">
|
||||
My Spells v2.0
|
||||
</q-toolbar-title>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
Replace following "div" with
|
||||
"<router-view class="layout-view">" component
|
||||
if using subRoutes
|
||||
-->
|
||||
<div class="layout-view">
|
||||
<spell-list></spell-list>
|
||||
</div>
|
||||
</q-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import SpellList from './Spelllist'
|
||||
|
||||
Vue.component('spell-list', SpellList)
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="styl">
|
||||
</style>
|
16
src/components/Spellitem.vue
Normal file
16
src/components/Spellitem.vue
Normal file
|
@ -0,0 +1,16 @@
|
|||
<template>
|
||||
<q-collapsible :label="spell.title" group="spells">
|
||||
{{spell.description}}
|
||||
</q-collapsible>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: [
|
||||
'spell'
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="stylus">
|
||||
</style>
|
38
src/components/Spelllist.vue
Normal file
38
src/components/Spelllist.vue
Normal file
|
@ -0,0 +1,38 @@
|
|||
<template>
|
||||
<table class="list">
|
||||
<tr
|
||||
is="spell-item"
|
||||
v-for="spell in spells"
|
||||
:spell="spell"
|
||||
>
|
||||
</tr>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import SpellItem from './Spellitem'
|
||||
|
||||
Vue.component('spell-item', SpellItem)
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
spells: [
|
||||
{
|
||||
title: 'example 1',
|
||||
description: 'foo'
|
||||
}, {
|
||||
title: 'example 2',
|
||||
description: 'bar'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="stylus">
|
||||
.list
|
||||
width: 100%
|
||||
</style>
|
16
src/index.html
Normal file
16
src/index.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
|
||||
|
||||
<title>Quasar App</title>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="statics/favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<div id="q-app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
22
src/main.js
Normal file
22
src/main.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
// === 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`)
|
||||
// ==============================
|
||||
|
||||
import Vue from 'vue'
|
||||
import Quasar from 'quasar'
|
||||
import router from './router'
|
||||
|
||||
Vue.use(Quasar) // Install Quasar Framework
|
||||
|
||||
Quasar.start(() => {
|
||||
/* eslint-disable no-new */
|
||||
new Vue({
|
||||
el: '#q-app',
|
||||
router,
|
||||
render: h => h(require('./App'))
|
||||
})
|
||||
})
|
27
src/router.js
Normal file
27
src/router.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
|
||||
Vue.use(VueRouter)
|
||||
|
||||
function load (component) {
|
||||
return () => System.import(`components/${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.
|
||||
*/
|
||||
|
||||
routes: [
|
||||
{ path: '/', component: load('Index') }, // Default
|
||||
{ path: '*', component: load('Error404') } // Not found
|
||||
]
|
||||
})
|
BIN
src/statics/favicon.ico
Normal file
BIN
src/statics/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 6 KiB |
26
src/themes/app.ios.styl
Normal file
26
src/themes/app.ios.styl
Normal file
|
@ -0,0 +1,26 @@
|
|||
// 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'
|
||||
|
||||
// App iOS Design Variables
|
||||
// --------------------------------------------------
|
||||
// iOS Design only Stylus variables can go here
|
||||
// http://quasar-framework.org/api/css-stylus-variables.html
|
||||
|
||||
$typography-font-family ?= '-apple-system', 'Helvetica Neue', Helvetica, Arial, sans-serif
|
||||
|
||||
$toolbar-color ?= #424242
|
||||
$toolbar-background ?= $light
|
||||
$toolbar-active-color ?= $light
|
||||
$toolbar-faded-color ?= composite-color($toolbar-color)
|
||||
|
||||
// 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'
|
26
src/themes/app.mat.styl
Normal file
26
src/themes/app.mat.styl
Normal file
|
@ -0,0 +1,26 @@
|
|||
// 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'
|
||||
|
||||
// App Material Design Variables
|
||||
// --------------------------------------------------
|
||||
// Material Design only Stylus variables can go here
|
||||
// http://quasar-framework.org/api/css-stylus-variables.html
|
||||
|
||||
$typography-font-family ?= 'Roboto'
|
||||
|
||||
$toolbar-color ?= white
|
||||
$toolbar-background ?= $primary
|
||||
$toolbar-active-color ?= $primary
|
||||
$toolbar-faded-color ?= composite-color($primary)
|
||||
|
||||
// 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'
|
37
src/themes/app.variables.styl
Normal file
37
src/themes/app.variables.styl
Normal file
|
@ -0,0 +1,37 @@
|
|||
// 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
|
||||
|
||||
$light = #f4f4f4
|
||||
$dark = #333
|
||||
$faded = #777
|
||||
|
||||
$text-color = lighten(black, 17%)
|
||||
$background-color = white
|
||||
|
||||
$link-color = lighten($primary, 25%)
|
||||
$link-color-active = $primary
|
14
templates/component.vue
Normal file
14
templates/component.vue
Normal file
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
55
templates/layout.vue
Normal file
55
templates/layout.vue
Normal file
|
@ -0,0 +1,55 @@
|
|||
<template>
|
||||
<q-layout>
|
||||
<div slot="header" class="toolbar">
|
||||
<!-- opens drawer below
|
||||
<button class="hide-on-drawer-visible" @click="$refs.drawer.open()">
|
||||
<i>menu</i>
|
||||
</button>
|
||||
-->
|
||||
<q-toolbar-title :padding="1">
|
||||
Title
|
||||
</q-toolbar-title>
|
||||
</div>
|
||||
|
||||
<!-- Navigation Tabs
|
||||
<q-tabs slot="navigation">
|
||||
<q-tab icon="mail" route="/layout" exact replace>Mails</q-tab>
|
||||
<q-tab icon="alarm" route="/layout/alarm" exact replace>Alarms</q-tab>
|
||||
<q-tab icon="help" route="/layout/help" exact replace>Help</q-tab>
|
||||
</q-tabs>
|
||||
-->
|
||||
|
||||
<!-- Drawer
|
||||
<q-drawer ref="drawer">
|
||||
<div class="toolbar">
|
||||
<q-toolbar-title>
|
||||
Drawer Title
|
||||
</q-toolbar-title>
|
||||
</div>
|
||||
|
||||
<div class="list no-border platform-delimiter">
|
||||
<q-drawer-link icon="mail" :to="{path: '/', exact: true}">
|
||||
Link
|
||||
</q-drawer-link>
|
||||
</div>
|
||||
</q-drawer>
|
||||
-->
|
||||
|
||||
<router-view class="layout-view"></router-view>
|
||||
|
||||
<!-- Footer
|
||||
<div slot="footer" class="toolbar"></div>
|
||||
-->
|
||||
</q-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
20
templates/view.vue
Normal file
20
templates/view.vue
Normal file
|
@ -0,0 +1,20 @@
|
|||
<template>
|
||||
<!-- root node required -->
|
||||
<div>
|
||||
<!-- your content -->
|
||||
<div class="layout-padding">
|
||||
<!-- if you want automatic padding -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
Loading…
Add table
Reference in a new issue