Adding Vuex-ORM to Laravel Nova tool - laravel

Can someone help me out with adding vuex-orm to a Laravel Nova Tool.
The base of a Laravel Nova tool has tool.js with the following content ('planning-tool' in name, and path may vary according to the name of your tool):
Nova.booting((Vue, router, store) => {
router.addRoutes([
{
name: 'planning-tool',
path: '/planning-tool',
component: require('./components/Tool'),
},
])
})
As you can see Laravel Nova already has a store present.
According to the Vuex-ORM docs (https://vuex-orm.org/guide/prologue/getting-started.html#register-models-to-vuex), I should get it started using:
import Vue from 'vue'
import Vuex from 'vuex'
import VuexORM from '#vuex-orm/core'
import User from '#/models/User'
Vue.use(Vuex)
// Create a new instance of Database.
const database = new VuexORM.Database()
// Register Models to Database.
database.register(User)
// Create Vuex Store and register database through Vuex ORM.
const store = new Vuex.Store({
plugins: [VuexORM.install(database)]
})
export default store
Since Laravel Nova already has a Vuex store I was trying to mix it up. But as soon as I add an import related to #vuex-orm/core I get the following error:
ERROR in ./node_modules/#vuex-orm/core/dist/vuex-orm.esm.js
Module parse failed: Unexpected token (1105:21)
You may need an appropriate loader to handle this file type.
| }
| if (typeof target === 'object' && target !== {}) {
| const cp = { ...target };
| Object.keys(cp).forEach((k) => (cp[k] = cloneDeep(cp[k])));
| return cp;
# ./resources/js/tool.js 1:0-37
# multi ./resources/js/tool.js ./resources/sass/tool.scss
My code (just so far) is:
import VuexORM from '#vuex-orm/core'
Nova.booting((Vue, router, store) => {
router.addRoutes([
{
name: 'planning-tool',
path: '/planning-tool',
component: require('./components/NewTool'),
},
])
// Create a new instance of Database.
const database = new VuexORM.Database()
// TODO ...
})
Does anybody have a suggestion? I know I can use normal Vuex store but vuex-orm adds so many nice features (which I'm used to) that I would take me a lot of time to work with normal objects as models by looping through them and loading additional relationships.
FURTHER AHEAD
To get ahead of myself, how should I register the vuex-orm database plugin since all I can find is creating a Vuex store with the (VuexORM) plugin directly passed along. I've read that a plugin is just function with the store as the only argument, so would something like this work? I've read that it does not always work when you use it like this.
const plugin = VuexORM.install(database)
plugin(store)
Any suggestions of what to try is welcome, I've been at it for quite a while now...

The problem was with webpack and/or Laravel mix 1. We solved it by adding babel dependencies and upgrading Laravel mix tot ^6.0.19.
Our package.json is:
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
"devDependencies": {
"#babel/core": "^7.14.3",
"#babel/plugin-transform-runtime": "^7.14.3",
"#babel/preset-env": "^7.14.4",
"#vuex-orm/core": "^0.36.4",
"babel-loader": "^8.2.2",
"cross-env": "^5.0.0",
"laravel-mix": "^6.0.19",
"vue": "^2.6.14",
"vue-loader": "^15.9.7",
"vuex": "^3.6.2"
},
"dependencies": {
"#babel/runtime": "^7.14.0"
}
}
Our .babelrc is:
{
"presets": [
[
"#babel/preset-env",
{
"useBuiltIns": false
}
]
],
"plugins": [
"#babel/transform-runtime"
]
}
Our tool.js is:
import VuexORM from '#vuex-orm/core'
import ExampleModel from './models/ExampleModel'
import Tool from './components/Tool'
Nova.booting((Vue, router, store) => {
router.addRoutes([
{
name: 'planning-tool',
path: '/planning-tool',
component: Tool,
},
])
// Create a new instance of Database.
const database = new VuexORM.Database()
database.register(ExampleModel)
const plugin = VuexORM.install(database)
plugin(store)
})
I hope this helps someone in the future.

Related

React Native Web implement SSR

https://necolas.github.io/react-native-web/docs/rendering/
After reading the SSR example from the document, I still don't know how to implement SSR
And I don't want to apply SSR with other framework like NextJS
Can anyone show me an example or give me some advice
I'm posting this, not as a direct answer to the original question, because it's targeted directly SSR with NextJS, and the OP needed SSR independently from frameworks like NextJS. However, understanding it with NextJS can get anyone closer with things, because they key relies in Webpack config that NextJS also use as SSR in its encapsulation config.
First thing to know is that, once a Package has been written for React Native, it need to be transpiled first to be able to be used in Web, with webpack config.externals.
let modulesToTranspile = [
'react-native',
'react-native-dotenv',
'react-native-linear-gradient',
'react-native-media-query',
'react-native-paper',
'react-native-view-more-text',
// 'react-native-vector-icons',
];
Then you need to alias some react-native packages to react-native-web equivalent to let package use web version of modules like:
config.resolve.alias = {
...(config.resolve.alias || {}),
// Transform all direct `react-native` imports to `react-native-web`
'react-native$': 'react-native-web',
'react-native-linear-gradient': 'react-native-web-linear-gradient',
};
At this point, you almost get the essential. The rest is normal Webpack config for the normal Application. Also, it needs some additional config in native config file too. I will post all configs content.
For NextJS: next.config.js :
const path = require('path');
let modulesToTranspile = [
'react-native',
'react-native-dotenv',
'react-native-linear-gradient',
'react-native-media-query',
'react-native-paper',
'react-native-view-more-text',
// 'react-native-vector-icons',
];
// console.log('modules to transpile', modulesToTranspile);
// import ntm = from 'next-transpile-modules';
// const withTM = ntm(modulesToTranspile);
// logic below for externals has been extracted from 'next-transpile-modules'
// we won't use this modules as they don't allow package without 'main' field...
// https://github.com/martpie/next-transpile-modules/issues/170
const getPackageRootDirectory = m =>
path.resolve(path.join(__dirname, 'node_modules', m));
const modulesPaths = modulesToTranspile.map(getPackageRootDirectory);
const hasInclude = (context, request) => {
return modulesPaths.some(mod => {
// If we the code requires/import an absolute path
if (!request.startsWith('.')) {
try {
const moduleDirectory = getPackageRootDirectory(request);
if (!moduleDirectory) {
return false;
}
return moduleDirectory.includes(mod);
} catch (err) {
return false;
}
}
// Otherwise, for relative imports
return path.resolve(context, request).includes(mod);
});
};
const configuration = {
node: {
global: true,
},
env: {
ENV: process.env.NODE_ENV,
},
// optimizeFonts: false,
// target: 'serverless',
// bs-platform
// pageExtensions: ['jsx', 'js', 'bs.js'],
// options: { buildId, dev, isServer, defaultLoaders, webpack }
webpack: (config, options) => {
// config.experimental.forceSwcTransforms = true;
// console.log('fallback', config.resolve.fallback);
if (!options.isServer) {
// We shim fs for things like the blog slugs component
// where we need fs access in the server-side part
config.resolve.fallback.fs = false;
} else {
// SSR
// provide plugin
config.plugins.push(
new options.webpack.ProvidePlugin({
requestAnimationFrame: path.resolve(__dirname, './polyfills/raf.js'),
}),
);
}
// react-native-web
config.resolve.alias = {
...(config.resolve.alias || {}),
// Transform all direct `react-native` imports to `react-native-web`
'react-native$': 'react-native-web',
'react-native-linear-gradient': 'react-native-web-linear-gradient',
};
config.resolve.extensions = [
'.web.js',
'.web.ts',
'.web.tsx',
...config.resolve.extensions,
];
config.externals = config.externals.map(external => {
if (typeof external !== 'function') {
return external;
}
return async ({ context, request, getResolve }) => {
if (hasInclude(context, request)) {
return;
}
return external({ context, request, getResolve });
};
});
const babelLoaderConfiguration = {
test: /\.jsx?$/,
use: options.defaultLoaders.babel,
include: modulesPaths,
// exclude: /node_modules[/\\](?!react-native-vector-icons)/,
};
babelLoaderConfiguration.use.options = {
...babelLoaderConfiguration.use.options,
cacheDirectory: false,
// For Next JS transpile
presets: ['next/babel'],
plugins: [
['react-native-web', { commonjs: true }],
['#babel/plugin-proposal-class-properties'],
// ['#babel/plugin-proposal-object-rest-spread'],
],
};
config.module.rules.push(babelLoaderConfiguration);
return config;
},
};
// module.exports = withTM(config);
module.exports = configuration;
SSR will fail to build when missing some functions at server side. The most popular with React Native is requestAnimationFrame. I added it add a Webpack Plugin to mimic it. It can be an empty function or Polyfill:
The file 'polyfills/raf.js(I just put it assetImmediate`):
const polys = { requestAnimationFrame: setImmediate };
module.exports = polys.requestAnimationFrame;
The Babel config is necessary for the last part of it, couldn't work directly in next config. babel.config.js :
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [['module:react-native-dotenv'], 'react-native-reanimated/plugin'],
};
And finally, my list of packages in package.json:
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"scripts": {
"android": "react-native run-android",
"android:dev": "adb reverse tcp:8081 tcp:8081 && react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint .",
"web": "webpack serve -d source-map --mode development --config \"./web/webpack.config.js\" --inline --color --hot",
"build:web": "webpack --mode production --config \"./web/webpack.config.js\" --hot",
"next:dev": "next",
"next:build": "next build",
"next:start": "next start",
"next:analyze": "ANALYZE=true next build"
},
"dependencies": {
"#material-ui/core": "^4.12.4",
"#react-native-async-storage/async-storage": "^1.17.3",
"#react-navigation/drawer": "^6.4.1",
"#react-navigation/native": "^6.0.10",
"#react-navigation/stack": "^6.2.1",
"#reduxjs/toolkit": "^1.8.1",
"axios": "^0.21.1",
"local-storage": "^2.0.0",
"lottie-ios": "^3.2.3",
"lottie-react-native": "^5.1.3",
"lottie-web": "^5.9.4",
"moment": "^2.29.1",
"next": "^12.1.6",
"nookies": "^2.5.2",
"numeral": "^2.0.6",
"raf": "^3.4.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-native": "0.68.1",
"react-native-dotenv": "^2.5.5",
"react-native-gesture-handler": "^2.4.2",
"react-native-keyboard-aware-scroll-view": "^0.9.5",
"react-native-linear-gradient": "^2.5.6",
"react-native-media-query": "^1.0.9",
"react-native-paper": "^4.12.1",
"react-native-progress": "^5.0.0",
"react-native-read-more-text": "^1.1.2",
"react-native-reanimated": "^2.8.0",
"react-native-safe-area-context": "^4.2.5",
"react-native-screens": "^3.13.1",
"react-native-share-menu": "^6.0.0",
"react-native-svg": "^12.3.0",
"react-native-svg-transformer": "^1.0.0",
"react-native-vector-icons": "^9.1.0",
"react-native-view-more-text": "^2.1.0",
"react-native-web": "^0.17.7",
"react-native-web-linear-gradient": "^1.1.2",
"react-redux": "^8.0.1"
},
"devDependencies": {
"#babel/plugin-proposal-class-properties": "^7.14.5",
"#next/bundle-analyzer": "^12.2.2",
"#react-native-community/eslint-config": "^2.0.0",
"#swc/cli": "^0.1.57",
"#swc/core": "^1.2.179",
"eslint": "^7.28.0",
"metro-react-native-babel-preset": "^0.66.0",
"url-loader": "^4.1.1",
"webpack": "^5.39.1",
"webpack-cli": "^4.7.2"
},
"jest": {
"preset": "react-native-web"
},
"sideEffects": false
}
NB: only React-Native packages used also in Web has to be transpiled. Some React-Native packages can be used ONLY in Native, so transpiling them for Web will add up unnecessary chunks of heavy codes in the Web, which is not good. React-Native-Web/React-Native is already more heavy for Web than normal packages made directly for Web.
TIPS to keep it cool with NextJS
Avoid writing conditional Platform.OS === 'web' on small components where you plan to use either a React-Native module or a Web module, which can cause all of them to load unnecessary Native-Only package on web codes. If size is not important, then you can ignore it. Add extension .web.js and .native.js at the end and separate the small codes. For example I write separate Functions and Components for : Storage.web.js, Storage.native.js, CustomLink.web.js, CustomLink.native.js, and hooks useCustomNavigation.web.js, useCustomNavigation.native.js, so that I call CustomLink in place of NextJS Link/router and React-Navigation Link/navigation.
I use react-native-media-query package as life saver for advanced media queries for all SSR/CSR Web and Native responsive display. The App can be restructured on big screen like normal Desktop Web, and be shrunk to Mobile View on the go, EXACTLY LIKE Material-UI on NextJS.

