Upgrade to Webpack 4 + improve the build system

This commit is contained in:
Lucas Verney 2018-08-05 22:05:56 +02:00
parent 95ef4d2c4d
commit 6a70deec70
24 changed files with 1064 additions and 1326 deletions

View File

@ -1,12 +1,6 @@
{ {
"presets": [ "presets": [
["env", { ["env", { "modules": false, "useBuiltIns": true }],
"modules": false, "stage-2"
"targets": { ]
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"]
} }

View File

@ -1,41 +0,0 @@
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'
const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const spinner = ora('building for production...')
spinner.start()
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, (err, stats) => {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
chunks: false,
chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})

View File

@ -1,54 +0,0 @@
'use strict'
const chalk = require('chalk')
const semver = require('semver')
const packageConfig = require('../package.json')
const shell = require('shelljs')
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
}
const versionRequirements = [
{
name: 'node',
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node
}
]
if (shell.which('npm')) {
versionRequirements.push({
name: 'npm',
currentVersion: exec('npm --version'),
versionRequirement: packageConfig.engines.npm
})
}
module.exports = function () {
const warnings = []
for (let i = 0; i < versionRequirements.length; i++) {
const mod = versionRequirements[i]
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
warnings.push(mod.name + ': ' +
chalk.red(mod.currentVersion) + ' should be ' +
chalk.green(mod.versionRequirement)
)
}
}
if (warnings.length) {
console.log('')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log()
for (let i = 0; i < warnings.length; i++) {
const warning = warnings[i]
console.log(' ' + warning)
}
console.log()
process.exit(1)
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -1,101 +1,11 @@
'use strict' 'use strict'
const path = require('path') const path = require('path')
const config = require('../config') const config = require('../config')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const packageConfig = require('../package.json')
exports.assetsPath = function (_path) { exports.assetsPath = function (_path) {
const assetsSubDirectory = process.env.NODE_ENV === 'production' return path.posix.join(config.build.assetsSubDirectory, _path)
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
} }
exports.cssLoaders = function (options) { exports.resolve = function (dir) {
options = options || {} return path.join(__dirname, '..', dir)
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
}
}
const postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
exports.createNotifierCallback = () => {
const notifier = require('node-notifier')
return (severity, errors) => {
if (severity !== 'error') return
const error = errors[0]
const filename = error.file && error.file.split('!').pop()
notifier.notify({
title: packageConfig.name,
message: severity + ': ' + error.name,
subtitle: filename || '',
icon: path.join(__dirname, '../src/assets/logo.svg')
})
}
} }

View File

@ -1,22 +0,0 @@
'use strict'
const utils = require('./utils')
const config = require('../config')
const isProduction = process.env.NODE_ENV === 'production'
const sourceMapEnabled = isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap
module.exports = {
loaders: utils.cssLoaders({
sourceMap: sourceMapEnabled,
extract: isProduction
}),
cssSourceMap: sourceMapEnabled,
cacheBusting: config.dev.cacheBusting,
transformToRequire: {
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: 'xlink:href'
}
}

View File

@ -1,114 +1,251 @@
'use strict' 'use strict'
const path = require('path') const path = require('path')
const svg2png = require('svg2png')
const webpack = require('webpack')
const AppManifestWebpackPlugin = require('app-manifest-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const utils = require('./utils') const utils = require('./utils')
const config = require('../config') const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
const createLintingRule = () => ({
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: !config.dev.showEslintErrorsInOverlay
}
})
module.exports = { module.exports = {
context: path.resolve(__dirname, '../'), context: path.resolve(__dirname, '../'),
entry: { entry: {
app: './src/main.js' app: './src/main.js'
}, },
output: { output: {
path: config.build.assetsRoot, path: config.build.assetsRoot,
filename: '[name].js', filename: utils.assetsPath('js/[name].js'),
publicPath: process.env.NODE_ENV === 'production' chunkFilename: utils.assetsPath('js/[name].js'),
? config.build.assetsPublicPath publicPath: config.build.assetsPublicPath,
: config.dev.assetsPublicPath },
}, optimization: {
resolve: { minimizer: [
extensions: ['.js', '.vue', '.json'], new UglifyJsPlugin({
alias: { cache: true,
'vue$': 'vue/dist/vue.esm.js', sourceMap: true,
'@': resolve('src'), parallel: true
} }),
}, new OptimizeCSSAssetsPlugin({})
module: { ],
rules: [ splitChunks: {
...(config.dev.useEslint ? [createLintingRule()] : []), chunks: 'initial',
{ cacheGroups: {
test: /\.vue$/, vendors: {
loader: 'vue-loader', test: /[\\/]node_modules[\\/]|[\\/]css\/vendor[\\/]/,
options: vueLoaderConfig },
}, },
{ },
test: /\.js$/, },
loader: 'babel-loader', resolve: {
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] extensions: ['.js', '.vue', '.json'],
}, alias: {
{ '@': utils.resolve('src'),
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
// optipng.enabled: false will disable optipng
optipng: {
enabled: false,
},
pngquant: {
quality: '65-90',
speed: 4
},
gifsicle: {
interlaced: false,
},
// the webp option will enable WEBP
webp: {
quality: 75
}
}
},
],
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
} }
}, },
{ stats: {
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, children: false,
loader: 'url-loader', },
options: { module: {
limit: 10000, rules: [
name: utils.assetsPath('fonts/[name].[hash:7].[ext]') {
} test: /\.(js|vue)$/,
} loader: 'eslint-loader',
] enforce: 'pre',
}, include: [utils.resolve('src')],
node: { options: {
// prevent webpack from injecting useless setImmediate polyfill because Vue formatter: require('eslint-friendly-formatter'),
// source contains it (although only uses it if it's native). emitWarning: true,
setImmediate: false, },
// prevent webpack from injecting mocks to Node native modules },
// that does not make sense for the client {
dgram: 'empty', test: /\.vue$/,
fs: 'empty', loader: 'vue-loader',
net: 'empty', },
tls: 'empty', {
child_process: 'empty' test: /\.js$/,
} loader: 'babel-loader',
exclude: file => (
/node_modules/.test(file) &&
!/\.vue\.js/.test(file)
),
},
{
test: /\.css$/,
use: [
process.env.NODE_ENV !== 'production'
? 'vue-style-loader'
: MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: { importLoaders: 1 },
},
{
loader: 'postcss-loader',
options: {
plugins: () => [require("autoprefixer")()],
},
},
],
},
{
test: /\.styl(us)?/,
use: [
process.env.NODE_ENV !== 'production'
? 'vue-style-loader'
: MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: { importLoaders: 1 },
},
{
loader: 'postcss-loader',
options: {
plugins: () => [require("autoprefixer")()],
},
},
'stylus-loader',
],
},
{
test: /\.(jpe?g|png|gif)$/,
use: [
{
loader: 'url-loader',
options: {
name: utils.assetsPath('images/[name].[hash:4].[ext]'),
// Images larger than 10 KB wont be inlined
limit: 10 * 1024,
}
},
{
loader: 'image-webpack-loader',
options: {
disable: process.env.NODE_ENV !== 'production',
},
},
],
},
{
test: /\.svg$/,
use: [
{
loader: "svg-url-loader",
options: {
name: utils.assetsPath('images/[name].[hash:4].[ext]'),
// Images larger than 10 KB wont be inlined
limit: 10 * 1024,
noquotes: true,
},
},
{
loader: 'image-webpack-loader',
options: {
disable: process.env.NODE_ENV !== 'production',
},
},
],
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)$/,
loader: 'url-loader',
options: {
limit: 10 * 1024,
name: utils.assetsPath('media/[name].[hash:4].[ext]'),
},
},
{
test: /\.(woff2?|eot|ttf|otf)$/,
loader: 'url-loader',
options: {
limit: 10 * 1024,
name: utils.assetsPath('fonts/[name].[hash:4].[ext]'),
},
},
],
},
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty',
},
plugins: [
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: utils.assetsPath('css/[name].[contenthash:4].css'),
chunkFilename: utils.assetsPath('css/[name].[contenthash:4].css'),
}),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
ogURL: config.build.ogURL,
ogImage: config.build.ogImage,
inject: true,
minify: (
process.env.NODE_ENV === 'production'
? {
collapseBooleanAttributes: true,
collapseWhitespace: true,
html5: true,
removeAttributeQuotes: true,
removeComments: true,
}
: {}
),
}),
new AppManifestWebpackPlugin({
logo: path.resolve(__dirname, '../src/assets/logo.svg'),
prefix: '.',
output: '/static/icons-[hash:8]/',
inject: true,
persistentCache: true,
config: {
appName: 'Cyclassist',
appDescription: "Track and share issues (work, interruption in routes, parked cars) on bike lanes in realtime.",
developerName: 'Phyks (Lucas Verney)',
developerURL: 'https://phyks.me',
}
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
},
{
from: path.resolve(__dirname, '../src/assets/logo.svg'),
to: path.join(config.build.assetsSubDirectory, 'ogIcon.png'),
transform (content, path) {
return Promise.resolve(svg2png(content, { width: 400, height: 400 }));
}
},
{
from: path.resolve(__dirname, '../humans.txt'),
to: config.build.assetsRoot,
ignore: ['.*']
},
{
from: path.resolve(__dirname, '../robots.txt'),
to: config.build.assetsRoot,
ignore: ['.*']
}
]),
// Only keep the useful locales from Moment.
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
],
} }

