New modules API (final)
See original GitHub issueNew, simplified modules API
Broader explaination still needs to be written but in short words this change will enable;
Inspiration is taken from new Vue’s functional API and nuxt modules.
- Less abstraction with direct access to
store
,router
so better learning curve and sticking to native Vue APIs to not limit customization posibilities with our limited wrappers on it. Also less code to maintain 😉 - Much simplier API based on single function
- Ability to hook into various points of application lifecycle
- Separation of module APIs and ones that can be used inside modules from the core package.
@vue-storefront/module
can now be a separate npm package used in VS modules packages as dependency.- Having this will allow us to enable packaging fo VS modules as npm packages that doesn’t require tyepscript.
- We have control over what can be used in modules = no need to worry about changing APIs in core that could break modules
- Ability to register modules lazily which will gain huge performance boost. If module is registered lazily it can’t access some of the hooks like
onAppInit
. - Current Vuex extending API is rough and not intuitive so it needed to be rewritten anyway
- Ability to codesplit VS modules config and pass config to module
- Ability to define extension points in module thanks to config
New API
import { extendStore, isServer } from '@vue-storefront/module/helpers' // helpers that can be sued inside module
import { afterAppInitHook } from '@vue-storefront/module/hooks' // List of events and hooks
import { cartVuexModule } from './store/cart.js' // Vuex module that will extend cart module
import { newVuexModule } from './store/newModule.js'// new Vuex module to be registered
import { newRoutes } from './routes/newRoutes.js'
export default function (app, router, store, config, appConfig) => {
// This is how you extend the router, native Vue API
router.addRoutes(newRoutes)
router.beforeEach((to, from, next) => { next() })
// This is how you extend the Vuex store, native Vue API
store.registerModule('newModule', newVuexModule)
// This is how you extend currently existing Vuex module, much simpler API, just pass Vuex module and it will be merged with module that has same name
extendStore('cart', cartVuexModule)
// This is how you can access Vue Storefront hooks
afterAppInitHook(() => {
console.log('App has just been initialized')
})
}
Inside module’s init function we have acces to:
- app instance (Vue instance)
- router insatnce
- Vuex store instance
- module config passed during registration
- VS config
What else:
- You can call module helper functions outside of modules. This will let you to do simple modifications in your theme without a need to wrap it into VS module. For instance if you want to just extend Vuex module from your theme instead of creating a lot of boilerplate you can simply do this
// theme/index.js
import { extendStore } from '@vue-storefront/module/helpers'
import { newCart } from './cart.js'
extendStore('cart', newCart)
Much more elegant isn’t it?
-Thanks to config you can define extension points in your module, i.e. let people override your hooks
// module
export default function (app, store, router, config, appConfig) {
onAppInit(() => {
if (config.onAppInit) {
config.onAppInit()
} else {
// regular hook
}
})
}
// registration
registerModule(someModule, {
onAppInit: () => { console.log('Hello') }
})
Registration
Whenever you want to register VS module you can do it by using registerModule
function and passing optional config. This will let us to codesplit module configs.
import { registerModule } from '@vue-storefront/module'
import { RecentlyViewedModule } from './modules/recently-viewed'
registerModule(RecentlyViewedModule, {
productsCount: 10
})
What about backward compatibility
Porting old Vue Storefront modules to new ones will be available only through changing index file of any module. There will be also a method to port old module to new one via helper function as simple as
import { legacyModuleWrapper } from '@vue-storefrpnt/module/helpers'
import { registerModule } from '@vue-storefrpnt/module/helpers'
import { legacyModule } from './legacyModule'
registerModule(legacyModuleWrapper(legacyModule))
What will happen with old api
Old way of Vue Storefront modules registration will still be possible and won’t be depreciated until Vue Storefront 2.0. After this there will still be a legacyModuleWrapper
function so old modules still can be used (but they can’t benefit from new features)
In plans
Ability to extend express server and webpack config.
Each module could have a server.js
file in a root that will export webpack config object and express server.
For webpack it will work exactly the same as current extension model from themes.
For server it will work as current extension model in src/server
// module/server.js
exports.webpack = function (config) {
// do modifications
return config
}
exports.server = function (app) {
// do sth with express instance
}
If you’d like to make use of server utilities of a given module you just need to register server side part of the module in VS config.
// config/local.json
"modules": {
"serverSideModules": ['absolute/path', 'package-name']
}
Please note that no matter if client part fo the module is async or not server side part will be registered during app initialization so we have 2 entry points for every module - index.ts
for client (can be loaded lazily) and server.js
for webpack/express
Issue Analytics
- State:
- Created 4 years ago
- Reactions:2
- Comments:36 (5 by maintainers)
Top GitHub Comments
This is cool idea @filrak as a VSF user I want to have this feature! 😃
I’m closing the issue. New API is now merged into develop