How to instantiate a vue 3 application within Laravel without using a parent App.vue?

I am working in a Laravel 8.x application and have had vue 2.6.12 installed for the longest time. I am working on upgrading to use Vue 3 with laravel and am using with Webpack. I have updated my package.json scripts and have the following installed for Vue 3 compatability:
{
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
"devDependencies": {
"bootstrap": "^4.5.2",
"jquery": "^3.4",
"laravel-mix": "^6.0.39",
"laravel-mix-polyfill": "^2.0.0",
"vue-loader": "^16.8.3"
},
"dependencies": {
"#vue/compiler-sfc": "^3.2.24",
"jquery-validation": "^1.17.0",
"jquery.nicescroll": "^3.7.6",
"jquery.scrollto": "^2.1.2",
"mdb-vue-ui-kit": "^1.7.0",
"sass": "^1.21.0",
"sass-loader": "^7.1.0",
"vue": "^3.2.24",
"vue-moment": "^4.1.0",
"vue-router": "^4.0.12",
"vue-template-compiler": "^2.6.14",
}
}
I never had a main App.vue file as this started as a Laravel app and Vue was brought in later. Instead I have created (with vue 2 and vue3 now) the initial vue object in my /resources/js/app.js file. This just keyed off of a <div id="app"> located in my parent blade.php file. But now with Vue 3 I am unsure how to do this without manually adding an App.vue file. Is this needed or is there something else I can do to configure vue 3 instantiation in my Laravel app?
Vue 2 setup (working)
const router = new VueRouter({
mode: 'history',
routes: routes
});
const app = new Vue({
el: '#app',
router
});
Vue 3 instantiation attempt
import Vue, {createApp } from 'vue';
import router from './router/routes.js';
const app = new Vue({});
createApp(app)
.use(router)
.use(require('vue-moment'))
.use(VueToast)
.mount('#app')
Main error I get when running npm run dev
WARNING in ./resources/js/app.js 50:14-17
export 'default' (imported as 'Vue') was not found in 'vue' (possible exports: BaseTransition, Comment, EffectScope, Fragment, KeepAlive, ReactiveEffect, Static, Suspense, Teleport, Text, Transition, TransitionGroup, VueElement, callWithAsyncErrorHandling, callWithErrorHandling, camelize, capitalize, cloneVNode, compatUtils, compile, computed, createApp, createBlock, createCommentVNode, createElementBlock, createElementVNode, createHydrationRenderer, createPropsRestProxy, createRenderer, createSSRApp, createSlots, createStaticVNode, createTextVNode, createVNode, customRef, defineAsyncComponent, defineComponent, defineCustomElement, defineEmits, defineExpose, defineProps, defineSSRCustomElement, devtools, effect, effectScope, getCurrentInstance, getCurrentScope, getTransitionRawChildren, guardReactiveProps, h, handleError, hydrate, initCustomFormatter, initDirectivesForSSR, inject, isMemoSame, isProxy, isReactive, isReadonly, isRef, isRuntimeOnly, isVNode, markRaw, mergeDefaults, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, openBlock, popScopeId, provide, proxyRefs, pushScopeId, queuePostFlushCb, reactive, readonly, ref, registerRuntimeCompiler, render, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, resolveFilter, resolveTransitionHooks, setBlockTracking, setDevtoolsHook, setTransitionHooks, shallowReactive, shallowReadonly, shallowRef, ssrContextKey, ssrUtils, stop, toDisplayString, toHandlerKey, toHandlers, toRaw, toRef, toRefs, transformVNodeArgs, triggerRef, unref, useAttrs, useCssModule, useCssVars, useSSRContext, useSlots, useTransitionState, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, version, warn, watch, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withDirectives, withKeys, withMemo, withModifiers, withScopeId)
You can register global components to the app you are creating.
import {createApp, defineComponent } from 'vue';
import router from './router/routes.js';
import MyComponent from '#/components/MyComponent.vue'
// Root vue component
const root = defineComponent({/* ... */})
//Create the app
const app = createApp(root)
//Configure the app
app.use(router)
.use(require('vue-moment'))
.use(VueToast)
//Attach global components to the app
app.component('my-component', MyComponent)
//Mount the app
app.mount('#app')