95
build/webpack.dev.conf.js Executable file → Normal file
View File

@ -1,33 +1,29 @@
'use strict' 'use strict'
const svg2png = require('svg2png')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const path = require('path') const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const AppManifestWebpackPlugin = require('app-manifest-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder') const portfinder = require('portfinder')
const webpack = require('webpack')
const merge = require('webpack-merge')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const baseWebpackConfig = require('./webpack.base.conf')
const config = require('../config')
const env = require('../config/dev.env');
const HOST = process.env.HOST const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT) const PORT = process.env.PORT && Number(process.env.PORT)
const devWebpackConfig = merge(baseWebpackConfig, { const devWebpackConfig = merge(baseWebpackConfig, {
module: { mode: 'development',
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
}, // cheap-module-eval-source-map is faster for development
// cheap-module-eval-source-map is faster for development devtool: 'cheap-module-eval-source-map',
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: { devServer: {
clientLogLevel: 'warning', clientLogLevel: 'warning',
historyApiFallback: { historyApiFallback: {
rewrites: [ rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, { from: /.*/, to: path.posix.join(config.build.assetsPublicPath, 'index.html') },
], ],
}, },
hot: true, hot: true,
@ -36,69 +32,15 @@ const devWebpackConfig = merge(baseWebpackConfig, {
host: HOST || config.dev.host, host: HOST || config.dev.host,
port: PORT || config.dev.port, port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser, open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay overlay: { warnings: false, errors: true },
? { warnings: false, errors: true } publicPath: config.build.assetsPublicPath,
: false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
quiet: true, // necessary for FriendlyErrorsPlugin quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
}, },
plugins: [ plugins: [
new webpack.DefinePlugin({ new webpack.DefinePlugin({
'process.env': require('../config/dev.env') 'process.env': env,
}), }),
new webpack.HotModuleReplacementPlugin(), new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
new AppManifestWebpackPlugin({
logo: path.resolve(__dirname, '../src/assets/logo.svg'),
prefix: '.',
output: '/static/icons-[hash:8]/',
inject: true,
persistentCache: true,
config: {
appName: 'Cyclassist',
appDescription: "Track and share issues (work, interruption in routes, parked cars) on bike lanes in realtime.",
developerName: 'Phyks (Lucas Verney)',
developerURL: 'https://phyks.me',
}
}),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
ogURL: config.build.ogURL,
ogImage: config.build.ogImage,
inject: true
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
},
{
from: path.resolve(__dirname, '../src/assets/logo.svg'),
to: path.join(config.build.assetsSubDirectory, 'ogIcon.png'),
transform (content, path) {
return Promise.resolve(svg2png(content, { width: 400, height: 400 }));
}
},
{
from: path.resolve(__dirname, '../humans.txt'),
to: config.build.assetsRoot,
ignore: ['.*']
},
{
from: path.resolve(__dirname, '../robots.txt'),
to: config.build.assetsRoot,
ignore: ['.*']
}
])
] ]
}) })
@ -108,8 +50,6 @@ module.exports = new Promise((resolve, reject) => {
if (err) { if (err) {
reject(err) reject(err)
} else { } else {
// publish the new Port, necessary for e2e tests
process.env.PORT = port
// add port to devServer config // add port to devServer config
devWebpackConfig.devServer.port = port devWebpackConfig.devServer.port = port
@ -118,9 +58,6 @@ module.exports = new Promise((resolve, reject) => {
compilationSuccessInfo: { compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
}, },
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
})) }))
resolve(devWebpackConfig) resolve(devWebpackConfig)

