Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH-5, autowire views #17

Merged
merged 1 commit into from
May 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 20 additions & 16 deletions dist/vue-autowire.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function registerComponents (Vue, requireContext) {
function registerAsyncComponents (Vue, requireContext) {
// Make sure require.context was created with lazy mode
if (!requireContext.id.includes('lazy')) {
throw new Error('require.context for asyn components should be created in lazy mode. See https://github.com/webpack/docs/wiki/context#context-module-api');
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
Expand All @@ -88,26 +88,30 @@ function autowire (Vue, conventions) {
// 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 },
components: { requireContext: null, requireAsyncContext: null }
components: { requireContext: null, requireAsyncContext: null },
views: { requireContext: null, requireAsyncContext: null }
}, conventions);

// Keep track of every asset wired by the library
// Wire every asset type for which there is a require.context provided
var aw = {
routes: [],
components: [],
asyncComponents: []
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) :
[]
};

if (conventions.components.requireContext) {
aw.components = registerComponents(Vue, conventions.components.requireContext);
}
if (conventions.components.requireAsyncContext) {
aw.asyncComponents = registerAsyncComponents(Vue, conventions.components.requireAsyncContext);
}
if (conventions.routes.requireContext) {
aw.routes = registerRoutes(Vue, conventions.routes.requireContext);
}

// export the results into the Vue instance, so they can be inspected
Vue.autowire = aw;
}

Expand Down
36 changes: 20 additions & 16 deletions dist/vue-autowire.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function registerComponents (Vue, requireContext) {
function registerAsyncComponents (Vue, requireContext) {
// Make sure require.context was created with lazy mode
if (!requireContext.id.includes('lazy')) {
throw new Error('require.context for asyn components should be created in lazy mode. See https://github.com/webpack/docs/wiki/context#context-module-api');
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
Expand All @@ -86,26 +86,30 @@ function autowire (Vue, conventions) {
// 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 },
components: { requireContext: null, requireAsyncContext: null }
components: { requireContext: null, requireAsyncContext: null },
views: { requireContext: null, requireAsyncContext: null }
}, conventions);

// Keep track of every asset wired by the library
// Wire every asset type for which there is a require.context provided
var aw = {
routes: [],
components: [],
asyncComponents: []
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) :
[]
};

if (conventions.components.requireContext) {
aw.components = registerComponents(Vue, conventions.components.requireContext);
}
if (conventions.components.requireAsyncContext) {
aw.asyncComponents = registerAsyncComponents(Vue, conventions.components.requireAsyncContext);
}
if (conventions.routes.requireContext) {
aw.routes = registerRoutes(Vue, conventions.routes.requireContext);
}

// export the results into the Vue instance, so they can be inspected
Vue.autowire = aw;
}

Expand Down
36 changes: 20 additions & 16 deletions dist/vue-autowire.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function registerComponents (Vue, requireContext) {
function registerAsyncComponents (Vue, requireContext) {
// Make sure require.context was created with lazy mode
if (!requireContext.id.includes('lazy')) {
throw new Error('require.context for asyn components should be created in lazy mode. See https://github.com/webpack/docs/wiki/context#context-module-api');
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
Expand All @@ -92,26 +92,30 @@ function autowire (Vue, conventions) {
// 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 },
components: { requireContext: null, requireAsyncContext: null }
components: { requireContext: null, requireAsyncContext: null },
views: { requireContext: null, requireAsyncContext: null }
}, conventions);

// Keep track of every asset wired by the library
// Wire every asset type for which there is a require.context provided
var aw = {
routes: [],
components: [],
asyncComponents: []
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) :
[]
};

if (conventions.components.requireContext) {
aw.components = registerComponents(Vue, conventions.components.requireContext);
}
if (conventions.components.requireAsyncContext) {
aw.asyncComponents = registerAsyncComponents(Vue, conventions.components.requireAsyncContext);
}
if (conventions.routes.requireContext) {
aw.routes = registerRoutes(Vue, conventions.routes.requireContext);
}

// export the results into the Vue instance, so they can be inspected
Vue.autowire = aw;
}