Windi CSS HMR not working for Svelte + vite app

I created a Svelte project with Vite and added windicss. I am using Yarn as build tool. I added WindiCSS to vite using https://windicss.org/integrations/vite.html#install. It works fine when I start the project using,
yarn dev
But HMR (Hot Module Reload) for Windi CSS does not work. But when I kill the server and restart it picks up the Windi CSS changes. Even the Devtool changes are working fine, only HMR is not working.
package.json file,
{
"name": "svelte-in",
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview"
},
"devDependencies": {
"#sveltejs/vite-plugin-svelte": "^1.0.0-next.11",
"svelte": "^3.37.0",
"vite": "^2.6.4",
"vite-plugin-windicss": "^1.4.11",
"windicss": "^3.1.9"
}
}
vite.config.js file,
import { defineConfig } from 'vite'
import { svelte } from '#sveltejs/vite-plugin-svelte'
import WindiCSS from 'vite-plugin-windicss'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
svelte(),
WindiCSS()
]
})
And main.js is,
import App from './App.svelte'
import 'virtual:windi.css'
import 'virtual:windi-devtools' // To enable windi in dev tools
const app = new App({
target: document.getElementById('app')
})
export default app
Not sure if I am missing anything else.
I had to put WindiCSS() before svelte() for HMR to work.