View File

@ -1,183 +1,29 @@
'use strict' 'use strict'
const fs = require('fs')
const path = require('path')
const svg2png = require('svg2png')
const utils = require('./utils')
const webpack = require('webpack') const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge') const merge = require('webpack-merge')
process.env.NODE_ENV = 'production';
const baseWebpackConfig = require('./webpack.base.conf') const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const AppManifestWebpackPlugin = require('app-manifest-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const env = require('../config/prod.env') const env = require('../config/prod.env')
const utils = require('./utils')
const webpackConfig = merge(baseWebpackConfig, { const webpackConfig = merge(baseWebpackConfig, {
module: { mode: 'production',
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: { output: {
path: config.build.assetsRoot, filename: utils.assetsPath('js/[name].[chunkhash:4].js'),
filename: utils.assetsPath('js/[name].[chunkhash].js'), chunkFilename: utils.assetsPath('js/[name].[chunkhash:4].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
}, },
plugins: [ plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({ new webpack.DefinePlugin({
'process.env': env 'process.env': env,
}),
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'),
// Setting the following option to `false` will not extract CSS from codesplit chunks.
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
allChunks: true,
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}),
new AppManifestWebpackPlugin({
logo: path.resolve(__dirname, '../src/assets/logo.svg'),
prefix: '.',
output: '/static/icons-[hash:8]/',
inject: true,
persistentCache: true,
config: {
appName: 'Cyclassist',
appDescription: "Track and share issues (work, interruption in routes, parked cars) on bike lanes in realtime.",
developerName: 'Phyks (Lucas Verney)',
developerURL: 'https://phyks.me',
}
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
//
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
ogURL: config.build.ogURL,
ogImage: config.build.ogImage,
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'
}), }),
// keep module.id stable when vendor modules does not change // keep module.id stable when vendor modules does not change
new webpack.HashedModuleIdsPlugin(), new webpack.HashedModuleIdsPlugin(),
// enable scope hoisting
new webpack.optimize.ModuleConcatenationPlugin(),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks (module) {
// 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',
minChunks: Infinity
}),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
// Only keep the useful locales from Moment.
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
},
{
from: path.resolve(__dirname, '../src/assets/logo.svg'),
to: path.join(config.build.assetsSubDirectory, 'ogIcon.png'),
transform (content, path) {
return Promise.resolve(svg2png(content, { width: 400, height: 400 }));
}
},
{
from: path.resolve(__dirname, '../humans.txt'),
to: config.build.assetsRoot,
ignore: ['.*']
},
{
from: path.resolve(__dirname, '../robots.txt'),
to: config.build.assetsRoot,
ignore: ['.*']
}
])
] ]
}) })
if (config.build.productionGzip) { if (process.env.ANALYZE) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin()) webpackConfig.plugins.push(new BundleAnalyzerPlugin())
} }

View File

@ -1,7 +1,8 @@
'use strict' 'use strict'
const merge = require('webpack-merge') const merge = require('webpack-merge')
const prodEnv = require('./prod.env') const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, { module.exports = merge(prodEnv, {
NODE_ENV: '"development"', NODE_ENV: '"development"',
}) })

View File

