404
How did we get here?Take me home.
diff --git a/.eslintignore b/.eslintignore index 1521c8b..f9085fe 100755 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,2 @@ dist +docs \ No newline at end of file diff --git a/README.md b/README.md index de3ae8f..e0cdd3d 100644 --- a/README.md +++ b/README.md @@ -3,25 +3,35 @@ Vue plugin with conventions for automatically wiring components, pages and routes. -- Docs will be available at https://kaizendorks.github.io/vue-autowire/. - -Use it by cloning the repo and building with `npm run build`. - ``` import Vue from 'vue' import App from './App.vue' -import VueAutowire from './autowire'; +import VueAutowire from 'vue-autowire'; Vue.config.productionTip = false +// Use default settings +Vue.use(VueAutowire); + +// Enable only certain options Vue.use(VueAutowire, { - // All .js and .vue files except the ones ending with .async.vue - context: require.context('./', true, /\/(?:[^.]+|(?!\.async\.vue$))(\.js|\.vue)$/), - // All the .async.vue files as async components on their own vue file - asyncContext: require.context('./', true, /async\.vue$/, 'lazy') -}) + routes: { enabled: false }, +}); + +// Provide your own webpack context with your own convention for folder/file names +Vue.use(VueAutowire, { + components: { + // all components in the /src/components folder that end with .vue, excluding the .async.vue ones + context: require.context('@/components', true, /\/(?:[^.]+|(?!\.async\.vue$))\.vue$/), + // all components in the /src/components folder that end with async.vue + // Not the last argument to use webpack's lazy mode so they get their own chunk + context: require.context('@/components', true, /async\.vue$/, 'lazy'), + }, +}); new Vue({ render: h => h(App), }).$mount('#app') ``` + +For more information, check the docs at https://kaizendorks.github.io/vue-autowire/! diff --git a/dist/vue-autowire.common.js b/dist/vue-autowire.common.js index c316e04..cf9aeda 100644 --- a/dist/vue-autowire.common.js +++ b/dist/vue-autowire.common.js @@ -8,45 +8,65 @@ var _defaults = { routes: { enabled: true, - pattern: /\.router.js$/ + requireContext: null }, components: { enabled: true, - pattern: /\/components\/.*\.vue$/ + requireContext: null, + requireAsyncContext: null } }; /** * Load router files * @param {Vue} Vue VueJS instance - * @param {Object} options + * @param {Object} routesOptions */ -function registerRoutes (Vue, options) { - var routeFiles = options.requireContext - .keys() - .filter(function (file) { return file.match(options.routes.pattern); }); - +function registerRoutes (Vue, routesOptions) { + // Setup webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api + var requireContext = routesOptions.requireContext || require.context( + // root folder for routes + // relies on vue-cli setting a webpack alias of '@' to the project's /src folder + '@/', + // recursive + true, + // include all .router.js files + /\.router.js$/); + + // Ask webpack to list the files (In sync mode, require.context already adds all files to bundle) + var routeFiles = requireContext.keys(); + + // Return them all loaded, so users can pass them onto their VueRouter declaration return routeFiles.map(function (routeFile) { - var routerConfig = options.requireContext(routeFile); + var routerConfig = requireContext(routeFile); return routerConfig.default ? routerConfig.default : routerConfig; }); } /** - * Register components files using Vue.component and requiring the file from the context + * Register components files using Vue.component and requiring the file from webpack's context * @param {Vue} Vue VueJS instance - * @param {Object} options + * @param {Object} componentOptions */ -function registerComponents (Vue, options) { - var componentsFiles = options.requireContext - .keys() - .filter(function (file) { return file.match(options.components.pattern); }); - +function registerComponents (Vue, componentOptions) { + // Setup webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api + var requireContext = componentOptions.requireContext || require.context( + // root folder for components + // relies on vue-cli setting a webpack alias of '@' to the project's /src folder + '@/components', + // recursive + true, + // include all .vue files except for the .async.vue ones + /\/(?:[^.]+|(?!\.async\.vue$))\.vue$/); + + // Ask webpack to list the files (In sync mode, require.context already adds all files to bundle) + var componentFiles = requireContext.keys(); + + // Register all of them in Vue var getFileName = function (name) { return /\/([^\/]*)\.vue$/.exec(name)[1]; }; - - return componentsFiles.map(function (file) { + return componentFiles.map(function (file) { var name = getFileName(file); - var component = options.requireContext(file); + var component = requireContext(file); // Unwrap "default" from ES6 module if (component.hasOwnProperty('default')) { component = component.default; } Vue.component(name, component); @@ -57,25 +77,34 @@ function registerComponents (Vue, options) { } /** - * Register components files using Vue.component as async components by setting up a factory function using the requireAsyncContext + * 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} options + * @param {Object} componentOptions */ -function registerAsyncComponents (Vue, options) { - var componentsFiles = options.requireAsyncContext - .keys() - .filter(function (file) { return file.match(options.components.pattern); }); - +function registerAsyncComponents (Vue, componentOptions) { + // Setup webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api + var requireAsyncContext = componentOptions.requireAsyncContext || require.context( + // root folder for components + // relies on vue-cli setting a webpack alias of '@' to the project's /src folder + '@/components', + // recursive + true, + // include only .async.vue components + /async\.vue$/, + // webpack's lazy mode for require.context + 'lazy'); + + // Ask webpack to list the files (In lazy mode, files are added to their own chunk and only if we require them) + var componentFiles = requireAsyncContext.keys(); + + // Register all of them in Vue var getFileName = function (name) { return /\/([^\/]*)\.async\.vue$/.exec(name)[1]; }; - - return componentsFiles.map(function (file) { + return componentFiles.map(function (file) { var name = getFileName(file); // Register as async component https://vuejs.org/v2/guide/components-dynamic-async.html#Async-Components - Vue.component( - name, - function () { return options.requireAsyncContext(file); } - ); + Vue.component(name, function () { return requireAsyncContext(file); }); // Return the registered component return Vue.component(name); @@ -91,19 +120,6 @@ function parseOptions (userOptions) { userOptions = userOptions || {}; return { - // context and asyncContext are user provided using the require.context API - // which allows a 4th argument to specify the mode in which to load files - // By default this is 'sync', but can be made async as in require.context('./', true, /async\.vue$/, 'lazy') - // See https://github.com/webpack/docs/wiki/context#context-module-api - requireContext: userOptions.context, - requireAsyncContext: userOptions.asyncContext && userOptions.asyncContext.id.includes("lazy") ? - userOptions.asyncContext : - null, - - // Async mode is enabled/disabled depending on the last argument provided to require.context - // For example, enable async with: require.context('./', true, /(\.js|\.vue)$/, 'lazy') - // async: requireContext.id.includes("lazy"), - // Merge user-specific options for each of the different asset types routes: Object.assign({}, _defaults.routes, userOptions.routes), components: Object.assign({}, _defaults.components, userOptions.components) @@ -125,14 +141,12 @@ function register (Vue, userOptions) { routes: [], components: [] }; - if (options.routes.enabled && options.requireContext) { - aw.routes.push(registerRoutes(Vue, options)); - } - if (options.components.enabled && options.requireContext) { - aw.components.push(registerComponents(Vue, options)); + if (options.routes.enabled) { + aw.routes.push(registerRoutes(Vue, options.routes)); } - if (options.components.enabled && options.requireAsyncContext) { - aw.components.push(registerAsyncComponents(Vue, options)); + if (options.components.enabled) { + aw.components.push(registerComponents(Vue, options.components)); + aw.components.push(registerAsyncComponents(Vue, options.components)); } return aw; diff --git a/dist/vue-autowire.esm.browser.js b/dist/vue-autowire.esm.browser.js index ce78f15..07b8caa 100644 --- a/dist/vue-autowire.esm.browser.js +++ b/dist/vue-autowire.esm.browser.js @@ -6,45 +6,65 @@ const _defaults = { routes: { enabled: true, - pattern: /\.router.js$/ + requireContext: null }, components: { enabled: true, - pattern: /\/components\/.*\.vue$/ + requireContext: null, + requireAsyncContext: null } }; /** * Load router files * @param {Vue} Vue VueJS instance - * @param {Object} options + * @param {Object} routesOptions */ -function registerRoutes (Vue, options) { - const routeFiles = options.requireContext - .keys() - .filter(file => file.match(options.routes.pattern)); - +function registerRoutes (Vue, routesOptions) { + // Setup webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api + const requireContext = routesOptions.requireContext || require.context( + // root folder for routes + // relies on vue-cli setting a webpack alias of '@' to the project's /src folder + '@/', + // recursive + true, + // include all .router.js files + /\.router.js$/); + + // Ask webpack to list the files (In sync mode, require.context already adds all files to bundle) + const routeFiles = requireContext.keys(); + + // Return them all loaded, so users can pass them onto their VueRouter declaration return routeFiles.map(routeFile => { - const routerConfig = options.requireContext(routeFile); + const routerConfig = requireContext(routeFile); return routerConfig.default ? routerConfig.default : routerConfig; }); } /** - * Register components files using Vue.component and requiring the file from the context + * Register components files using Vue.component and requiring the file from webpack's context * @param {Vue} Vue VueJS instance - * @param {Object} options + * @param {Object} componentOptions */ -function registerComponents (Vue, options) { - const componentsFiles = options.requireContext - .keys() - .filter(file => file.match(options.components.pattern)); - +function registerComponents (Vue, componentOptions) { + // Setup webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api + const requireContext = componentOptions.requireContext || require.context( + // root folder for components + // relies on vue-cli setting a webpack alias of '@' to the project's /src folder + '@/components', + // recursive + true, + // include all .vue files except for the .async.vue ones + /\/(?:[^.]+|(?!\.async\.vue$))\.vue$/); + + // Ask webpack to list the files (In sync mode, require.context already adds all files to bundle) + const componentFiles = requireContext.keys(); + + // Register all of them in Vue const getFileName = name => /\/([^\/]*)\.vue$/.exec(name)[1]; - - return componentsFiles.map(file => { + return componentFiles.map(file => { const name = getFileName(file); - let component = options.requireContext(file); + let component = requireContext(file); // Unwrap "default" from ES6 module if (component.hasOwnProperty('default')) component = component.default; Vue.component(name, component); @@ -55,25 +75,34 @@ function registerComponents (Vue, options) { } /** - * Register components files using Vue.component as async components by setting up a factory function using the requireAsyncContext + * 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} options + * @param {Object} componentOptions */ -function registerAsyncComponents (Vue, options) { - const componentsFiles = options.requireAsyncContext - .keys() - .filter(file => file.match(options.components.pattern)); - +function registerAsyncComponents (Vue, componentOptions) { + // Setup webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api + const requireAsyncContext = componentOptions.requireAsyncContext || require.context( + // root folder for components + // relies on vue-cli setting a webpack alias of '@' to the project's /src folder + '@/components', + // recursive + true, + // include only .async.vue components + /async\.vue$/, + // webpack's lazy mode for require.context + 'lazy'); + + // Ask webpack to list the files (In lazy mode, files are added to their own chunk and only if we require them) + const componentFiles = requireAsyncContext.keys(); + + // Register all of them in Vue const getFileName = name => /\/([^\/]*)\.async\.vue$/.exec(name)[1]; - - return componentsFiles.map(file => { + return componentFiles.map(file => { const name = getFileName(file); // Register as async component https://vuejs.org/v2/guide/components-dynamic-async.html#Async-Components - Vue.component( - name, - () => options.requireAsyncContext(file) - ); + Vue.component(name, () => requireAsyncContext(file)); // Return the registered component return Vue.component(name); @@ -89,19 +118,6 @@ function parseOptions (userOptions) { userOptions = userOptions || {}; return { - // context and asyncContext are user provided using the require.context API - // which allows a 4th argument to specify the mode in which to load files - // By default this is 'sync', but can be made async as in require.context('./', true, /async\.vue$/, 'lazy') - // See https://github.com/webpack/docs/wiki/context#context-module-api - requireContext: userOptions.context, - requireAsyncContext: userOptions.asyncContext && userOptions.asyncContext.id.includes("lazy") ? - userOptions.asyncContext : - null, - - // Async mode is enabled/disabled depending on the last argument provided to require.context - // For example, enable async with: require.context('./', true, /(\.js|\.vue)$/, 'lazy') - // async: requireContext.id.includes("lazy"), - // Merge user-specific options for each of the different asset types routes: Object.assign({}, _defaults.routes, userOptions.routes), components: Object.assign({}, _defaults.components, userOptions.components) @@ -123,14 +139,12 @@ function register (Vue, userOptions) { routes: [], components: [] }; - if (options.routes.enabled && options.requireContext) { - aw.routes.push(registerRoutes(Vue, options)); - } - if (options.components.enabled && options.requireContext) { - aw.components.push(registerComponents(Vue, options)); + if (options.routes.enabled) { + aw.routes.push(registerRoutes(Vue, options.routes)); } - if (options.components.enabled && options.requireAsyncContext) { - aw.components.push(registerAsyncComponents(Vue, options)); + if (options.components.enabled) { + aw.components.push(registerComponents(Vue, options.components)); + aw.components.push(registerAsyncComponents(Vue, options.components)); } return aw; diff --git a/dist/vue-autowire.esm.browser.min.js b/dist/vue-autowire.esm.browser.min.js index 2e22b85..ec899ab 100644 --- a/dist/vue-autowire.esm.browser.min.js +++ b/dist/vue-autowire.esm.browser.min.js @@ -3,4 +3,4 @@ * (c) 2019 Kaizen Dorks * @license MIT */ -const e={routes:{enabled:!0,pattern:/\.router.js$/},components:{enabled:!0,pattern:/\/components\/.*\.vue$/}};function t(t,n){const o=function(t){return{requireContext:(t=t||{}).context,requireAsyncContext:t.asyncContext&&t.asyncContext.id.includes("lazy")?t.asyncContext:null,routes:Object.assign({},e.routes,t.routes),components:Object.assign({},e.components,t.components)}}(n),r={routes:[],components:[]};return o.routes.enabled&&o.requireContext&&r.routes.push(function(e,t){return t.requireContext.keys().filter(e=>e.match(t.routes.pattern)).map(e=>{const n=t.requireContext(e);return n.default?n.default:n})}(0,o)),o.components.enabled&&o.requireContext&&r.components.push(function(e,t){return t.requireContext.keys().filter(e=>e.match(t.components.pattern)).map(n=>{const o=(e=>/\/([^\/]*)\.vue$/.exec(e)[1])(n);let r=t.requireContext(n);return r.hasOwnProperty("default")&&(r=r.default),e.component(o,r),e.component(o)})}(t,o)),o.components.enabled&&o.requireAsyncContext&&r.components.push(function(e,t){return t.requireAsyncContext.keys().filter(e=>e.match(t.components.pattern)).map(n=>{const o=(e=>/\/([^\/]*)\.async\.vue$/.exec(e)[1])(n);return e.component(o,()=>t.requireAsyncContext(n)),e.component(o)})}(t,o)),r}export default function(e,n){e.autowire=t(e,n)} \ No newline at end of file +const e={routes:{enabled:!0,requireContext:null},components:{enabled:!0,requireContext:null,requireAsyncContext:null}};function n(n,t){const o=function(n){return n=n||{},{routes:Object.assign({},e.routes,n.routes),components:Object.assign({},e.components,n.components)}}(t),u={routes:[],components:[]};return o.routes.enabled&&u.routes.push(function(e,n){const t=n.requireContext||require.context("@/",!0,/\.router.js$/);return t.keys().map(e=>{const n=t(e);return n.default?n.default:n})}(0,o.routes)),o.components.enabled&&(u.components.push(function(e,n){const t=n.requireContext||require.context("@/components",!0,/\/(?:[^.]+|(?!\.async\.vue$))\.vue$/);return t.keys().map(n=>{const o=(e=>/\/([^\/]*)\.vue$/.exec(e)[1])(n);let u=t(n);return u.hasOwnProperty("default")&&(u=u.default),e.component(o,u),e.component(o)})}(n,o.components)),u.components.push(function(e,n){const t=n.requireAsyncContext||require.context("@/components",!0,/async\.vue$/,"lazy");return t.keys().map(n=>{const o=(e=>/\/([^\/]*)\.async\.vue$/.exec(e)[1])(n);return e.component(o,()=>t(n)),e.component(o)})}(n,o.components))),u}export default function(e,t){e.autowire=n(e,t)} \ No newline at end of file diff --git a/dist/vue-autowire.esm.js b/dist/vue-autowire.esm.js index 5578c63..b77d08c 100644 --- a/dist/vue-autowire.esm.js +++ b/dist/vue-autowire.esm.js @@ -6,45 +6,65 @@ var _defaults = { routes: { enabled: true, - pattern: /\.router.js$/ + requireContext: null }, components: { enabled: true, - pattern: /\/components\/.*\.vue$/ + requireContext: null, + requireAsyncContext: null } }; /** * Load router files * @param {Vue} Vue VueJS instance - * @param {Object} options + * @param {Object} routesOptions */ -function registerRoutes (Vue, options) { - var routeFiles = options.requireContext - .keys() - .filter(function (file) { return file.match(options.routes.pattern); }); - +function registerRoutes (Vue, routesOptions) { + // Setup webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api + var requireContext = routesOptions.requireContext || require.context( + // root folder for routes + // relies on vue-cli setting a webpack alias of '@' to the project's /src folder + '@/', + // recursive + true, + // include all .router.js files + /\.router.js$/); + + // Ask webpack to list the files (In sync mode, require.context already adds all files to bundle) + var routeFiles = requireContext.keys(); + + // Return them all loaded, so users can pass them onto their VueRouter declaration return routeFiles.map(function (routeFile) { - var routerConfig = options.requireContext(routeFile); + var routerConfig = requireContext(routeFile); return routerConfig.default ? routerConfig.default : routerConfig; }); } /** - * Register components files using Vue.component and requiring the file from the context + * Register components files using Vue.component and requiring the file from webpack's context * @param {Vue} Vue VueJS instance - * @param {Object} options + * @param {Object} componentOptions */ -function registerComponents (Vue, options) { - var componentsFiles = options.requireContext - .keys() - .filter(function (file) { return file.match(options.components.pattern); }); - +function registerComponents (Vue, componentOptions) { + // Setup webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api + var requireContext = componentOptions.requireContext || require.context( + // root folder for components + // relies on vue-cli setting a webpack alias of '@' to the project's /src folder + '@/components', + // recursive + true, + // include all .vue files except for the .async.vue ones + /\/(?:[^.]+|(?!\.async\.vue$))\.vue$/); + + // Ask webpack to list the files (In sync mode, require.context already adds all files to bundle) + var componentFiles = requireContext.keys(); + + // Register all of them in Vue var getFileName = function (name) { return /\/([^\/]*)\.vue$/.exec(name)[1]; }; - - return componentsFiles.map(function (file) { + return componentFiles.map(function (file) { var name = getFileName(file); - var component = options.requireContext(file); + var component = requireContext(file); // Unwrap "default" from ES6 module if (component.hasOwnProperty('default')) { component = component.default; } Vue.component(name, component); @@ -55,25 +75,34 @@ function registerComponents (Vue, options) { } /** - * Register components files using Vue.component as async components by setting up a factory function using the requireAsyncContext + * 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} options + * @param {Object} componentOptions */ -function registerAsyncComponents (Vue, options) { - var componentsFiles = options.requireAsyncContext - .keys() - .filter(function (file) { return file.match(options.components.pattern); }); - +function registerAsyncComponents (Vue, componentOptions) { + // Setup webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api + var requireAsyncContext = componentOptions.requireAsyncContext || require.context( + // root folder for components + // relies on vue-cli setting a webpack alias of '@' to the project's /src folder + '@/components', + // recursive + true, + // include only .async.vue components + /async\.vue$/, + // webpack's lazy mode for require.context + 'lazy'); + + // Ask webpack to list the files (In lazy mode, files are added to their own chunk and only if we require them) + var componentFiles = requireAsyncContext.keys(); + + // Register all of them in Vue var getFileName = function (name) { return /\/([^\/]*)\.async\.vue$/.exec(name)[1]; }; - - return componentsFiles.map(function (file) { + return componentFiles.map(function (file) { var name = getFileName(file); // Register as async component https://vuejs.org/v2/guide/components-dynamic-async.html#Async-Components - Vue.component( - name, - function () { return options.requireAsyncContext(file); } - ); + Vue.component(name, function () { return requireAsyncContext(file); }); // Return the registered component return Vue.component(name); @@ -89,19 +118,6 @@ function parseOptions (userOptions) { userOptions = userOptions || {}; return { - // context and asyncContext are user provided using the require.context API - // which allows a 4th argument to specify the mode in which to load files - // By default this is 'sync', but can be made async as in require.context('./', true, /async\.vue$/, 'lazy') - // See https://github.com/webpack/docs/wiki/context#context-module-api - requireContext: userOptions.context, - requireAsyncContext: userOptions.asyncContext && userOptions.asyncContext.id.includes("lazy") ? - userOptions.asyncContext : - null, - - // Async mode is enabled/disabled depending on the last argument provided to require.context - // For example, enable async with: require.context('./', true, /(\.js|\.vue)$/, 'lazy') - // async: requireContext.id.includes("lazy"), - // Merge user-specific options for each of the different asset types routes: Object.assign({}, _defaults.routes, userOptions.routes), components: Object.assign({}, _defaults.components, userOptions.components) @@ -123,14 +139,12 @@ function register (Vue, userOptions) { routes: [], components: [] }; - if (options.routes.enabled && options.requireContext) { - aw.routes.push(registerRoutes(Vue, options)); - } - if (options.components.enabled && options.requireContext) { - aw.components.push(registerComponents(Vue, options)); + if (options.routes.enabled) { + aw.routes.push(registerRoutes(Vue, options.routes)); } - if (options.components.enabled && options.requireAsyncContext) { - aw.components.push(registerAsyncComponents(Vue, options)); + if (options.components.enabled) { + aw.components.push(registerComponents(Vue, options.components)); + aw.components.push(registerAsyncComponents(Vue, options.components)); } return aw; diff --git a/dist/vue-autowire.js b/dist/vue-autowire.js index 11cb24f..6104fc1 100644 --- a/dist/vue-autowire.js +++ b/dist/vue-autowire.js @@ -12,45 +12,65 @@ var _defaults = { routes: { enabled: true, - pattern: /\.router.js$/ + requireContext: null }, components: { enabled: true, - pattern: /\/components\/.*\.vue$/ + requireContext: null, + requireAsyncContext: null } }; /** * Load router files * @param {Vue} Vue VueJS instance - * @param {Object} options + * @param {Object} routesOptions */ -function registerRoutes (Vue, options) { - var routeFiles = options.requireContext - .keys() - .filter(function (file) { return file.match(options.routes.pattern); }); - +function registerRoutes (Vue, routesOptions) { + // Setup webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api + var requireContext = routesOptions.requireContext || require.context( + // root folder for routes + // relies on vue-cli setting a webpack alias of '@' to the project's /src folder + '@/', + // recursive + true, + // include all .router.js files + /\.router.js$/); + + // Ask webpack to list the files (In sync mode, require.context already adds all files to bundle) + var routeFiles = requireContext.keys(); + + // Return them all loaded, so users can pass them onto their VueRouter declaration return routeFiles.map(function (routeFile) { - var routerConfig = options.requireContext(routeFile); + var routerConfig = requireContext(routeFile); return routerConfig.default ? routerConfig.default : routerConfig; }); } /** - * Register components files using Vue.component and requiring the file from the context + * Register components files using Vue.component and requiring the file from webpack's context * @param {Vue} Vue VueJS instance - * @param {Object} options + * @param {Object} componentOptions */ -function registerComponents (Vue, options) { - var componentsFiles = options.requireContext - .keys() - .filter(function (file) { return file.match(options.components.pattern); }); - +function registerComponents (Vue, componentOptions) { + // Setup webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api + var requireContext = componentOptions.requireContext || require.context( + // root folder for components + // relies on vue-cli setting a webpack alias of '@' to the project's /src folder + '@/components', + // recursive + true, + // include all .vue files except for the .async.vue ones + /\/(?:[^.]+|(?!\.async\.vue$))\.vue$/); + + // Ask webpack to list the files (In sync mode, require.context already adds all files to bundle) + var componentFiles = requireContext.keys(); + + // Register all of them in Vue var getFileName = function (name) { return /\/([^\/]*)\.vue$/.exec(name)[1]; }; - - return componentsFiles.map(function (file) { + return componentFiles.map(function (file) { var name = getFileName(file); - var component = options.requireContext(file); + var component = requireContext(file); // Unwrap "default" from ES6 module if (component.hasOwnProperty('default')) { component = component.default; } Vue.component(name, component); @@ -61,25 +81,34 @@ function registerComponents (Vue, options) { } /** - * Register components files using Vue.component as async components by setting up a factory function using the requireAsyncContext + * 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} options + * @param {Object} componentOptions */ -function registerAsyncComponents (Vue, options) { - var componentsFiles = options.requireAsyncContext - .keys() - .filter(function (file) { return file.match(options.components.pattern); }); - +function registerAsyncComponents (Vue, componentOptions) { + // Setup webpack's require context. See https://github.com/webpack/docs/wiki/context#context-module-api + var requireAsyncContext = componentOptions.requireAsyncContext || require.context( + // root folder for components + // relies on vue-cli setting a webpack alias of '@' to the project's /src folder + '@/components', + // recursive + true, + // include only .async.vue components + /async\.vue$/, + // webpack's lazy mode for require.context + 'lazy'); + + // Ask webpack to list the files (In lazy mode, files are added to their own chunk and only if we require them) + var componentFiles = requireAsyncContext.keys(); + + // Register all of them in Vue var getFileName = function (name) { return /\/([^\/]*)\.async\.vue$/.exec(name)[1]; }; - - return componentsFiles.map(function (file) { + return componentFiles.map(function (file) { var name = getFileName(file); // Register as async component https://vuejs.org/v2/guide/components-dynamic-async.html#Async-Components - Vue.component( - name, - function () { return options.requireAsyncContext(file); } - ); + Vue.component(name, function () { return requireAsyncContext(file); }); // Return the registered component return Vue.component(name); @@ -95,19 +124,6 @@ function parseOptions (userOptions) { userOptions = userOptions || {}; return { - // context and asyncContext are user provided using the require.context API - // which allows a 4th argument to specify the mode in which to load files - // By default this is 'sync', but can be made async as in require.context('./', true, /async\.vue$/, 'lazy') - // See https://github.com/webpack/docs/wiki/context#context-module-api - requireContext: userOptions.context, - requireAsyncContext: userOptions.asyncContext && userOptions.asyncContext.id.includes("lazy") ? - userOptions.asyncContext : - null, - - // Async mode is enabled/disabled depending on the last argument provided to require.context - // For example, enable async with: require.context('./', true, /(\.js|\.vue)$/, 'lazy') - // async: requireContext.id.includes("lazy"), - // Merge user-specific options for each of the different asset types routes: Object.assign({}, _defaults.routes, userOptions.routes), components: Object.assign({}, _defaults.components, userOptions.components) @@ -129,14 +145,12 @@ function register (Vue, userOptions) { routes: [], components: [] }; - if (options.routes.enabled && options.requireContext) { - aw.routes.push(registerRoutes(Vue, options)); - } - if (options.components.enabled && options.requireContext) { - aw.components.push(registerComponents(Vue, options)); + if (options.routes.enabled) { + aw.routes.push(registerRoutes(Vue, options.routes)); } - if (options.components.enabled && options.requireAsyncContext) { - aw.components.push(registerAsyncComponents(Vue, options)); + if (options.components.enabled) { + aw.components.push(registerComponents(Vue, options.components)); + aw.components.push(registerAsyncComponents(Vue, options.components)); } return aw; diff --git a/dist/vue-autowire.min.js b/dist/vue-autowire.min.js index dd90523..6c1a852 100644 --- a/dist/vue-autowire.min.js +++ b/dist/vue-autowire.min.js @@ -3,4 +3,4 @@ * (c) 2019 Kaizen Dorks * @license MIT */ -var e,n;e=this,n=function(){"use strict";var e={routes:{enabled:!0,pattern:/\.router.js$/},components:{enabled:!0,pattern:/\/components\/.*\.vue$/}};function n(n,t){var o=function(n){return{requireContext:(n=n||{}).context,requireAsyncContext:n.asyncContext&&n.asyncContext.id.includes("lazy")?n.asyncContext:null,routes:Object.assign({},e.routes,n.routes),components:Object.assign({},e.components,n.components)}}(t),r={routes:[],components:[]};return o.routes.enabled&&o.requireContext&&r.routes.push(function(e,n){return n.requireContext.keys().filter(function(e){return e.match(n.routes.pattern)}).map(function(e){var t=n.requireContext(e);return t.default?t.default:t})}(0,o)),o.components.enabled&&o.requireContext&&r.components.push(function(e,n){return n.requireContext.keys().filter(function(e){return e.match(n.components.pattern)}).map(function(t){var o=function(e){return/\/([^\/]*)\.vue$/.exec(e)[1]}(t),r=n.requireContext(t);return r.hasOwnProperty("default")&&(r=r.default),e.component(o,r),e.component(o)})}(n,o)),o.components.enabled&&o.requireAsyncContext&&r.components.push(function(e,n){return n.requireAsyncContext.keys().filter(function(e){return e.match(n.components.pattern)}).map(function(t){var o=function(e){return/\/([^\/]*)\.async\.vue$/.exec(e)[1]}(t);return e.component(o,function(){return n.requireAsyncContext(t)}),e.component(o)})}(n,o)),r}return function(e,t){e.autowire=n(e,t)}},"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):e.VueAutowire=n(); \ No newline at end of file +var e,n;e=this,n=function(){"use strict";var e={routes:{enabled:!0,requireContext:null},components:{enabled:!0,requireContext:null,requireAsyncContext:null}};function n(n,t){var o,r,u=function(n){return n=n||{},{routes:Object.assign({},e.routes,n.routes),components:Object.assign({},e.components,n.components)}}(t),c={routes:[],components:[]};return u.routes.enabled&&c.routes.push((o=u.routes,(r=o.requireContext||require.context("@/",!0,/\.router.js$/)).keys().map(function(e){var n=r(e);return n.default?n.default:n}))),u.components.enabled&&(c.components.push(function(e,n){var t=n.requireContext||require.context("@/components",!0,/\/(?:[^.]+|(?!\.async\.vue$))\.vue$/);return t.keys().map(function(n){var o=function(e){return/\/([^\/]*)\.vue$/.exec(e)[1]}(n),r=t(n);return r.hasOwnProperty("default")&&(r=r.default),e.component(o,r),e.component(o)})}(n,u.components)),c.components.push(function(e,n){var t=n.requireAsyncContext||require.context("@/components",!0,/async\.vue$/,"lazy");return t.keys().map(function(n){var o=function(e){return/\/([^\/]*)\.async\.vue$/.exec(e)[1]}(n);return e.component(o,function(){return t(n)}),e.component(o)})}(n,u.components))),c}return function(e,t){e.autowire=n(e,t)}},"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):e.VueAutowire=n(); \ No newline at end of file diff --git a/docs-src/guide/README.md b/docs-src/guide/README.md index b642665..31a6e32 100755 --- a/docs-src/guide/README.md +++ b/docs-src/guide/README.md @@ -1,20 +1,32 @@ # Getting Started -Sample usage +Sample usage with a project generated with the vue-cli ``` import Vue from 'vue' import App from './App.vue' -import VueAutowire from './autowire'; +import VueAutowire from 'vue-autowire'; Vue.config.productionTip = false +// Use default settings +Vue.use(VueAutowire); + +// Enable only certain options +Vue.use(VueAutowire, { + routes: { enabled: false }, +}); + +// Provide your own webpack context with your own convention for folder/file names Vue.use(VueAutowire, { - // All .js and .vue files except the ones ending with .async.vue - context: require.context('./', true, /\/(?:[^.]+|(?!\.async\.vue$))(\.js|\.vue)$/), - // All the .async.vue files as async components on their own webpack chunk - asyncContext: require.context('./', true, /async\.vue$/, 'lazy') -}) + components: { + // all components in the /src/components folder that end with .vue, excluding the .async.vue ones + context: require.context('@/components', true, /\/(?:[^.]+|(?!\.async\.vue$))\.vue$/), + // all components in the /src/components folder that end with async.vue + // Not the last argument to use webpack's lazy mode so they get their own chunk + context: require.context('@/components', true, /async\.vue$/, 'lazy'), + }, +}); new Vue({ render: h => h(App), diff --git a/docs/404.html b/docs/404.html index 6f871ad..adfc867 100644 --- a/docs/404.html +++ b/docs/404.html @@ -7,11 +7,11 @@ - +
-