mirror of
https://github.com/prurigro/hypothetical.git
synced 2024-11-21 23:52:31 -05:00
Upgrade to Vue 3, replace vue-resource with axios, update other libraries, set the NODE_ENV to production in the gulpfile when --production is specified rather than in the init.sh, and improve the README
This commit is contained in:
parent
30f57e6082
commit
ef617ac409
11 changed files with 3800 additions and 9381 deletions
129
gulpfile.js
129
gulpfile.js
|
@ -2,7 +2,6 @@
|
|||
const gulp = require("gulp"),
|
||||
minimist = require("minimist"),
|
||||
log = require("fancy-log"),
|
||||
insert = require("gulp-insert"),
|
||||
plumber = require("gulp-plumber"),
|
||||
concat = require("gulp-concat"),
|
||||
fs = require("fs"),
|
||||
|
@ -21,10 +20,10 @@ const babel = require("gulp-babel"),
|
|||
uglify = require("gulp-uglify-es").default;
|
||||
|
||||
// Vue packages
|
||||
const browserify = require("browserify"),
|
||||
vueify = require("vueify-next"),
|
||||
source = require("vinyl-source-stream"),
|
||||
buffer = require("vinyl-buffer");
|
||||
const webpack = require("webpack"),
|
||||
terserWebpackPlugin = require("terser-webpack-plugin"),
|
||||
{ VueLoaderPlugin } = require("vue-loader"),
|
||||
path = require("path");
|
||||
|
||||
// Determine if gulp has been run with --production
|
||||
const isProduction = minimist(process.argv.slice(2)).production !== undefined;
|
||||
|
@ -32,15 +31,16 @@ const isProduction = minimist(process.argv.slice(2)).production !== undefined;
|
|||
// Include browsersync when gulp has not been run with --production
|
||||
let browserSync = undefined;
|
||||
|
||||
if (!isProduction) {
|
||||
if (isProduction) {
|
||||
process.env.NODE_ENV = "production";
|
||||
} else {
|
||||
browserSync = require("browser-sync").create();
|
||||
}
|
||||
|
||||
// Declare plugin settings
|
||||
const sassOutputStyle = isProduction ? "compressed" : "expanded",
|
||||
sassPaths = [ "node_modules" ],
|
||||
autoprefixerSettings = { remove: false, cascade: false },
|
||||
vuePaths = [ "./node_modules", "./resources/components", "./resources/js" ];
|
||||
autoprefixerSettings = { remove: false, cascade: false };
|
||||
|
||||
// Javascript files for the public site
|
||||
const jsPublic = "resources/js/app.js";
|
||||
|
@ -120,43 +120,86 @@ function processCSS(outputFilename, inputFiles) {
|
|||
}
|
||||
|
||||
// Process vue
|
||||
function processVue(outputFilename, inputFile) {
|
||||
const processedDir = "storage/app/",
|
||||
processedFile = `__${outputFilename}.js`;
|
||||
function processVue(outputFilename, inputFile, done) {
|
||||
webpack({
|
||||
mode: isProduction ? "production" : "development",
|
||||
entry: [ `./${inputFile}` ],
|
||||
output: { path: path.resolve(__dirname, "public/js"), filename: `${outputFilename}.js` },
|
||||
devtool: false,
|
||||
|
||||
const preProcess = () => {
|
||||
const javascript = gulp.src([ inputFile ]);
|
||||
performance: {
|
||||
maxEntrypointSize: 500000,
|
||||
maxAssetSize: 500000
|
||||
},
|
||||
|
||||
if (isProduction) {
|
||||
javascript.pipe(insert.transform(function(contents) {
|
||||
return contents.replace(/vue\.js/, "vue.min.js");
|
||||
}));
|
||||
resolve: {
|
||||
alias: {
|
||||
vue$: "vue/dist/vue.esm-bundler.js",
|
||||
vuex$: "vuex/dist/vuex.esm-bundler.js",
|
||||
pages: path.resolve(__dirname, "resources/components/pages"),
|
||||
sections: path.resolve(__dirname, "resources/components/sections"),
|
||||
partials: path.resolve(__dirname, "resources/components/partials"),
|
||||
mixins: path.resolve(__dirname, "resources/js/mixins"),
|
||||
imports: path.resolve(__dirname, "resources/js/imports")
|
||||
}
|
||||
},
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: "vue-loader",
|
||||
options: { presets: [ [ "@babel/preset-env" ] ] }
|
||||
},
|
||||
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: "babel-loader",
|
||||
options: { presets: [ [ "@babel/preset-env" ] ] }
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({ __VUE_OPTIONS_API__: true, __VUE_PROD_DEVTOOLS__: false }),
|
||||
new VueLoaderPlugin()
|
||||
],
|
||||
|
||||
optimization: {
|
||||
minimizer: [
|
||||
new terserWebpackPlugin({
|
||||
extractComments: false,
|
||||
|
||||
terserOptions: {
|
||||
format: { comments: false },
|
||||
compress: { drop_console: isProduction }
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
||||
}, (err, stats) => {
|
||||
let statsJson;
|
||||
|
||||
if (err) {
|
||||
log.error(err.stack || err);
|
||||
|
||||
if (err.details) {
|
||||
log.error(err.details);
|
||||
}
|
||||
} else if (stats.hasWarnings() || stats.hasErrors()) {
|
||||
statsString = stats.toString("errors-only", {
|
||||
colors: true,
|
||||
modules: false,
|
||||
children: false,
|
||||
chunks: false,
|
||||
chunkModules: false
|
||||
});
|
||||
|
||||
log.error(statsString);
|
||||
}
|
||||
|
||||
return javascript.pipe(concat(processedFile))
|
||||
.pipe(gulp.dest(processedDir));
|
||||
};
|
||||
|
||||
const process = () => {
|
||||
const javascript = browserify({
|
||||
entries: [ processedDir + processedFile ],
|
||||
paths: vuePaths
|
||||
}).transform("babelify")
|
||||
.transform(vueify)
|
||||
.bundle()
|
||||
.on("error", handleError)
|
||||
.pipe(source(`${outputFilename}.js`))
|
||||
.pipe(buffer());
|
||||
|
||||
if (isProduction) {
|
||||
javascript.pipe(stripDebug()).pipe(uglify().on("error", handleError));
|
||||
}
|
||||
|
||||
return javascript.pipe(gulp.dest("public/js/"));
|
||||
};
|
||||
|
||||
preProcess();
|
||||
return process();
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
// Process javascript
|
||||
|
@ -210,8 +253,8 @@ gulp.task("css-dashboard-libs", () => {
|
|||
});
|
||||
|
||||
// Task for public javascript
|
||||
gulp.task("js-public", () => {
|
||||
return processVue("app", jsPublic);
|
||||
gulp.task("js-public", (done) => {
|
||||
return processVue("app", jsPublic, done);
|
||||
});
|
||||
|
||||
// Task for public javascript libraries
|
||||
|
|
2
init.sh
2
init.sh
|
@ -101,7 +101,7 @@ msg "Running: ${c_m}npm install --production"
|
|||
npm install --production || error "${c_m}npm install --production$c_w exited with an error status"
|
||||
|
||||
msg "Running: ${c_m}gulp --production"
|
||||
NODE_ENV=production "$(npm bin)/gulp" --production || error "${c_m}gulp --production$c_w exited with an error status"
|
||||
"$(npm bin)/gulp" --production || error "${c_m}gulp --production$c_w exited with an error status"
|
||||
|
||||
if (( artisan_down )); then
|
||||
msg "Running: ${c_m}php artisan up"
|
||||
|
|
12885
package-lock.json
generated
12885
package-lock.json
generated
File diff suppressed because it is too large
Load diff
36
package.json
36
package.json
|
@ -5,27 +5,26 @@
|
|||
"dev": "gulp default watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"browser-sync": "2.27.9"
|
||||
"browser-sync": "2.27.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "7.17.8",
|
||||
"@babel/preset-env": "7.16.11",
|
||||
"@babel/core": "7.18.5",
|
||||
"@babel/preset-env": "7.18.2",
|
||||
"@fortawesome/fontawesome-free": "5.15.4",
|
||||
"@mr-hope/gulp-sass": "2.0.0",
|
||||
"autonumeric": "4.6.0",
|
||||
"autoprefixer": "10.4.4",
|
||||
"babelify": "10.0.0",
|
||||
"autoprefixer": "10.4.5",
|
||||
"axios": "0.27.2",
|
||||
"babel-loader": "8.2.5",
|
||||
"bootstrap": "5.1.3",
|
||||
"browserify": "17.0.0",
|
||||
"easymde": "2.16.1",
|
||||
"fancy-log": "2.0.0",
|
||||
"flatpickr": "4.6.11",
|
||||
"gsap": "3.9.1",
|
||||
"flatpickr": "4.6.13",
|
||||
"gsap": "3.10.4",
|
||||
"gulp": "4.0.2",
|
||||
"gulp-babel": "8.0.0",
|
||||
"gulp-clean-css": "4.3.0",
|
||||
"gulp-concat": "2.6.1",
|
||||
"gulp-insert": "0.5.0",
|
||||
"gulp-plumber": "1.2.1",
|
||||
"gulp-postcss": "9.0.1",
|
||||
"gulp-sass-glob": "1.1.0",
|
||||
|
@ -35,19 +34,16 @@
|
|||
"list.js": "2.3.1",
|
||||
"minimist": "1.2.6",
|
||||
"popper.js": "1.16.1",
|
||||
"postcss": "8.4.12",
|
||||
"postcss": "8.4.14",
|
||||
"sass": "1.32.12",
|
||||
"sortablejs": "1.15.0",
|
||||
"spinkit": "2.0.1",
|
||||
"vinyl-buffer": "1.0.1",
|
||||
"vinyl-source-stream": "2.0.0",
|
||||
"vue": "2.6.14",
|
||||
"vue-resource": "1.5.3",
|
||||
"vue-router": "3.5.3",
|
||||
"vue-template-compiler": "2.6.14",
|
||||
"vueify-next": "9.6.0",
|
||||
"vuex": "3.6.2",
|
||||
"vuex-router-sync": "5.0.0",
|
||||
"what-input": "5.2.10"
|
||||
"terser-webpack-plugin": "5.3.3",
|
||||
"vue": "3.2.37",
|
||||
"vue-loader": "17.0.0",
|
||||
"vue-router": "4.0.16",
|
||||
"vuex": "4.0.2",
|
||||
"webpack": "5.73.0",
|
||||
"what-input": "5.2.12"
|
||||
}
|
||||
}
|
||||
|
|
26
readme.md
26
readme.md
|
@ -3,7 +3,24 @@
|
|||
A Hypothetical website template for bootstrapping new projects.
|
||||
|
||||
* Written and maintained by Kevin MacMartin
|
||||
* Based on Laravel 9.1.8
|
||||
|
||||
## Features
|
||||
|
||||
* A choice between an SPA on top of a PHP backend or a pure SSR site (See the [Public](#public) section below for more information)
|
||||
* A flexible dashboard for managing data/assets and displaying collected form data
|
||||
* Great defaults and popular libraries to build on top of
|
||||
* A custom Sass function allowing values to be specified in `px` and output in `rem`
|
||||
|
||||
## Major Components
|
||||
|
||||
* Bootstrap 5
|
||||
* Fontawesome 5
|
||||
* Gsap 3
|
||||
* Gulp 4
|
||||
* Jquery 3
|
||||
* Laravel 9
|
||||
* Sass 1.32
|
||||
* Vue 3 (Optional)
|
||||
|
||||
## Setup
|
||||
|
||||
|
@ -64,7 +81,12 @@ BrowserSync is used to keep the browser in sync with your code when running the
|
|||
|
||||
## Public
|
||||
|
||||
The default public facing website uses Vue.js. To configure a non-SPA traditional website, look at the files in `traditional-bootstrap`.
|
||||
The default public facing website is an SPA using Vue.js. To configure a non-SPA traditional SSR website remove the following files before moving the contents of `traditional-bootstrap` into the root project:
|
||||
|
||||
* `package-lock.json`
|
||||
* `resources/components`
|
||||
* `resources/js/mixins`
|
||||
* `resources/js/imports`
|
||||
|
||||
The following list of files and directories are where various pieces of the public website are located:
|
||||
|
||||
|
|
|
@ -55,8 +55,8 @@
|
|||
methods: {
|
||||
populateBlogEntries() {
|
||||
this.$http.get("/api/blog-entries" + env.apiToken).then((response) => {
|
||||
this.blogEntries = response.body;
|
||||
}, (response) => {
|
||||
this.blogEntries = response.data;
|
||||
}).catch((error) => {
|
||||
console.log("Failed to retrieve blog entries");
|
||||
});
|
||||
}
|
||||
|
|
|
@ -90,17 +90,17 @@
|
|||
this.submitting = true;
|
||||
$(this.$el).find(":input.error").removeClass("error");
|
||||
|
||||
this.$http.post("/api/contact-submit" + env.apiToken, JSON.stringify(this.form)).then((response) => {
|
||||
this.$http.post("/api/contact-submit" + env.apiToken, this.form).then((response) => {
|
||||
// Success
|
||||
$(this.$el).find(":input").attr("disabled", true);
|
||||
this.errorCount = 0;
|
||||
this.submitSuccess = true;
|
||||
this.submitting = false;
|
||||
}, (response) => {
|
||||
}).catch((error) => {
|
||||
// Error
|
||||
let errors = 0;
|
||||
|
||||
for (let errorName in response.body.errors) {
|
||||
for (let errorName in error.response.data.errors) {
|
||||
if ($(this.$el).find(`[name='${errorName}']`).length) {
|
||||
$(this.$el).find(`[name='${errorName}']`).addClass("error");
|
||||
errors++;
|
||||
|
|
|
@ -31,17 +31,17 @@
|
|||
this.notifyStatus = "";
|
||||
$(this.$el).find(":input.error").removeClass("error");
|
||||
|
||||
this.$http.post("/api/subscription-submit" + env.apiToken, JSON.stringify(this.form)).then((response) => {
|
||||
this.$http.post("/api/subscription-submit" + env.apiToken, this.form).then((response) => {
|
||||
// Success
|
||||
$(this.$el).find(":input").fadeOut(150);
|
||||
this.notifyText = "Thanks for subscribing!";
|
||||
this.notifyStatus = "success";
|
||||
this.submitting = false;
|
||||
}, (response) => {
|
||||
}).catch((error) => {
|
||||
// Error
|
||||
let errors = 0;
|
||||
|
||||
for (let errorName in response.body.errors) {
|
||||
for (let errorName in error.response.data.errors) {
|
||||
if ($(this.$el).find(`[name='${errorName}']`).length) {
|
||||
$(this.$el).find(`[name='${errorName}']`).addClass("error");
|
||||
errors++;
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
// Import features from Vue
|
||||
import { createApp, nextTick } from "vue";
|
||||
|
||||
// Initialize Vue
|
||||
const Vue = require("vue/dist/vue.js");
|
||||
const Vue = createApp({});
|
||||
|
||||
// Import and configure axios
|
||||
window.axios = require("axios");
|
||||
|
||||
window.axios.defaults.headers.common = {
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
"X-CSRF-TOKEN": env.csrfToken
|
||||
};
|
||||
|
||||
Vue.config.globalProperties.$http = window.axios;
|
||||
|
||||
// Import plugins
|
||||
import VueRouter from "vue-router";
|
||||
import VueResource from "vue-resource";
|
||||
import Vuex from "vuex";
|
||||
import { sync } from "vuex-router-sync";
|
||||
|
||||
// Load plugins
|
||||
Vue.use(VueRouter);
|
||||
Vue.use(VueResource);
|
||||
Vue.use(Vuex);
|
||||
|
||||
// CSRF prevention header
|
||||
Vue.http.headers.common["X-CSRF-TOKEN"] = env.csrfToken;
|
||||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import { createStore } from "vuex";
|
||||
|
||||
// Import local javascript
|
||||
import SupportsWebP from "imports/supports-webp.js";
|
||||
|
@ -41,8 +44,8 @@ import ContactPage from "pages/contact.vue";
|
|||
import Error404Page from "pages/error404.vue";
|
||||
|
||||
// Create a router instance
|
||||
const router = new VueRouter({
|
||||
mode: "history",
|
||||
const router = new createRouter({
|
||||
history: createWebHistory(),
|
||||
linkActiveClass: "active",
|
||||
|
||||
routes: [
|
||||
|
@ -64,7 +67,7 @@ const router = new VueRouter({
|
|||
});
|
||||
|
||||
// Create a vuex store instance
|
||||
const store = new Vuex.Store({
|
||||
const store = createStore({
|
||||
state: {
|
||||
appName: env.appName,
|
||||
appLang: env.appLang,
|
||||
|
@ -127,9 +130,6 @@ const store = new Vuex.Store({
|
|||
// Detect webp support
|
||||
SupportsWebP.detect(store);
|
||||
|
||||
// Sync vue-router-sync with vuex store
|
||||
sync(store, router);
|
||||
|
||||
// Functionality to run before page load and change
|
||||
router.beforeEach((to, from, next) => {
|
||||
if (to.path !== store.getters.getLastPath) {
|
||||
|
@ -159,14 +159,11 @@ router.afterEach((to, from) => {
|
|||
// Set Page.firstLoad to false so we know the initial load has completed
|
||||
store.commit("setFirstLoad", false);
|
||||
} else {
|
||||
Vue.nextTick(() => {
|
||||
nextTick(() => {
|
||||
TweenMax.to("#router-view", 0.25, { opacity: 1 });
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const App = new Vue({
|
||||
router,
|
||||
store
|
||||
}).$mount("#vue-container");
|
||||
Vue.use(router).use(store).mount("#vue-container");
|
||||
|
|
|
@ -25,7 +25,9 @@ const isProduction = minimist(process.argv.slice(2)).production !== undefined;
|
|||
// Include browsersync when gulp has not been run with --production
|
||||
let browserSync = undefined;
|
||||
|
||||
if (!isProduction) {
|
||||
if (isProduction) {
|
||||
process.env.NODE_ENV = "production";
|
||||
} else {
|
||||
browserSync = require("browser-sync").create();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,20 +5,20 @@
|
|||
"dev": "gulp default watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"browser-sync": "2.27.9"
|
||||
"browser-sync": "2.27.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "7.17.8",
|
||||
"@babel/preset-env": "7.16.11",
|
||||
"@babel/core": "7.18.5",
|
||||
"@babel/preset-env": "7.18.2",
|
||||
"@fortawesome/fontawesome-free": "5.15.4",
|
||||
"@mr-hope/gulp-sass": "2.0.0",
|
||||
"autonumeric": "4.6.0",
|
||||
"autoprefixer": "10.4.4",
|
||||
"autoprefixer": "10.4.5",
|
||||
"bootstrap": "5.1.3",
|
||||
"easymde": "2.16.1",
|
||||
"fancy-log": "2.0.0",
|
||||
"flatpickr": "4.6.11",
|
||||
"gsap": "3.9.1",
|
||||
"flatpickr": "4.6.13",
|
||||
"gsap": "3.10.4",
|
||||
"gulp": "4.0.2",
|
||||
"gulp-babel": "8.0.0",
|
||||
"gulp-clean-css": "4.3.0",
|
||||
|
@ -32,10 +32,10 @@
|
|||
"list.js": "2.3.1",
|
||||
"minimist": "1.2.6",
|
||||
"popper.js": "1.16.1",
|
||||
"postcss": "8.4.12",
|
||||
"postcss": "8.4.14",
|
||||
"sass": "1.32.12",
|
||||
"sortablejs": "1.15.0",
|
||||
"spinkit": "2.0.1",
|
||||
"what-input": "5.2.10"
|
||||
"what-input": "5.2.12"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue