Skip to content

Commit

Permalink
Merge pull request #11 from kaizendorks/GH-9
Browse files Browse the repository at this point in the history
GH-9, rearchitect to allow zero-config usage with default conventions
  • Loading branch information
DaniJG committed May 19, 2019
2 parents bd5f6ed + 36ad580 commit 121f01d
Show file tree
Hide file tree
Showing 23 changed files with 426 additions and 321 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
dist
docs
30 changes: 20 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/!
118 changes: 66 additions & 52 deletions dist/vue-autowire.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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)
Expand All @@ -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;
Expand Down
118 changes: 66 additions & 52 deletions dist/vue-autowire.esm.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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)
Expand All @@ -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;
Expand Down

0 comments on commit 121f01d

Please sign in to comment.