diff --git a/template/build/build_preprod.js b/template/build/build_preprod.js new file mode 100644 index 0000000000..f8974b00ad --- /dev/null +++ b/template/build/build_preprod.js @@ -0,0 +1,35 @@ +require('./check-versions')() + +process.env.NODE_ENV = 'preproduction' + +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.preprod.conf') + +var spinner = ora('building for preproduction...') +spinner.start() + +rm(path.join(config.build_preprod.assetsRoot, config.build_preprod.assetsSubDirectory), err => { + if (err) throw err + webpack(webpackConfig, function (err, stats) { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, + chunks: false, + chunkModules: false + }) + '\n\n') + + 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' + )) + }) +}) diff --git a/template/build/utils.js b/template/build/utils.js index b1d54b4d6c..f412e6ed24 100644 --- a/template/build/utils.js +++ b/template/build/utils.js @@ -5,7 +5,7 @@ var ExtractTextPlugin = require('extract-text-webpack-plugin') exports.assetsPath = function (_path) { var assetsSubDirectory = process.env.NODE_ENV === 'production' ? config.build.assetsSubDirectory - : config.dev.assetsSubDirectory + : (process.env.NODE_ENV === 'preproduction' ? config.build_preprod.assetsSubDirectory : config.dev.assetsSubDirectory) return path.posix.join(assetsSubDirectory, _path) } @@ -15,7 +15,7 @@ exports.cssLoaders = function (options) { var cssLoader = { loader: 'css-loader', options: { - minimize: process.env.NODE_ENV === 'production', + minimize: process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'preproduction', sourceMap: options.sourceMap } } diff --git a/template/build/webpack.base.conf.js b/template/build/webpack.base.conf.js index b32c985e9c..542bb72ddf 100644 --- a/template/build/webpack.base.conf.js +++ b/template/build/webpack.base.conf.js @@ -16,7 +16,7 @@ module.exports = { filename: '[name].js', publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath - : config.dev.assetsPublicPath + : (process.env.NODE_ENV === 'preproduction' ? config.build_preprod.assetsPublicPath : config.dev.assetsPublicPath) }, resolve: { extensions: ['.js', '.vue', '.json'], diff --git a/template/build/webpack.preprod.conf.js b/template/build/webpack.preprod.conf.js new file mode 100644 index 0000000000..3206da9da7 --- /dev/null +++ b/template/build/webpack.preprod.conf.js @@ -0,0 +1,116 @@ +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') + +var env = config.build_preprod.env + +var webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build_preprod.productionSourceMap, + extract: true + }) + }, + devtool: config.build_preprod.productionSourceMap ? '#source-map' : false, + output: { + path: config.build_preprod.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + new webpack.optimize.UglifyJsPlugin({ + compress: { + warnings: false + }, + sourceMap: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css') + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin(), + // 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_preprod.index, + template: 'index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks: function (module, count) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + chunks: ['vendor'] + }), + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.build_preprod.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +if (config.build_preprod.productionGzip) { + var CompressionWebpackPlugin = require('compression-webpack-plugin') + + webpackConfig.plugins.push( + new CompressionWebpackPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp( + '\\.(' + + config.build_preprod.productionGzipExtensions.join('|') + + ')$' + ), + threshold: 10240, + minRatio: 0.8 + }) + ) +} + +if (config.build_preprod.bundleAnalyzerReport) { + var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + webpackConfig.plugins.push(new BundleAnalyzerPlugin()) +} + +module.exports = webpackConfig diff --git a/template/config/index.js b/template/config/index.js index 196da1fa7d..d6a18ec17e 100644 --- a/template/config/index.js +++ b/template/config/index.js @@ -21,6 +21,25 @@ module.exports = { // Set to `true` or `false` to always turn it on or off bundleAnalyzerReport: process.env.npm_config_report }, + build_preprod: { + env: require('./preprod.env'), + index: path.resolve(__dirname, '../dist/index.html'), + assetsRoot: path.resolve(__dirname, '../dist'), + assetsSubDirectory: 'static', + assetsPublicPath: '/', + productionSourceMap: true, + // 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: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + }, dev: { env: require('./dev.env'), port: 8080, diff --git a/template/config/preprod.env.js b/template/config/preprod.env.js new file mode 100644 index 0000000000..27ea355399 --- /dev/null +++ b/template/config/preprod.env.js @@ -0,0 +1,6 @@ +var merge = require('webpack-merge') +var prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"preproduction"' +}) diff --git a/template/package.json b/template/package.json index e70020564a..13054a2710 100644 --- a/template/package.json +++ b/template/package.json @@ -7,7 +7,8 @@ "scripts": { "dev": "node build/dev-server.js", "start": "node build/dev-server.js", - "build": "node build/build.js",{{#unit}} + "build": "node build/build.js", + "build_preprod": "node build/build_preprod.js",{{#unit}} "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",{{/unit}}{{#e2e}} "e2e": "node test/e2e/runner.js",{{/e2e}}{{#if_or unit e2e}} "test": "{{#unit}}npm run unit{{/unit}}{{#unit}}{{#e2e}} && {{/e2e}}{{/unit}}{{#e2e}}npm run e2e{{/e2e}}",{{/if_or}} @@ -15,6 +16,10 @@ }, "dependencies": { "axios": "^0.15.3", + "buefy": "^0.3.1", + "bulma": "^0.4.1", + "font-awesome": "^4.7.0", + "moment": "^2.18.1", "vue": "^2.3.3", "vue-router": "^2.3.1", "vuex": "^2.2.1" diff --git a/template/src/main.js b/template/src/main.js index b301b3730f..bfbbef6930 100644 --- a/template/src/main.js +++ b/template/src/main.js @@ -2,9 +2,24 @@ import Vue from 'vue' import App from './App' import router from './router' import store from './store/store' +import Buefy from 'buefy' +import moment from 'moment' +import 'bulma/css/bulma.css' +import 'font-awesome/css/font-awesome.css' +import 'buefy/lib/buefy.css' Vue.config.productionTip = false +Vue.filter('formatDate', function (value) { + if (value) { + return moment(String(value)).format('DD-MMM-YYYY') + } +}) + +Vue.use(Buefy, { + defaultIconPack: 'fa' +}) + /* eslint-disable no-new */ new Vue({ el : '#app',