UNPKG

vue-autowire

Version:
192 lines (171 loc) 7.95 kB
'use strict'; import { getAssetName } from './utils'; /** * Load router files * @param {Vue} Vue VueJS instance * @param {Object} requireContext Webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api */ function registerRoutes (Vue, requireContext) { // Ask webpack to list the files // By default require.context adds all files to the main bundle unless "lazy" mode is used const routeFiles = requireContext.keys(); // Return them all loaded, so users can pass them onto their VueRouter declaration return routeFiles.map(routeFile => { const routerConfig = requireContext(routeFile); return routerConfig.default ? routerConfig.default : routerConfig; }); } /** * Load filter files * @param {Vue} Vue VueJS instance * @param {Object} requireContext Webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api */ function registerFilters (Vue, requireContext) { // Ask webpack to list the files // By default require.context adds all files to the main bundle unless "lazy" mode is used const filterFiles = requireContext.keys(); return filterFiles.map(file => { const name = getAssetName(file); let filter = requireContext(file); // Unwrap "default" from ES6 module if (filter.hasOwnProperty('default')) filter = filter.default; Vue.filter(name, filter); // Return the registered filter return { name, filter: Vue.filter(name) }; }); } /** * Load directive files * @param {Vue} Vue VueJS instance * @param {Object} requireContext Webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api */ function registerDirectives (Vue, requireContext) { // Ask webpack to list the files // By default require.context adds all files to the main bundle unless "lazy" mode is used const directiveFiles = requireContext.keys(); return directiveFiles.map(file => { const name = getAssetName(file); let directive = requireContext(file); // Unwrap "default" from ES6 module if (directive.hasOwnProperty('default')) directive = directive.default; Vue.directive(name, directive); // Return the registered directive return { name, directive: Vue.directive(name) }; }); }; /** * Register components files using Vue.component and requiring the file from webpack's context * @param {Vue} Vue VueJS instance * @param {Object} requireContext Webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api */ function registerComponents (Vue, requireContext) { // Ask webpack to list the files. // By default require.context adds all files to the main bundle unless "lazy" mode is used const componentFiles = requireContext.keys(); // Register all of them in Vue return componentFiles.map(file => { const name = getAssetName(file); let component = requireContext(file); // Unwrap "default" from ES6 module if (component.hasOwnProperty('default')) component = component.default; Vue.component(name, component); // Return the registered component return { name, component: Vue.component(name) }; }); } /** * Register components files using Vue.component as async components by setting up a factory function * that loads the module using webpack's lazy mode * Each of these components will be on its own chunk * @param {Vue} Vue VueJS instance * @param {Object} requireContext Webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api */ function registerAsyncComponents (Vue, requireContext) { // Make sure require.context was created with lazy mode if (typeof requireContext.id === 'string' && !requireContext.id.includes('lazy')) { throw new Error('require.context for async components should be created in lazy mode. See https://github.com/webpack/docs/wiki/context#context-module-api'); } // Ask webpack to list the files. In lazy mode, these are added to their own chunk const componentFiles = requireContext.keys(); // Register all of them in Vue as async components. See https://vuejs.org/v2/guide/components-dynamic-async.html#Async-Components return componentFiles.map(file => { const name = getAssetName(file); Vue.component(name, () => requireContext(file)); // Return the registered component return { name, component: Vue.component(name) }; }); } /** * Main function, registers in Vue each of the different asset types based on the conventions provided. * @param {Object} Vue The Vue API * @param {Object} conventions Conventions defining which files to register for each asset type */ function autowire (Vue, conventions) { // Merge with empty conventions // The reason why we dont load here the default conventions is that webpack would then follow the chain of require/imports that lead // to our conventions and they would ALWAYS be added to the bundles, even when users do not use them conventions = Object.assign({ routes: { requireContext: null }, filters: { requireContext: null }, directives: { requireContext: null }, components: { requireContext: null, requireAsyncContext: null }, views: { requireContext: null, requireAsyncContext: null } }, conventions); const assetResults = { components: conventions.components.requireContext ? registerComponents(Vue, conventions.components.requireContext) : [], asyncComponents: conventions.components.requireAsyncContext ? registerAsyncComponents(Vue, conventions.components.requireAsyncContext) : [], views: conventions.views.requireContext ? registerComponents(Vue, conventions.views.requireContext) : [], asyncViews: conventions.views.requireAsyncContext ? registerAsyncComponents(Vue, conventions.views.requireAsyncContext) : [], routes: conventions.routes.requireContext ? registerRoutes(Vue, conventions.routes.requireContext) : [], filters: conventions.filters.requireContext ? registerFilters(Vue, conventions.filters.requireContext) : [], directives: conventions.directives.requireContext ? registerDirectives(Vue, conventions.directives.requireContext) : [] }; // Wire every asset type for which there is a require.context provided const aw = { components: assetResults.components, asyncComponents: assetResults.asyncComponents, views: assetResults.views, asyncViews: assetResults.asyncViews, routes: assetResults.routes, filters: assetResults.filters, directives: assetResults.directives, registerComponents: function (requireContext) { this.components = this.components.concat(registerComponents(Vue, requireContext)); }, registerAsyncComponents: function (requireContext) { this.asyncComponents = this.asyncComponents.concat(registerAsyncComponents(Vue, requireContext)); }, registerViews: function (requireContext) { this.views = this.views.concat(registerComponents(Vue, requireContext)); }, registerAsyncViews: function (requireContext) { this.asyncViews = this.asyncViews.concat(registerAsyncComponents(Vue, requireContext)); }, registerRoutes: function (requireContext) { this.routes = this.routes.concat(registerRoutes(Vue, requireContext)); }, registerFilters: function (requireContext) { this.filters = this.filters.concat(registerFilters(Vue, requireContext)); }, registerDirectives: function (requireContext) { this.directives = this.directives.concat(registerDirectives(Vue, requireContext)); }, }; // export the results into the Vue instance, so they can be inspected Vue.autowire = aw; } export default autowire;