The fact is that when node.js came along, JavaScript replaced Java and C#, but this led to things like classes in ES6, dependency injection in Angular.js, decorators in Ember, CSS-in-JS, ecosystem lock-in, engine-lock-in, etc, etc.
frameworks:
- name: "Hyperapp"
year: 2017
url: "https://hyperapp.dev"
description: "A minimalist framework focused on simplicity and functional programming, usable directly in the browser."
- name: "HTM"
year: 2018
url: "https://github.com/developit/htm"
description: "A lightweight library for JSX-like syntax without compilation, compatible with frameworks like Preact."
- name: "Lit"
year: 2018
url: "https://lit.dev"
description: "A library for building web components using native browser APIs, without requiring a build process."
- name: "Alpine.js"
year: 2019
url: "https://alpinejs.dev"
description: "A lightweight framework for declarative, reactive UI, easily usable without Node.js or compilation."
- name: "Petite-Vue"
year: 2021
url: "https://github.com/vuejs/petite-vue"
description: "A minimalist subset of Vue.js, focused on progressive enhancement and browser-native use."
vue_lifecycle_methods:
vue2:
beforeCreate:
description: "Called synchronously after the instance has been initialized, before data observation and event/watcher setup."
created:
description: "Called synchronously after the instance is created. At this point, the instance has finished processing options, which means the following have been set up: data observation, computed properties, methods, and watchers, though it has not yet been mounted to the DOM."
beforeMount:
description: "Called right before the mounting begins: the render function is about to be called for the first time."
mounted:
description: "Called after the instance has been mounted, where el is replaced by the newly created vm.$el. If the root instance is mounted to an in-document element, vm.$el will also be in-document when mounted is called."
beforeUpdate:
description: "Called when data changes, before the DOM is patched."
updated:
description: "Called after a data change causes the DOM to be re-rendered and patched."
activated:
description: "Called when a kept-alive component is activated."
deactivated:
description: "Called when a kept-alive component is deactivated."
beforeDestroy:
description: "Called right before a Vue instance is destroyed."
destroyed:
description: "Called after a Vue instance has been destroyed."
vue3:
beforeCreate:
description: "Called right after the instance has been initialized, before data observation and event/watcher setup."
created:
description: "Called after the instance is created. At this point, the instance has finished processing options, which means the following have been set up: reactive data, computed properties, methods, and watchers, though it has not yet been mounted."
beforeMount:
description: "Called right before the mounting begins: the render function is about to be called for the first time."
mounted:
description: "Called after the instance has been mounted. At this point, the el property is replaced by the newly created vm.$el. If the root instance is mounted on an in-document element, vm.$el will also be in-document."
beforeUpdate:
description: "Called when data changes, before the virtual DOM is patched."
updated:
description: "Called after a data change causes the virtual DOM to be re-rendered and patched."
beforeUnmount:
description: "Called right before a component instance is unmounted."
unmounted:
description: "Called after a component instance is unmounted."
activated:
description: "Called when a kept-alive component is activated."
deactivated:
description: "Called when a kept-alive component is deactivated."
errorCaptured:
description: "Called when an error from a descendant component is captured."
Vuex to Pinia
lifecycle_methods:
store_initialization:
vuex: 'store'
pinia: 'createPinia'
state_definition:
vuex: 'state'
pinia: 'state'
getters:
vuex: 'getters'
pinia: 'getters'
actions:
vuex: 'actions'
pinia: 'actions'
mutations:
vuex: 'mutations'
pinia: 'no direct equivalent (use actions or composition API)'
modules:
vuex: 'modules'
pinia: 'no direct equivalent (use multiple stores)'
plugins:
vuex: 'plugins'
pinia: 'plugins'
state_access:
vuex: 'this.$store.state'
pinia: 'useStore().$state'
commit:
vuex: 'this.$store.commit'
pinia: 'useStore().$patch'
dispatch:
vuex: 'this.$store.dispatch'
pinia: 'useStore().$patch or direct action call'
strict_mode:
vuex: 'strict'
pinia: 'no direct equivalent (use devtools or custom logic)'
hot_module_replacement:
vuex: 'store.hotUpdate'
pinia: 'not needed (store is reactive by default)'
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue 3 with Pinia and Axios</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/pinia@2/dist/pinia.iife.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<dropdown-component></dropdown-component>
</div>
<script>
const { createApp, ref, onMounted, defineComponent } = Vue;
const { createPinia, defineStore } = Pinia;
// Define the Pinia store
const useStore = defineStore('main', {
state: () => ({
options: [],
selectedOption: null
}),
actions: {
fetchOptions() {
const script = document.createElement('script');
const callbackName = 'foo';
// Define the callback function
window[callbackName] = (response) => {
this.options = response.query.search.map(item => item.title);
};
// Set the JSONP URL
const url = `https://en.wikipedia.org/w/api.php?action=query&format=json&list=search&srsearch=vue&origin=*&callback=${callbackName}`;
// Set the script element's src to the JSONP URL
script.src = url;
// Append the script to the document
document.body.appendChild(script);
// Clean up the script and callback after execution
script.onload = () => {
document.body.removeChild(script);
delete window[callbackName];
};
script.onerror = (error) => {
console.error('Error fetching options:', error);
document.body.removeChild(script);
delete window[callbackName];
};
}
}
});
// Define the Vue component
const DropdownComponent = defineComponent({
template: `
<div>
<label for="wiki-select">Choose an article:</label>
<select id="wiki-select" v-model="selectedOption" ref="selectDropdown">
<option v-for="option in options" :key="option" :value="option">{{ option }}</option>
</select>
<p>Selected option: {{ selectedOption }}</p>
</div>
`,
setup() {
const store = useStore();
const selectDropdown = ref(null);
// Define the foo method
const foo = (selectedOption) => {
console.log('Selected option changed:', selectedOption);
};
onMounted(() => {
store.fetchOptions();
selectDropdown.value.addEventListener('change', (event) => {
foo(event.target.value);
});
});
return {
options: store.options,
selectedOption: store.$state.selectedOption,
selectDropdown
};
}
});
// Create the Vue app and Pinia store
const app = createApp({
components: {
DropdownComponent
}
});
const pinia = createPinia();
app.use(pinia);
app.mount('#app');
</script>
</body>
</html>
Nuxt
/*
Scope:
publicRuntimeConfig: These configuration values are accessible on both the server and the client. This means any value defined here can be accessed and used in your client-side code.
privateRuntimeConfig: These configuration values are only accessible on the server side. They are not exposed to the client, making them suitable for sensitive data that should not be exposed to the client.
Security:
publicRuntimeConfig: Since values here are available on the client side, they should not contain sensitive information such as API keys or secrets.
privateRuntimeConfig: Safe to store sensitive information as these values are only accessible on the server.
Access:
publicRuntimeConfig: You can access these values using this.$config in your Vue components and context.$config in the Nuxt context.
privateRuntimeConfig: These values are accessible in server-side code, such as server middleware, API routes, and server-side Vue components.
*/
import axios from 'axios';
export default async () => {
const { data } = await axios.get('https://api.example.com/config');
return {
publicRuntimeConfig: {
apiBase: process.env.API_BASE || data.apiBase,
},
privateRuntimeConfig: {
apiSecret: process.env.API_SECRET || data.apiSecret,
},
};
};
documentation:
- name: "GitHub Issue - Extract window.__NUXT__ to <script>"
description: "Discusses how to extract `window.__NUXT__` to a `<script>` tag for SEO purposes."
url: "https://github.com/nuxt/nuxt/issues/8548"
- name: "GitHub Issue - Remove window.__NUXT__ once app initialises"
description: "Discusses the use of `window.__NUXT__` for backward compatibility and its removal in future versions."
url: "https://github.com/nuxt/nuxt/issues/25336"
- name: "Nuxt Documentation - The Context"
description: "Explains the context object, which includes `window.__NUXT__`."
url: "https://v2.nuxt.com/docs/internals-glossary/context/"
function getQueryParam(key) {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get(key);
}
jQuery Usage
$(document).ready(function() {
// Store the function object
$(document).data('getQueryParam', getQueryParam);
// Retrieve and use the function
const getQueryParam = $(document).data('getQueryParam');
const value = getQueryParam('foo');
// Assert the query parameter
if (value === 'bar') {
console.log("The query parameter 'foo' has the value 'bar'");
} else {
console.log("The query parameter 'foo' does not have the value 'bar'");
}
});
JQuery QUnit Test
QUnit.test("Query string contains key 'foo' with value 'bar'", function(assert) {
const getQueryParam = $(document).data('getQueryParam');
const value = getQueryParam('foo');
assert.equal(value, 'bar', "The query parameter 'foo' should have the value 'bar'"); });
articles:
- title: "Why we migrated from WordPress to NodeJS"
url: "https://polyfable.com/articles/wordpress-to-nodejs/"
summary: >
This blog post details the decision to migrate from WordPress to Node.js, emphasizing performance improvements,
scalability concerns, and the difficulties of maintaining a plugin-heavy WordPress site. The authors describe their
transition to a more modern JavaScript-based stack that allows for greater flexibility and speed in their web application.
- title: "Moving from WordPress to Node.js for scalability"
url: "https://dev.to/someauthor/migrating-from-wordpress-to-nodejs-for-performance-3abc"
summary: >
The article explores the technical reasons behind switching from WordPress to Node.js, particularly focusing on
how Node.js provided better concurrency, API management, and optimized handling of large-scale traffic. The author
shares insights into rewriting a WordPress application into a JavaScript-based solution for improved efficiency.
Dynamic Vue3 Component in Nuxt2
Step
Details
1. Install Vue 3
Run npm install vue@next to install Vue 3 separately without interfering with Nuxt 2.
2. Create Vue 3 Component
Define a standalone Vue 3 component using createApp() and h(). Example:
maturity_models:
- organization: "NIST"
maturity_model: "Cybersecurity Framework Maturity Model"
topic: "Security"
url: "https://www.nist.gov/cyberframework"
summary: "Provides a cybersecurity framework to help organizations assess and mature their security controls and risk management practices."
- organization: "TMMi Foundation"
maturity_model: "Test Maturity Model integration (TMMi)"
topic: "Testability"
url: "https://www.tmmi.org/"
summary: "Offers a structured model to evaluate and improve the maturity of software testing processes within organizations."
- organization: "CMMI Institute"
maturity_model: "Capability Maturity Model Integration (CMMI)"
topic: "Compliance, Testability, Process Improvement"
url: "https://cmmiinstitute.com/"
summary: "Provides comprehensive models for process improvement that address areas such as compliance, quality assurance, and test maturity within software and process development."
- organization: "DAMA International"
maturity_model: "Data Management Maturity (DMM) Model"
topic: "Data Governance"
url: "https://www.dama.org/"
summary: "Delivers guidelines and maturity models to help organizations assess and advance their data governance practices, ensuring data quality and effective management."
- organization: "EDM Council"
maturity_model: "Data Management Capability Assessment Model (DCAM)"
topic: "Data Governance, Compliance"
url: "https://edmcouncil.org/"
summary: "Focuses on best practices for data management by providing a capability model that assists organizations in evaluating and enhancing their data governance and compliance frameworks."
- organization: "The Open Group"
maturity_model: "TOGAF Maturity Model"
topic: "Interoperability, Portability"
url: "https://www.opengroup.org/"
summary: "Through frameworks like TOGAF, The Open Group offers maturity models that guide organizations in improving enterprise architecture, with a focus on achieving better interoperability and portability among systems."
- organization: "W3C"
- maturity_model: "Accessibility Maturity Model"
- topic: "Accessibility"
- url: "https://www.w3.org/TR/maturity-model/"
- summary: "Digital accessibility is a human right"
Nuxt Bridge: Installing Composition API
installation:
remove_legacy:
command: "npm uninstall @vue/composition-api @nuxtjs/composition-api"
description: "Removes outdated Composition API dependencies that were used in Nuxt 2."
enable_composition_api:
file: "nuxt.config.js"
settings:
bridge:
capi: true # Enables Composition API in Nuxt Bridge
nitro: false # Set to true if transitioning to Nuxt 3's Nitro engine
description: "Activates Composition API inside Nuxt Bridge configuration."
remove_manual_plugin:
file: "plugins/composition-api.js"
remove_code: |
import Vue from 'vue';
import VueCompositionAPI from '@vue/composition-api';
Vue.use(VueCompositionAPI);
description: "Nuxt Bridge automatically imports Composition API, so manual plugin registration is unnecessary."
update_imports:
before: |
import { ref, computed, useRoute } from '@nuxtjs/composition-api';
after: |
import { ref, computed } from 'vue';
import { useRoute } from '#imports';
description: "Replaces outdated imports with Nuxt Bridge-compatible ones."
removed_composables:
list:
- name: "withContext"
alternative: "No replacement"
- name: "useStatic"
alternative: "No replacement (consider fetching data dynamically)"
- name: "reqRef / reqSsrRef"
alternative: "Use 'ssrRef' instead"
description: "Some Composition API functions from Nuxt 2 are unavailable in Nuxt Bridge."