question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

New modules API (final)

See original GitHub issue

New, 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.

  1. 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 😉
  2. Much simplier API based on single function
  3. Ability to hook into various points of application lifecycle
  4. 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
  1. 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.
  2. Current Vuex extending API is rough and not intuitive so it needed to be rewritten anyway
  3. Ability to codesplit VS modules config and pass config to module
  4. 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:closed
  • Created 4 years ago
  • Reactions:2
  • Comments:36 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
pkarwcommented, Jun 29, 2019

So assuming that we have extension point in theme

<div ext-payment-method />

you can extend it from the inside of module (or anywhere else) just by writing

Vue.extend('[ext-payment-method], Component)

This is cool idea @filrak as a VSF user I want to have this feature! 😃

1reaction
filrakcommented, Jul 16, 2019

I’m closing the issue. New API is now merged into develop

Read more comments on GitHub >

github_iconTop Results From Across the Web

Introduction: How to Design a Module API - Apache NetBeans
Each new version of NetBeans should make sure that it allows existing modules to execute and work in reasonable way, or, failing that,...
Read more >
Using the Modules API - App Engine - Google Cloud
The Modules API provides functions that return information about the current operating environment (module, version, and instance). The Modules API also has ...
Read more >
Modules (Guice 4.2 API) - Google
public final class Modules extends java.lang.Object. Static utility methods for creating and working ... Returns a new module that installs all of modules...
Read more >
Get Modules API | Online Help - Zoho CRM
Learn more about how to retrieve module details via API. ... Represents the date and time of when the module properties were last...
Read more >
ECMAScript 6 modules: the final syntax - 2ality
The ES6 module standard has two parts: Declarative syntax (for importing and exporting); Programmatic loader API: to configure how modules are ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found