Expand Down
2 changes: 1 addition & 1 deletion dist/vue-autowire.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions docs-src/conventions/components.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Components

Vue-Autowire lets you provide 2 different `require.context` instances when defining the components convention:
Similarly to the [views](./views.md) convention, Vue-Autowire lets you provide 2 different `require.context` instances when defining the components convention:
```js
Vue.use(VueAutowire, {
components: {
Expand Down Expand Up @@ -35,8 +35,8 @@ It is defined as follows:

Which means:
- Assumes there is a [webpack alias](https://webpack.js.org/configuration/resolve/#resolvealias) defined as `@` which maps to the root source of the Vue application. _If you are using the Vue-CLI, this is already the case_
- With `requireContext`, all the files inside the `@/components` folder that end with `.vue` but not with `.local.vue` nor `.async.vue` will be found. They will be registered as components within the Vue application and included in the main bundle.
- With `requireAsyncContext`, all the files inside the `@/components` folder that end with `async.vue` will be found. They will be registered as **async** components within the Vue application and included in **their own bundle**. (One bundle per each async component)
- With `requireContext`, all the files inside the `@/components` folder that end with `.vue` but not with `.local.vue` nor `.async.vue` will be found. They will be registered as Vue components within the Vue application and included in the main bundle.
- With `requireAsyncContext`, all the files inside the `@/components` folder that end with `async.vue` will be found. They will be registered as **async** Vue components within the Vue application and included in **their own bundle**. (One bundle per each async component)

### Example
Given a folder structure like
Expand All @@ -48,7 +48,7 @@ Given a folder structure like
markdown-editor.async.vue
/blog-entry-preview
blog-entry-preview.async.vue
author-preview.local.vue // manually imported from blog-entry-preview.async.view
author-preview.local.vue // manually imported from blog-entry-preview.async.vue
/views
...
/directives
Expand Down
105 changes: 104 additions & 1 deletion docs-src/conventions/views.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,106 @@
# Views

WIP
Similarly to the [components](./components.md) convention, Vue-Autowire lets you provide 2 different `require.context` instances when defining the views convention:
```js
Vue.use(VueAutowire, {
views: {
requireContext: require.context('@/views', true, /\/(?:[^.]+|(?!\.local\.vue$)|(?!\.async\.vue$))\.vue$/),
requireAsyncContext: require.context('@/views', true, /async\.vue$/, 'lazy')
}
})
```

- The first one, `requireContext` lets you define the views that will be registered within Vue as regular sync components, to be included in the main webpack bundle.
- The second one, `requireAsyncContext` lets you define the views that will be registerd within Vue as [async components](https://vuejs.org/v2/guide/components-dynamic-async.html#Async-Components), to be included on their **own bundle** by using the **lazy** mode of webpack's [require.context](https://webpack.js.org/api/module-methods/#requirecontext) API.

## Default Convention

The default convention will be used with either of these:
```js
// Use all of the default conventions
import defaultConventions from 'vue-autowire/src/conventions'
// Use only the views default convention
import defaultViewConventions from 'vue-autowire/src/conventions/views'
```

It is defined as follows:
```js
{
views: {
requireContext: require.context('@/views', true, /\/(?:[^.]+|(?!\.local\.vue$)|(?!\.async\.vue$))\.vue$/),
requireAsyncContext: require.context('@/views', true, /async\.vue$/, 'lazy')
}
}
```

Which means:
- Assumes there is a [webpack alias](https://webpack.js.org/configuration/resolve/#resolvealias) defined as `@` which maps to the root source of the Vue application. _If you are using the Vue-CLI, this is already the case_
- With `requireContext`, all the files inside the `@/views` folder that end with `.vue` but not with `.local.vue` nor `.async.vue` will be found. They will be registered as Vue components within the Vue application and included in the main bundle.
- With `requireAsyncContext`, all the files inside the `@/views` folder that end with `async.vue` will be found. They will be registered as **async** Vue components within the Vue application and included in **their own bundle**. (One bundle per each async view)

### Example
Given a folder structure like
```
/src
/views
home.vue
about.async.vue
/profile-settings
profile-settings.async.vue
security-settings.local.vue // manually imported from profile-settings.async.vue
/components
...
/directives
...
/mixins
...
App.vue
main.js
router.js
```

The default **views convention** will:
- Register `home` as Vue sync components, exactly with that names.
- Include `home.vue` in the main webpack bundle
- Register `about` and `profile-settings` as Vue async components, exactly with those names.
- Include `about.async.vue` into its own webpack bundle
- Include `profile-settings.async.vue` and `security-settings.local.vue` into its own webpack bundle (assuming you manually import `security-settings.local.vue` from `profile-settings.async.vue`)


## Router integration
Most likely, you will define views so they can be defined as the component of vue-router routes.
Update your routes definition to use the components that Vue-Autowire will have registered:
```js
{
path: '/',
name: 'home',
// Instead of manually importing here the component, use the one that Vue-Autowire registered
// The name is based on the file name
component: Vue.component('home')
},
```
:::tip
This will work even if you defined the view as an async one!
:::

Then you want to make sure that Vue-Autowire is able to find and register all the views before you construct the routes.
For example, make sure the file where you create the `Router` instance exports a function rather than the instance:
```js
export default () => new Router({
routes: [
...
]
}
```

This way, in your main `app.js` file, you can execute the function to get the router _only after_ Vue-Autowire has been registered:
```js
Vue.use(VueAutowire, defaultConventions);

...

new Vue({
router: router(),
render: h => h(App)
}).$mount('#vue-holder');
```
4 changes: 2 additions & 2 deletions docs/404.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
<meta name="description" content="">


<link rel="preload" href="/vue-autowire/assets/css/0.styles.26b306d6.css" as="style"><link rel="preload" href="/vue-autowire/assets/js/app.50bcb63c.js" as="script"><link rel="prefetch" href="/vue-autowire/assets/js/10.610b9671.js"><link rel="prefetch" href="/vue-autowire/assets/js/11.8c0434a4.js"><link rel="prefetch" href="/vue-autowire/assets/js/2.afc26b7e.js"><link rel="prefetch" href="/vue-autowire/assets/js/3.d9556d6b.js"><link rel="prefetch" href="/vue-autowire/assets/js/4.4b186996.js"><link rel="prefetch" href="/vue-autowire/assets/js/5.9893796f.js"><link rel="prefetch" href="/vue-autowire/assets/js/6.5bcd68e7.js"><link rel="prefetch" href="/vue-autowire/assets/js/7.3a36a519.js"><link rel="prefetch" href="/vue-autowire/assets/js/8.faa0fff2.js"><link rel="prefetch" href="/vue-autowire/assets/js/9.07bc468b.js">
<link rel="preload" href="/vue-autowire/assets/css/0.styles.26b306d6.css" as="style"><link rel="preload" href="/vue-autowire/assets/js/app.5658a3d5.js" as="script"><link rel="prefetch" href="/vue-autowire/assets/js/10.610b9671.js"><link rel="prefetch" href="/vue-autowire/assets/js/11.8c0434a4.js"><link rel="prefetch" href="/vue-autowire/assets/js/2.afc26b7e.js"><link rel="prefetch" href="/vue-autowire/assets/js/3.d9556d6b.js"><link rel="prefetch" href="/vue-autowire/assets/js/4.4b186996.js"><link rel="prefetch" href="/vue-autowire/assets/js/5.00e5463d.js"><link rel="prefetch" href="/vue-autowire/assets/js/6.5bcd68e7.js"><link rel="prefetch" href="/vue-autowire/assets/js/7.3a36a519.js"><link rel="prefetch" href="/vue-autowire/assets/js/8.faa0fff2.js"><link rel="prefetch" href="/vue-autowire/assets/js/9.a44ae208.js">
<link rel="stylesheet" href="/vue-autowire/assets/css/0.styles.26b306d6.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><div class="content"><h1>404</h1> <blockquote>That's a Four-Oh-Four.</blockquote> <a href="/vue-autowire/" class="router-link-active">Take me home.</a></div></div></div>
<script src="/vue-autowire/assets/js/app.50bcb63c.js" defer></script>
<script src="/vue-autowire/assets/js/app.5658a3d5.js" defer></script>
</body>
</html>
Loading