How to run a previously built Canvas API project in simulator/smart-display?

I am trying to clone an application, which is given in their document under canvas API section. They have given an option for sample walkthrough [https://developers.google.com/actions/interactivecanvas/sample-walkthrough]. I have followed every step but I am getting an error that my intents are not handled.
You can see the code at [github.com/actions-on-google/dialogflow-snowman-nodejs.git].
I have tried seeing all the intent handlers, Also, i have tried changing all the packages to the lastest one, as i have mentioned in the question.
I am using following packages:
{
"name": "snowman-canvas-sample-functions",
"description": "Snowman Actions on Google Interactive Canvas Sample Functions",
"license": "Apache-2.0",
"private": true,
"engines": {
"node": "8"
},
"dependencies": {
"actions-on-google": "preview",
"firebase-admin": "~5.13.1",
"firebase-functions": "^2.0.2"
},
"scripts": {
"lint": "./node_modules/.bin/eslint --fix \"**/*.js\"",
"start": "firebase serve --only functions",
"deploy": "firebase deploy --only functions",
"test": "npm run lint"
},
"devDependencies": {
"eslint": "^6.0.1",
"eslint-config-google": "^0.13.0"
}
}
i am getting "Dialogflow IntentHandler not found for intent: Welcome at Function" error in the welcome intent itself. Please assist me what should i try next.
You need to make sure your Dialogflow intent name and your Firebase Function intent handler name are the same.
From here, you'd need to implement a handler:
const { dialogflow } = require('actions-on-google')
const app = dialogflow()
app.intent('Welcome', conv => {
conv.ask('Welcome!')
})

SyntaxError: Unexpected token static

I'm currently trying to evaluate different testing frameworks that work with React, and it turns out that Jest is on my list. However, I'm trying to use static properties outlined here: https://github.com/jeffmo/es-class-fields-and-static-properties.
So, I took the tutorial that is given on the Jest homepage, and added a static propTypes property, my code looks like this:
import React from 'react';
class CheckboxWithLabel extends React.Component {
static defaultProps = {}
constructor(props) {
super(props);
this.state = {isChecked: false};
// since auto-binding is disabled for React's class model
// we can prebind methods here
// http://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding
this.onChange = this.onChange.bind(this);
}
onChange() {
this.setState({isChecked: !this.state.isChecked});
}
render() {
return (
<label>
<input
type="checkbox"
checked={this.state.isChecked}
onChange={this.onChange}
/>
{this.state.isChecked ? this.props.labelOn : this.props.labelOff}
</label>
);
}
}
module.exports = CheckboxWithLabel;
When I run the tests (npm test or jest), It throws the following error:
➜ jest
Using Jest CLI v0.8.2, jasmine1
FAIL __tests__/CheckboxWithLabel-test.js
● Runtime Error
SyntaxError: Desktop/jest/examples/react/CheckboxWithLabel.js: Unexpected token (5:22)
My package.json file looks like this:
{
"dependencies": {
"react": "~0.14.0",
"react-dom": "~0.14.0"
},
"devDependencies": {
"babel-jest": "*",
"babel-preset-es2015": "*",
"babel-preset-react": "*",
"jest-cli": "*",
"react-addons-test-utils": "~0.14.0"
},
"scripts": {
"test": "jest"
},
"jest": {
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react",
"<rootDir>/node_modules/react-dom",
"<rootDir>/node_modules/react-addons-test-utils",
"<rootDir>/node_modules/fbjs"
],
"modulePathIgnorePatterns": [
"<rootDir>/node_modules/"
]
}
}
Any ideas on what I'm missing here?
Thanks.
Any ideas on what I'm missing here?
Class properties are neither part of the es2015 nor the react preset.
You have to load the plugins that handles class properties:
npm install babel-plugin-transform-class-properties babel-plugin-syntax-class-properties
And in your .babelrc file (next to existing plugins or presets):
"plugins": [
"syntax-class-properties",
"transform-class-properties"
]
This error occurs since Standard ES2015(ES6) classes can only have methods, not properties.
For me, it was resolved by installing babel-preset-stage-0 which adds support for class properties.
npm install babel-preset-stage-0 --save-dev
Then configure Webpack (or .babelrc) to use this preset:
//...
presets: ['react', 'es2015', 'stage-0']
//...
UPDATE:
As of Mid-2018, Babel env preset supports ES2015, ES2016 and ES2017.
So, you can skip stage-0 preset and instead use the env preset
npm install babel-preset-env --save-dev
And then update your .babelrc to
//...
presets: ['env', 'xyz']
//...
To support latest ES2018 features like spread operator/async functions, you can add stage-3 preset.
Reference tutorial

Resources