diff --git a/admin/.babelrc b/admin/.babelrc index 6fb5f59..c06df4d 100644 --- a/admin/.babelrc +++ b/admin/.babelrc @@ -1,14 +1,18 @@ { "presets": [ - ["env", { "modules": false }], + ["env", { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + }], "stage-2" ], "plugins": ["transform-runtime"], "env": { "test": { "presets": ["env", "stage-2"], - "plugins": [ "istanbul" ] + "plugins": ["istanbul"] } - }, - "comments": false + } } diff --git a/admin/build/build.js b/admin/build/build.js index 6b8add1..30f036a 100644 --- a/admin/build/build.js +++ b/admin/build/build.js @@ -1,16 +1,17 @@ +'use strict' require('./check-versions')() process.env.NODE_ENV = 'production' -var ora = require('ora') -var rm = require('rimraf') -var path = require('path') -var chalk = require('chalk') -var webpack = require('webpack') -var config = require('../config') -var webpackConfig = require('./webpack.prod.conf') +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') -var spinner = ora('building for production...') +const spinner = ora('building for production...') spinner.start() rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { @@ -26,6 +27,11 @@ rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 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' + diff --git a/admin/build/check-versions.js b/admin/build/check-versions.js index 100f3a0..ca407bb 100644 --- a/admin/build/check-versions.js +++ b/admin/build/check-versions.js @@ -1,17 +1,18 @@ -var chalk = require('chalk') -var semver = require('semver') -var packageConfig = require('../package.json') -var shell = require('shelljs') +'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() } -var versionRequirements = [ +const versionRequirements = [ { name: 'node', currentVersion: semver.clean(process.version), versionRequirement: packageConfig.engines.node - }, + } ] if (shell.which('npm')) { @@ -23,9 +24,9 @@ if (shell.which('npm')) { } module.exports = function () { - var warnings = [] - for (var i = 0; i < versionRequirements.length; i++) { - var mod = versionRequirements[i] + 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 ' + @@ -38,8 +39,8 @@ module.exports = function () { console.log('') console.log(chalk.yellow('To use this template, you must update following to modules:')) console.log() - for (var i = 0; i < warnings.length; i++) { - var warning = warnings[i] + for (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] console.log(' ' + warning) } console.log() diff --git a/admin/build/dev-client.js b/admin/build/dev-client.js index 18aa1e2..2f75dd5 100644 --- a/admin/build/dev-client.js +++ b/admin/build/dev-client.js @@ -1,4 +1,5 @@ /* eslint-disable */ +'use strict' require('eventsource-polyfill') var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') diff --git a/admin/build/dev-server.js b/admin/build/dev-server.js index d376ea6..a503b51 100644 --- a/admin/build/dev-server.js +++ b/admin/build/dev-server.js @@ -1,48 +1,55 @@ +'use strict' require('./check-versions')() -var config = require('../config') +const config = require('../config') if (!process.env.NODE_ENV) { process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV) } -var opn = require('opn') -var path = require('path') -var express = require('express') -var webpack = require('webpack') -var proxyMiddleware = require('http-proxy-middleware') -var webpackConfig = require('./webpack.dev.conf') +const opn = require('opn') +const path = require('path') +const express = require('express') +const webpack = require('webpack') +const proxyMiddleware = require('http-proxy-middleware') +const webpackConfig = require('./webpack.dev.conf') // default port where dev server listens for incoming traffic -var port = process.env.PORT || config.dev.port +const port = process.env.PORT || config.dev.port // automatically open browser, if not set will be false -var autoOpenBrowser = !!config.dev.autoOpenBrowser +const autoOpenBrowser = !!config.dev.autoOpenBrowser // Define HTTP proxies to your custom API backend // https://github.com/chimurai/http-proxy-middleware -var proxyTable = config.dev.proxyTable +const proxyTable = config.dev.proxyTable -var app = express() -var compiler = webpack(webpackConfig) +const app = express() +const compiler = webpack(webpackConfig) -var devMiddleware = require('webpack-dev-middleware')(compiler, { +const devMiddleware = require('webpack-dev-middleware')(compiler, { publicPath: webpackConfig.output.publicPath, quiet: true }) -var hotMiddleware = require('webpack-hot-middleware')(compiler, { - log: () => {}, +const hotMiddleware = require('webpack-hot-middleware')(compiler, { + log: false, heartbeat: 2000 }) // 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() - }) -}) +// currently disabled until this is resolved: +// https://github.com/jantimon/html-webpack-plugin/issues/680 +// compiler.plugin('compilation', function (compilation) { +// compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { +// hotMiddleware.publish({ action: 'reload' }) +// cb() +// }) +// }) + +// enable hot-reload and state-preserving +// compilation error display +app.use(hotMiddleware) // proxy api requests Object.keys(proxyTable).forEach(function (context) { - var options = proxyTable[context] + let options = proxyTable[context] if (typeof options === 'string') { options = { target: options } } @@ -55,33 +62,41 @@ 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 staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) +const staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) app.use(staticPath, express.static('./static')) -var uri = 'http://localhost:' + port +const uri = 'http://localhost:' + port var _resolve -var readyPromise = new Promise(resolve => { +var _reject +var readyPromise = new Promise((resolve, reject) => { _resolve = resolve + _reject = reject }) +var server +var portfinder = require('portfinder') +portfinder.basePort = port + console.log('> Starting dev server...') devMiddleware.waitUntilValid(() => { - console.log('> Listening at ' + uri + '\n') - // when env is testing, don't need open it - if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { - opn(uri) - } - _resolve() + portfinder.getPort((err, port) => { + if (err) { + _reject(err) + } + process.env.PORT = port + var uri = 'http://localhost:' + port + console.log('> Listening at ' + uri + '\n') + // when env is testing, don't need open it + if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { + opn(uri) + } + server = app.listen(port) + _resolve() + }) }) -var server = app.listen(port) - module.exports = { ready: readyPromise, close: () => { diff --git a/admin/build/utils.js b/admin/build/utils.js index b1d54b4..4ac71cb 100644 --- a/admin/build/utils.js +++ b/admin/build/utils.js @@ -1,9 +1,10 @@ -var path = require('path') -var config = require('../config') -var ExtractTextPlugin = require('extract-text-webpack-plugin') +'use strict' +const path = require('path') +const config = require('../config') +const ExtractTextPlugin = require('extract-text-webpack-plugin') exports.assetsPath = function (_path) { - var assetsSubDirectory = process.env.NODE_ENV === 'production' + const assetsSubDirectory = process.env.NODE_ENV === 'production' ? config.build.assetsSubDirectory : config.dev.assetsSubDirectory return path.posix.join(assetsSubDirectory, _path) @@ -12,7 +13,7 @@ exports.assetsPath = function (_path) { exports.cssLoaders = function (options) { options = options || {} - var cssLoader = { + const cssLoader = { loader: 'css-loader', options: { minimize: process.env.NODE_ENV === 'production', @@ -22,7 +23,7 @@ exports.cssLoaders = function (options) { // generate loader string to be used with extract text plugin function generateLoaders (loader, loaderOptions) { - var loaders = [cssLoader] + const loaders = [cssLoader] if (loader) { loaders.push({ loader: loader + '-loader', @@ -58,10 +59,10 @@ exports.cssLoaders = function (options) { // Generate loaders for standalone style files (outside of .vue) exports.styleLoaders = function (options) { - var output = [] - var loaders = exports.cssLoaders(options) - for (var extension in loaders) { - var loader = loaders[extension] + const output = [] + const loaders = exports.cssLoaders(options) + for (const extension in loaders) { + const loader = loaders[extension] output.push({ test: new RegExp('\\.' + extension + '$'), use: loader diff --git a/admin/build/vue-loader.conf.js b/admin/build/vue-loader.conf.js index 8a346d5..eece58f 100644 --- a/admin/build/vue-loader.conf.js +++ b/admin/build/vue-loader.conf.js @@ -1,6 +1,7 @@ -var utils = require('./utils') -var config = require('../config') -var isProduction = process.env.NODE_ENV === 'production' +'use strict' +const utils = require('./utils') +const config = require('../config') +const isProduction = process.env.NODE_ENV === 'production' module.exports = { loaders: utils.cssLoaders({ diff --git a/admin/build/webpack.base.conf.js b/admin/build/webpack.base.conf.js index f2899c5..8380237 100644 --- a/admin/build/webpack.base.conf.js +++ b/admin/build/webpack.base.conf.js @@ -1,7 +1,8 @@ -var path = require('path') -var utils = require('./utils') -var config = require('../config') -var vueLoaderConfig = require('./vue-loader.conf') +'use strict' +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const vueLoaderConfig = require('./vue-loader.conf') function resolve (dir) { return path.join(__dirname, '..', dir) @@ -21,8 +22,7 @@ module.exports = { resolve: { extensions: ['.js', '.vue', '.json'], alias: { - 'vue$': 'vue/dist/vue.esm.js', - '@': resolve('src') + '@': resolve('src'), } }, module: { diff --git a/admin/build/webpack.dev.conf.js b/admin/build/webpack.dev.conf.js index 5470402..6f25d63 100644 --- a/admin/build/webpack.dev.conf.js +++ b/admin/build/webpack.dev.conf.js @@ -1,10 +1,11 @@ -var utils = require('./utils') -var webpack = require('webpack') -var config = require('../config') -var merge = require('webpack-merge') -var baseWebpackConfig = require('./webpack.base.conf') -var HtmlWebpackPlugin = require('html-webpack-plugin') -var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +'use strict' +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') // add hot-reload related code to entry chunks Object.keys(baseWebpackConfig.entry).forEach(function (name) { diff --git a/admin/build/webpack.prod.conf.js b/admin/build/webpack.prod.conf.js index da44b65..dcb239d 100644 --- a/admin/build/webpack.prod.conf.js +++ b/admin/build/webpack.prod.conf.js @@ -1,17 +1,18 @@ -var path = require('path') -var utils = require('./utils') -var webpack = require('webpack') -var config = require('../config') -var merge = require('webpack-merge') -var baseWebpackConfig = require('./webpack.base.conf') -var CopyWebpackPlugin = require('copy-webpack-plugin') -var HtmlWebpackPlugin = require('html-webpack-plugin') -var ExtractTextPlugin = require('extract-text-webpack-plugin') -var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') -var env = config.build.env +const env = config.build.env -var webpackConfig = merge(baseWebpackConfig, { +const webpackConfig = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, @@ -29,6 +30,7 @@ var webpackConfig = merge(baseWebpackConfig, { new webpack.DefinePlugin({ 'process.env': env }), + // UglifyJs do not support ES6+, you can also use babel-minify for better treeshaking: https://github.com/babel/minify new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false @@ -63,10 +65,12 @@ var webpackConfig = merge(baseWebpackConfig, { // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency' }), + // keep module.id stable when vender modules does not change + new webpack.HashedModuleIdsPlugin(), // split vendor js into its own file new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', - minChunks: function (module, count) { + minChunks: function (module) { // any required modules inside node_modules are extracted to vendor return ( module.resource && @@ -95,7 +99,7 @@ var webpackConfig = merge(baseWebpackConfig, { }) if (config.build.productionGzip) { - var CompressionWebpackPlugin = require('compression-webpack-plugin') + const CompressionWebpackPlugin = require('compression-webpack-plugin') webpackConfig.plugins.push( new CompressionWebpackPlugin({ @@ -113,7 +117,7 @@ if (config.build.productionGzip) { } if (config.build.bundleAnalyzerReport) { - var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin webpackConfig.plugins.push(new BundleAnalyzerPlugin()) } diff --git a/admin/config/dev.env.js b/admin/config/dev.env.js index efead7c..1e22973 100644 --- a/admin/config/dev.env.js +++ b/admin/config/dev.env.js @@ -1,5 +1,6 @@ -var merge = require('webpack-merge') -var prodEnv = require('./prod.env') +'use strict' +const merge = require('webpack-merge') +const prodEnv = require('./prod.env') module.exports = merge(prodEnv, { NODE_ENV: '"development"' diff --git a/admin/config/index.js b/admin/config/index.js index 0582e91..8a34349 100644 --- a/admin/config/index.js +++ b/admin/config/index.js @@ -1,5 +1,9 @@ + +'use strict' +// Template version: 1.1.3 // see http://vuejs-templates.github.io/webpack for documentation. -var path = require('path') + +const path = require('path') module.exports = { build: { diff --git a/admin/package.json b/admin/package.json index 8bc3e96..df964f2 100644 --- a/admin/package.json +++ b/admin/package.json @@ -6,26 +6,21 @@ "private": true, "scripts": { "dev": "node build/dev-server.js", - "start": "node build/dev-server.js", + "start": "npm run dev", "build": "node build/build.js", "lint": "eslint --ext .js,.vue src" }, "dependencies": { "axios": "^0.17.0", - "css-loader": "^0.28.7", "element-ui": "^1.4.9", - "file-loader": "^0.11.2", "font-awesome": "^4.7.0", - "less-loader": "^4.0.5", - "moment": "^2.18.1", + "moment": "^2.19.1", "simditor": "^2.3.6", "simditor-markdown": "^1.1.2", "vue": "^2.5.3", - "vue-codemirror": "^3.1.0", - "vue-i18n": "^7.0.5", - "vue-loader": "^12.2.2", - "vue-router": "^2.6.0", - "vue-template-compiler": "^2.5.3" + "vue-codemirror": "^3.1.8", + "vue-i18n": "^7.3.2", + "vue-router": "^2.8.1" }, "devDependencies": { "autoprefixer": "^7.1.2", @@ -39,38 +34,40 @@ "chalk": "^2.0.1", "connect-history-api-fallback": "^1.3.0", "copy-webpack-plugin": "^4.0.1", - "css-loader": "^0.28.4", - "cssnano": "^3.10.0", + "css-loader": "^0.28.0", "eslint": "^3.19.0", - "eslint-config-standard": "^6.2.1", + "eslint-config-standard": "^10.2.1", "eslint-friendly-formatter": "^3.0.0", "eslint-loader": "^1.7.1", "eslint-plugin-html": "^3.0.0", + "eslint-plugin-import": "^2.7.0", + "eslint-plugin-node": "^5.2.0", "eslint-plugin-promise": "^3.4.0", - "eslint-plugin-standard": "^2.0.1", + "eslint-plugin-standard": "^3.0.1", "eventsource-polyfill": "^0.9.6", "express": "^4.14.1", - "extract-text-webpack-plugin": "^2.0.0", - "file-loader": "^0.11.1", - "friendly-errors-webpack-plugin": "^1.1.3", - "html-webpack-plugin": "^2.28.0", + "extract-text-webpack-plugin": "^3.0.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^2.30.1", "http-proxy-middleware": "^0.17.3", "less": "^2.7.2", "less-loader": "^4.0.5", "opn": "^5.1.0", - "optimize-css-assets-webpack-plugin": "^2.0.0", + "optimize-css-assets-webpack-plugin": "^3.2.0", "ora": "^1.2.0", + "portfinder": "^1.0.13", "rimraf": "^2.6.0", "semver": "^5.3.0", "shelljs": "^0.7.6", "url-loader": "^0.5.8", - "vue-loader": "^12.1.0", + "vue-loader": "^13.5.0", "vue-style-loader": "^3.0.1", - "vue-template-compiler": "^2.3.3", - "webpack": "^2.6.1", - "webpack-bundle-analyzer": "^2.2.1", - "webpack-dev-middleware": "^1.10.0", - "webpack-hot-middleware": "^2.18.0", + "vue-template-compiler": "^2.5.3", + "webpack": "^3.6.0", + "webpack-bundle-analyzer": "^2.9.0", + "webpack-dev-middleware": "^1.12.0", + "webpack-hot-middleware": "^2.18.2", "webpack-merge": "^4.1.0" }, "engines": { diff --git a/admin/src/App.vue b/admin/src/App.vue index cd93472..8eaf8de 100644 --- a/admin/src/App.vue +++ b/admin/src/App.vue @@ -9,7 +9,6 @@ name: 'app', components: {} } -