@ -6,73 +6,18 @@ const path = require('path')
module.exports = { module.exports = {
dev: { dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: process.env.PUBLIC_PATH || '/',
proxyTable: {},
// Various Dev Server settings // Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST host: 'localhost', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false, autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
// Use Eslint Loader?
// If true, your code will be linted during bundling and
// linting errors and warnings will be shown in the console.
useEslint: true,
// If true, eslint errors and warnings will also be shown in the error overlay
// in the browser.
showEslintErrorsInOverlay: false,
/**
* Source Maps
*/
// https://webpack.js.org/configuration/devtool/#development
devtool: 'cheap-module-eval-source-map',
// If you have problems debugging vue-files in devtools,
// set this to false - it *may* help
// https://vue-loader.vuejs.org/en/options.html#cachebusting
cacheBusting: true,
cssSourceMap: true,
}, },
build: { build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/index.html'),
// Paths // Paths
assetsRoot: path.resolve(__dirname, '../dist'), assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static', assetsSubDirectory: 'static',
assetsPublicPath: process.env.PUBLIC_PATH || '/', assetsPublicPath: process.env.PUBLIC_PATH || '/',
/**
* Source Maps
*/
productionSourceMap: true,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `ANALYZE=true yarn build`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.ANALYZE,
// OpenGraph-related variables // OpenGraph-related variables
ogURL: 'https://cyclo.phyks.me', ogURL: 'https://cyclo.phyks.me',
ogImage: 'https://cyclo.phyks.me/static/ogIcon.png', ogImage: 'https://cyclo.phyks.me/static/ogIcon.png',

View File

@ -8,13 +8,13 @@
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev", "start": "npm run dev",
"lint": "eslint --ext .js,.vue src", "lint": "eslint --ext .js,.vue src",
"build": "node build/build.js", "build": "rm -r dist/*; webpack-cli --bail --progress --config build/webpack.prod.conf.js",
"push-locales": "json2po -P -i src/i18n/en.json -t src/i18n/en.json -o po/cyclassist.pot && zanata push", "push-locales": "json2po -P -i src/i18n/en.json -t src/i18n/en.json -o po/cyclassist.pot && zanata push",
"pull-locales": "zanata pull && ./.po2json.sh", "pull-locales": "zanata pull && ./.po2json.sh",
"list-vuetify-components": "ack '<v-' src | sed -e 's/^src\\/.*:[[:space:]]*<//' | grep '^v-' | sed -e 's/\\(v-[^[:space:]>]*\\).*/\\1/' | sort | uniq" "list-vuetify-components": "ack '<v-' src | sed -e 's/^src\\/.*:[[:space:]]*<//' | grep '^v-' | sed -e 's/\\(v-[^[:space:]>]*\\).*/\\1/' | sort | uniq"
}, },
"dependencies": { "dependencies": {
"es6-promise": "^4.2.4", "babel-polyfill": "^6.26.0",
"file-saver": "^1.3.8", "file-saver": "^1.3.8",
"gps-to-gpx": "^1.3.0", "gps-to-gpx": "^1.3.0",
"howler": "^2.0.14", "howler": "^2.0.14",
@ -26,7 +26,7 @@
"nosleep.js": "^0.7.0", "nosleep.js": "^0.7.0",
"roboto-fontface": "^0.9.0", "roboto-fontface": "^0.9.0",
"vue": "^2.5.2", "vue": "^2.5.2",
"vue-i18n": "^7.8.1", "vue-i18n": "^8.0.0",
"vue-router": "^3.0.1", "vue-router": "^3.0.1",
"vue2-leaflet": "^1.0.2", "vue2-leaflet": "^1.0.2",
"vue2-leaflet-tracksymbol": "^1.0.10", "vue2-leaflet-tracksymbol": "^1.0.10",
@ -38,14 +38,9 @@
"autoprefixer": "^9.1.0", "autoprefixer": "^9.1.0",
"babel-core": "^6.22.1", "babel-core": "^6.22.1",
"babel-eslint": "^8.2.6", "babel-eslint": "^8.2.6",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^7.1.1", "babel-loader": "^7.1.1",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-preset-env": "^1.3.2", "babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0", "babel-preset-stage-2": "^6.22.0",
"chalk": "^2.0.1",
"copy-webpack-plugin": "^4.0.1", "copy-webpack-plugin": "^4.0.1",
"css-loader": "^1.0.0", "css-loader": "^1.0.0",
"eslint": "^5.3.0", "eslint": "^5.3.0",
@ -55,32 +50,29 @@
"eslint-loader": "^2.1.0", "eslint-loader": "^2.1.0",
"eslint-plugin-html": "^4.0.5", "eslint-plugin-html": "^4.0.5",
"eslint-plugin-import": "^2.7.0", "eslint-plugin-import": "^2.7.0",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.4", "file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1", "friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^3.2.0", "html-webpack-plugin": "^3.2.0",
"image-webpack-loader": "^4.3.1", "image-webpack-loader": "^4.3.1",
"node-notifier": "^5.1.2", "mini-css-extract-plugin": "^0.4.1",
"optimize-css-assets-webpack-plugin": "^5.0.0", "optimize-css-assets-webpack-plugin": "^5.0.0",
"ora": "^3.0.0", "portfinder": "^1.0.15",
"portfinder": "^1.0.13",
"postcss-import": "^12.0.0", "postcss-import": "^12.0.0",
"postcss-loader": "^2.0.8", "postcss-loader": "^2.0.8",
"postcss-url": "^7.2.1", "postcss-url": "^7.2.1",
"rimraf": "^2.6.0",
"semver": "^5.3.0",
"shelljs": "^0.8.2",
"stylus": "^0.54.5", "stylus": "^0.54.5",
"stylus-loader": "^3.0.2", "stylus-loader": "^3.0.2",
"svg-url-loader": "^2.3.2",
"svg2png": "^4.1.1", "svg2png": "^4.1.1",
"uglifyjs-webpack-plugin": "^1.1.1", "uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^1.0.1", "url-loader": "^1.0.1",
"vue-loader": "^13.3.0", "vue-loader": "^15.2.6",
"vue-style-loader": "^3.0.1", "vue-style-loader": "^4.1.1",
"vue-template-compiler": "^2.5.2", "vue-template-compiler": "^2.5.2",
"webpack": "^3.6.0", "webpack": "^4.16.5",
"webpack-bundle-analyzer": "^2.13.1", "webpack-bundle-analyzer": "^2.13.1",
"webpack-dev-server": "^2.9.1", "webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.5",
"webpack-merge": "^4.1.0" "webpack-merge": "^4.1.0"
}, },
"engines": { "engines": {

View File

@ -57,6 +57,10 @@ import L from 'leaflet';
import iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png'; import iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png';
import iconUrl from 'leaflet/dist/images/marker-icon.png'; import iconUrl from 'leaflet/dist/images/marker-icon.png';
import shadowUrl from 'leaflet/dist/images/marker-shadow.png'; import shadowUrl from 'leaflet/dist/images/marker-shadow.png';
import {
LMap, LTileLayer, LMarker, LCircleMarker, LCircle, LPolyline,
} from 'vue2-leaflet';
import Vue2LeafletTracksymbol from 'vue2-leaflet-tracksymbol';
import compassNorthIcon from '@/assets/compassNorth.svg'; import compassNorthIcon from '@/assets/compassNorth.svg';
import unknownMarkerIcon from '@/assets/unknownMarker.svg'; import unknownMarkerIcon from '@/assets/unknownMarker.svg';
@ -75,6 +79,13 @@ L.Icon.Default.mergeOptions({
export default { export default {
components: { components: {
'v-lmap': LMap,
'v-ltilelayer': LTileLayer,
'v-lmarker': LMarker,
'v-lcirclemarker': LCircleMarker,
'v-lcircle': LCircle,
'v-lpolyline': LPolyline,
'v-lts': Vue2LeafletTracksymbol,
ReportMarker, ReportMarker,
}, },
computed: { computed: {
@ -117,8 +128,9 @@ export default {
}, },
}, },
data() { data() {
const $t = this.$t.bind(this);
return { return {
attribution: this.$t('map.attribution'), attribution: $t('map.attribution'),
isProgrammaticMove: false, isProgrammaticMove: false,
isProgrammaticZoom: false, isProgrammaticZoom: false,
map: null, map: null,

View File

@ -3,6 +3,8 @@
</template> </template>
<script> <script>
import L from 'leaflet';
import { REPORT_TYPES } from '@/constants'; import { REPORT_TYPES } from '@/constants';
export default { export default {
@ -12,9 +14,9 @@ export default {
computed: { computed: {
icon() { icon() {
if (this.$store.state.reportDetails.id === this.marker.id) { if (this.$store.state.reportDetails.id === this.marker.id) {
return REPORT_TYPES[this.marker.type].markerLarge; return L.icon(REPORT_TYPES[this.marker.type].markerLarge);
} }
return REPORT_TYPES[this.marker.type].marker; return L.icon(REPORT_TYPES[this.marker.type].marker);
}, },
}, },
data() { data() {

View File

@ -1,5 +1,3 @@
import L from 'leaflet';
import accidentMarker from '@/assets/accidentMarker.svg'; import accidentMarker from '@/assets/accidentMarker.svg';
import gcumMarker from '@/assets/gcumMarker.svg'; import gcumMarker from '@/assets/gcumMarker.svg';
import interruptMarker from '@/assets/interruptMarker.svg'; import interruptMarker from '@/assets/interruptMarker.svg';
@ -20,93 +18,93 @@ export const REPORT_TYPES = {
description: 'reportLabels.accidentDescription', description: 'reportLabels.accidentDescription',
label: 'reportLabels.accident', label: 'reportLabels.accident',
image: accidentIcon, image: accidentIcon,
marker: L.icon({ marker: {
iconUrl: accidentMarker, iconUrl: accidentMarker,
iconSize: [40, 40], iconSize: [40, 40],
iconAnchor: [20, 40], iconAnchor: [20, 40],
}), },
markerLarge: L.icon({ markerLarge: {
iconUrl: accidentMarker, iconUrl: accidentMarker,
iconSize: [60, 60], iconSize: [60, 60],
iconAnchor: [30, 60], iconAnchor: [30, 60],
}), },
}, },
gcum: { gcum: {
description: 'reportLabels.gcumDescription', description: 'reportLabels.gcumDescription',
label: 'reportLabels.gcum', label: 'reportLabels.gcum',
image: gcumIcon, image: gcumIcon,
marker: L.icon({ marker: {
iconUrl: gcumMarker, iconUrl: gcumMarker,
iconSize: [40, 40], iconSize: [40, 40],
iconAnchor: [20, 40], iconAnchor: [20, 40],
}), },
markerLarge: L.icon({ markerLarge: {
iconUrl: gcumMarker, iconUrl: gcumMarker,
iconSize: [60, 60], iconSize: [60, 60],
iconAnchor: [30, 60], iconAnchor: [30, 60],
}), },
}, },
interrupt: { interrupt: {
description: 'reportLabels.interruptDescription', description: 'reportLabels.interruptDescription',
label: 'reportLabels.interrupt', label: 'reportLabels.interrupt',
image: interruptIcon, image: interruptIcon,
marker: L.icon({ marker: {
iconUrl: interruptMarker, iconUrl: interruptMarker,
iconSize: [40, 40], iconSize: [40, 40],
iconAnchor: [20, 40], iconAnchor: [20, 40],
}), },
markerLarge: L.icon({ markerLarge: {
iconUrl: interruptMarker, iconUrl: interruptMarker,
iconSize: [60, 60], iconSize: [60, 60],
iconAnchor: [30, 60], iconAnchor: [30, 60],
}), },
}, },
misc: { misc: {
description: 'reportLabels.miscDescription', description: 'reportLabels.miscDescription',
label: 'reportLabels.misc', label: 'reportLabels.misc',
image: miscIcon, image: miscIcon,
marker: L.icon({ marker: {
iconUrl: miscMarker, iconUrl: miscMarker,
iconSize: [40, 40], iconSize: [40, 40],
iconAnchor: [20, 40], iconAnchor: [20, 40],
}), },
markerLarge: L.icon({ markerLarge: {
iconUrl: miscMarker, iconUrl: miscMarker,
iconSize: [60, 60], iconSize: [60, 60],
iconAnchor: [30, 60], iconAnchor: [30, 60],
}), },
}, },
obstacle: { obstacle: {
description: 'reportLabels.obstacleDescription', description: 'reportLabels.obstacleDescription',
label: 'reportLabels.obstacle', label: 'reportLabels.obstacle',
image: obstacleIcon, image: obstacleIcon,
marker: L.icon({ marker: {
iconUrl: obstacleMarker, iconUrl: obstacleMarker,
iconSize: [40, 40], iconSize: [40, 40],
iconAnchor: [20, 40], iconAnchor: [20, 40],
}), },
markerLarge: L.icon({ markerLarge: {
iconUrl: obstacleMarker, iconUrl: obstacleMarker,
iconSize: [60, 60], iconSize: [60, 60],
iconAnchor: [30, 60], iconAnchor: [30, 60],
}), },
}, },
pothole: { pothole: {
description: 'reportLabels.potholeDescription', description: 'reportLabels.potholeDescription',
label: 'reportLabels.pothole', label: 'reportLabels.pothole',
image: potholeIcon, image: potholeIcon,
marker: L.icon({ marker: {
iconUrl: potholeMarker, iconUrl: potholeMarker,
iconSize: [40, 40], iconSize: [40, 40],
iconAnchor: [20, 40], iconAnchor: [20, 40],
}), },
markerLarge: L.icon({ markerLarge: {
iconUrl: potholeMarker, iconUrl: potholeMarker,
iconSize: [60, 60], iconSize: [60, 60],
iconAnchor: [30, 60], iconAnchor: [30, 60],
}), },
}, },
}; };
// Display order of the report types // Display order of the report types

View File

@ -1,195 +0,0 @@
/**
* Copy of the CSS file from the node_modules package, including an additional
* font-display directive.
*/
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.eot');
src: local('Roboto Thin'), local('Roboto-Thin'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.svg#Roboto') format('svg');
font-weight: 100;
font-style: normal;
}
@font-face {
font-display: swap;
font-family: 'Roboto-Thin';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.eot');
src: local('Roboto Thin'), local('Roboto-Thin'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.eot');
src: local('Roboto ThinItalic'), local('Roboto-ThinItalic'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.svg#Roboto') format('svg');
font-weight: 100;
font-style: italic;
}
@font-face {
font-display: swap;
font-family: 'Roboto-ThinItalic';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.eot');
src: local('Roboto ThinItalic'), local('Roboto-ThinItalic'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.eot');
src: local('Roboto Light'), local('Roboto-Light'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.svg#Roboto') format('svg');
font-weight: 300;
font-style: normal;
}
@font-face {
font-display: swap;
font-family: 'Roboto-Light';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.eot');
src: local('Roboto Light'), local('Roboto-Light'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.eot');
src: local('Roboto LightItalic'), local('Roboto-LightItalic'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.svg#Roboto') format('svg');
font-weight: 300;
font-style: italic;
}
@font-face {
font-display: swap;
font-family: 'Roboto-LightItalic';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.eot');
src: local('Roboto LightItalic'), local('Roboto-LightItalic'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.eot');
src: local('Roboto Regular'), local('Roboto-Regular'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.svg#Roboto') format('svg');
font-weight: 400;
font-style: normal;
}
@font-face {
font-display: swap;
font-family: 'Roboto-Regular';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.eot');
src: local('Roboto Regular'), local('Roboto-Regular'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.eot');
src: local('Roboto RegularItalic'), local('Roboto-RegularItalic'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.svg#Roboto') format('svg');
font-weight: 400;
font-style: italic;
}
@font-face {
font-display: swap;
font-family: 'Roboto-RegularItalic';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.eot');
src: local('Roboto RegularItalic'), local('Roboto-RegularItalic'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.eot');
src: local('Roboto Medium'), local('Roboto-Medium'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.svg#Roboto') format('svg');
font-weight: 500;
font-style: normal;
}
@font-face {
font-display: swap;
font-family: 'Roboto-Medium';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.eot');
src: local('Roboto Medium'), local('Roboto-Medium'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.eot');
src: local('Roboto MediumItalic'), local('Roboto-MediumItalic'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.svg#Roboto') format('svg');
font-weight: 500;
font-style: italic;
}
@font-face {
font-display: swap;
font-family: 'Roboto-MediumItalic';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.eot');
src: local('Roboto MediumItalic'), local('Roboto-MediumItalic'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.eot');
src: local('Roboto Bold'), local('Roboto-Bold'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.svg#Roboto') format('svg');
font-weight: 700;
font-style: normal;
}
@font-face {
font-display: swap;
font-family: 'Roboto-Bold';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.eot');
src: local('Roboto Bold'), local('Roboto-Bold'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.eot');
src: local('Roboto BoldItalic'), local('Roboto-BoldItalic'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.svg#Roboto') format('svg');
font-weight: 700;
font-style: italic;
}
@font-face {
font-display: swap;
font-family: 'Roboto-BoldItalic';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.eot');
src: local('Roboto BoldItalic'), local('Roboto-BoldItalic'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.eot');
src: local('Roboto Black'), local('Roboto-Black'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.svg#Roboto') format('svg');
font-weight: 900;
font-style: normal;
}
@font-face {
font-display: swap;
font-family: 'Roboto-Black';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.eot');
src: local('Roboto Black'), local('Roboto-Black'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.eot');
src: local('Roboto BlackItalic'), local('Roboto-BlackItalic'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.svg#Roboto') format('svg');
font-weight: 900;
font-style: italic;
}
@font-face {
font-display: swap;
font-family: 'Roboto-BlackItalic';
src: url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.eot');
src: local('Roboto BlackItalic'), local('Roboto-BlackItalic'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.eot?#iefix') format('embedded-opentype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.woff2') format('woff2'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.woff') format('woff'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.ttf') format('truetype'), url('../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.svg#Roboto') format('svg');
}

View File

@ -7,9 +7,9 @@
font-family: "Material Icons"; font-family: "Material Icons";
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
src: url("../../node_modules/material-icons/iconfont/MaterialIcons-Regular.eot"); src: url("../../../node_modules/material-icons/iconfont/MaterialIcons-Regular.eot");
/* For IE6-8 */ /* For IE6-8 */
src: local("Material Icons"), local("MaterialIcons-Regular"), url("../../node_modules/material-icons/iconfont/MaterialIcons-Regular.woff2") format("woff2"), url("../../node_modules/material-icons/iconfont/MaterialIcons-Regular.woff") format("woff"), url("../../node_modules/material-icons/iconfont/MaterialIcons-Regular.ttf") format("truetype"); src: local("Material Icons"), local("MaterialIcons-Regular"), url("../../../node_modules/material-icons/iconfont/MaterialIcons-Regular.woff2") format("woff2"), url("../../../node_modules/material-icons/iconfont/MaterialIcons-Regular.woff") format("woff"), url("../../../node_modules/material-icons/iconfont/MaterialIcons-Regular.ttf") format("truetype");
} }
.material-icons { .material-icons {

195
src/css/vendor/roboto-fontface.css vendored Normal file
View File

@ -0,0 +1,195 @@
/**
* Copy of the CSS file from the node_modules package, including an additional
* font-display directive.
*/
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.eot');
src: local('Roboto Thin'), local('Roboto-Thin'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.svg#Roboto') format('svg');
font-weight: 100;
font-style: normal;
}
@font-face {
font-display: swap;
font-family: 'Roboto-Thin';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.eot');
src: local('Roboto Thin'), local('Roboto-Thin'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.eot');
src: local('Roboto ThinItalic'), local('Roboto-ThinItalic'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.svg#Roboto') format('svg');
font-weight: 100;
font-style: italic;
}
@font-face {
font-display: swap;
font-family: 'Roboto-ThinItalic';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.eot');
src: local('Roboto ThinItalic'), local('Roboto-ThinItalic'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-ThinItalic.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.eot');
src: local('Roboto Light'), local('Roboto-Light'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.svg#Roboto') format('svg');
font-weight: 300;
font-style: normal;
}
@font-face {
font-display: swap;
font-family: 'Roboto-Light';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.eot');
src: local('Roboto Light'), local('Roboto-Light'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Light.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.eot');
src: local('Roboto LightItalic'), local('Roboto-LightItalic'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.svg#Roboto') format('svg');
font-weight: 300;
font-style: italic;
}
@font-face {
font-display: swap;
font-family: 'Roboto-LightItalic';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.eot');
src: local('Roboto LightItalic'), local('Roboto-LightItalic'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-LightItalic.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.eot');
src: local('Roboto Regular'), local('Roboto-Regular'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.svg#Roboto') format('svg');
font-weight: 400;
font-style: normal;
}
@font-face {
font-display: swap;
font-family: 'Roboto-Regular';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.eot');
src: local('Roboto Regular'), local('Roboto-Regular'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.eot');
src: local('Roboto RegularItalic'), local('Roboto-RegularItalic'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.svg#Roboto') format('svg');
font-weight: 400;
font-style: italic;
}
@font-face {
font-display: swap;
font-family: 'Roboto-RegularItalic';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.eot');
src: local('Roboto RegularItalic'), local('Roboto-RegularItalic'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-RegularItalic.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.eot');
src: local('Roboto Medium'), local('Roboto-Medium'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.svg#Roboto') format('svg');
font-weight: 500;
font-style: normal;
}
@font-face {
font-display: swap;
font-family: 'Roboto-Medium';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.eot');
src: local('Roboto Medium'), local('Roboto-Medium'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.eot');
src: local('Roboto MediumItalic'), local('Roboto-MediumItalic'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.svg#Roboto') format('svg');
font-weight: 500;
font-style: italic;
}
@font-face {
font-display: swap;
font-family: 'Roboto-MediumItalic';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.eot');
src: local('Roboto MediumItalic'), local('Roboto-MediumItalic'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-MediumItalic.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.eot');
src: local('Roboto Bold'), local('Roboto-Bold'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.svg#Roboto') format('svg');
font-weight: 700;
font-style: normal;
}
@font-face {
font-display: swap;
font-family: 'Roboto-Bold';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.eot');
src: local('Roboto Bold'), local('Roboto-Bold'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.eot');
src: local('Roboto BoldItalic'), local('Roboto-BoldItalic'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.svg#Roboto') format('svg');
font-weight: 700;
font-style: italic;
}
@font-face {
font-display: swap;
font-family: 'Roboto-BoldItalic';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.eot');
src: local('Roboto BoldItalic'), local('Roboto-BoldItalic'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BoldItalic.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.eot');
src: local('Roboto Black'), local('Roboto-Black'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.svg#Roboto') format('svg');
font-weight: 900;
font-style: normal;
}
@font-face {
font-display: swap;
font-family: 'Roboto-Black';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.eot');
src: local('Roboto Black'), local('Roboto-Black'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-Black.svg#Roboto') format('svg');
}
@font-face {
font-display: swap;
font-family: 'Roboto';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.eot');
src: local('Roboto BlackItalic'), local('Roboto-BlackItalic'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.svg#Roboto') format('svg');
font-weight: 900;
font-style: italic;
}
@font-face {
font-display: swap;
font-family: 'Roboto-BlackItalic';
src: url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.eot');
src: local('Roboto BlackItalic'), local('Roboto-BlackItalic'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.eot?#iefix') format('embedded-opentype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.woff2') format('woff2'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.woff') format('woff'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.ttf') format('truetype'), url('../../../node_modules/roboto-fontface/fonts/roboto/Roboto-BlackItalic.svg#Roboto') format('svg');
}

View File

@ -21,7 +21,7 @@ export const AVAILABLE_LOCALES = [
}, },
{ {
iso: 'fr', iso: 'fr',
name: 'French', name: 'Français',
messages: fr, messages: fr,
}, },
{ {

View File

@ -1,11 +1,11 @@
import '@/polyfills';
// The Vue build version to load with the `import` command // The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias. // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'; import Vue from 'vue';
import Vue2Leaflet from 'vue2-leaflet';
import Vue2LeafletTracksymbol from 'vue2-leaflet-tracksymbol';
import '@/css/roboto-fontface.css'; import '@/css/vendor/roboto-fontface.css';
import '@/css/material-icons.css'; import '@/css/vendor/material-icons.css';
import 'leaflet/dist/leaflet.css'; // eslint-disable-line import/first import 'leaflet/dist/leaflet.css'; // eslint-disable-line import/first
import 'vuetify/src/stylus/app.styl'; import 'vuetify/src/stylus/app.styl';
@ -13,20 +13,11 @@ import App from '@/App.vue';
import i18n from '@/i18n'; import i18n from '@/i18n';
import router from '@/router'; import router from '@/router';
import store from '@/store'; import store from '@/store';
import '@/polyfills';
import '@/vuetify'; import '@/vuetify';
// Ensure locale is correctly set from the store value // Ensure locale is correctly set from the store value
store.dispatch('setLocale', { locale: store.state.settings.locale }); store.dispatch('setLocale', { locale: store.state.settings.locale });
Vue.component('v-lmap', Vue2Leaflet.LMap);
Vue.component('v-ltilelayer', Vue2Leaflet.LTileLayer);
Vue.component('v-lmarker', Vue2Leaflet.LMarker);
Vue.component('v-lcirclemarker', Vue2Leaflet.LCircleMarker);
Vue.component('v-lcircle', Vue2Leaflet.LCircle);
Vue.component('v-lpolyline', Vue2Leaflet.LPolyline);
Vue.component('v-lts', Vue2LeafletTracksymbol);
Vue.config.productionTip = false; Vue.config.productionTip = false;
new Vue({ // eslint-disable-line no-new new Vue({ // eslint-disable-line no-new
@ -35,5 +26,7 @@ new Vue({ // eslint-disable-line no-new
i18n, i18n,
store, store,
components: { App }, components: { App },
template: '<App/>', render(h) {
return h('App');
},
}); });

View File

@ -1,7 +1,8 @@
require('babel-polyfill');
if (!Number.isNaN) { if (!Number.isNaN) {
// From https://developer.mozilla.org/pl/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN // From https://developer.mozilla.org/pl/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN
Number.isNaN = value => (value !== value); // eslint-disable-line no-self-compare Number.isNaN = value => (value !== value); // eslint-disable-line no-self-compare
} }
require('es6-promise').polyfill();
require('isomorphic-fetch'); require('isomorphic-fetch');

View File

@ -4,12 +4,13 @@ import Router from 'vue-router';
import store from '@/store'; import store from '@/store';
import About from '@/views/About.vue'; import About from '@/views/About.vue';
import Map from '@/views/Map.vue';
import Onboarding from '@/views/Onboarding.vue'; import Onboarding from '@/views/Onboarding.vue';
import Settings from '@/views/Settings.vue'; import Settings from '@/views/Settings.vue';
Vue.use(Router); Vue.use(Router);
const Map = () => import('@/views/Map.vue');
export default new Router({ export default new Router({
routes: [ routes: [
{ {

View File

@ -173,7 +173,8 @@ export default {
); );
} else { } else {
if (!('geolocation' in navigator)) { if (!('geolocation' in navigator)) {
this.$store.dispatch('setLocationError', { error: this.$t('geolocation.unavailable') }); const $t = this.$t.bind(this);
this.$store.dispatch('setLocationError', { error: $t('geolocation.unavailable') });
return; return;
} }

963
yarn.lock

File diff suppressed because it is too large Load Diff