Skip to content

Instantly share code, notes, and snippets.

@bayareawebpro
Last active February 5, 2020 00:08
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save bayareawebpro/21905daea09dcfbafbf464ab1f413663 to your computer and use it in GitHub Desktop.

Registering Providers (within application.js)

// Services/VueServiceProvider.js

this.load(require.context('./Services', true, /\.*ServiceProvider.js$/))
    .each((name, abstract) => this.register(abstract))

Binding Middleware

// Binding
this.bind('Middleware', () => {
    return this.load(require.context('./Middleware', true, /\.js$/)).toObjectEntries()
})

// Resolver
/**
 * Get Middleware
 * @param request {Request}
 * @return {Array}
 */
resolveMiddleware(request) {
    return this
        .make('Middleware')
        .filter(([alias, abstract]) => request.hasMiddleware(alias.toLowerCase()))
        .map(([alias, abstract]) => abstract)
}

Binding Components: (each file exports a Component)

// Components/UserForm.vue => v-user-form

this.app
    .load(require.context('./../../Components', true, /\.vue$/))
    .components(Vue.component.bind(Vue))

Binding Modules: (each file exports a Repository / Service)

// Modules/Admin/AdminStore.js => Admin
// Modules/Account/AccountStore.js => Account

this.app
    .load(require.context('../../Modules', true, /Store\.js$/))
    .each((binding, abstract)=>{
        this.app.bind(binding.replace('Store', ''), abstract)
    })

Binding Routes: (each file exports an array)

// Pages/Admin/Routes.js
// Pages/Account/Routes.js

const routes = this.app
    .load(require.context('./../../Pages', true, /Routes\.js$/))
    .toArray()
    .reduce((prev, current) => prev.concat(current))
    .sort((a, b) => a.path.localeCompare(b.path))

App Class Method

/**
 * AutoLoader Helper
 * @param context
 * @return {AutoLoader}
 */
load(context) {
    return AutoLoader.make(context)
}

Autoloader Class

/**
 * @docs https://webpack.js.org/guides/dependency-management/#require-context
 */
export default class AutoLoader{

    static make(context){
        return new AutoLoader(context)
    }

    constructor(context) {
        this.context = context
    }

    toObject(){
        const schema = {}
        this.context.keys().map((path) => {
            const abstract = this.context(path)
            const binding = this.toBaseName(path)
            schema[binding] = abstract.default || abstract
        })
        return schema
    }

    toObjectEntries(){
        return Object.entries(this.toObject())
    }

    toArray(){
        return this.context.keys().map((path) => {
            const abstract = this.context(path)
            return abstract.default || abstract
        })
    }

    each(callback){
        return this.context.keys().forEach((path) => {
            const abstract = this.context(path)
            const binding = this.toBaseName(path)
            callback(binding, abstract.default || abstract)
        })
    }

    components(callback){
        this.context.keys().forEach((path) => {
            const abstract = this.context(path)
            const tagName = this.toComponentName(path)
            callback(tagName, abstract.default || abstract)
        })
    }

    toBaseName(path){
        return path
            .replace(/^\.\//, '')
            .replace(/\.\w+$/, '')
            .split(/\//)
            .reduce((prev, current)=>current)
    }

    toComponentName(path){
        return 'v' + this.toBaseName(path)
            .replace(/([A-Z][a-z])/g,'-$1')
            .toLowerCase()
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment