Skip to content

Commit

Permalink
Merge pull request #1 from ara-framework/feat/lazy-load
Browse files Browse the repository at this point in the history
feat: Add lazy loading support usin views field in plugin configuration
  • Loading branch information
marconi1992 authored Sep 13, 2019
2 parents 8f589ac + 8e0681e commit e747b71
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 15 deletions.
5 changes: 4 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"extends": "airbnb-base"
"extends": "airbnb-base",
"rules": {
"arrow-body-style": 0
}
}
23 changes: 21 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ module.exports = {
new NovaConsumerPlugin({
novas: [
{
entry: 'http://localhost:8080/client.js'
entry: 'http://localhost:8080/client.js',
views: [
'ExampleView'
]
}
]
})
Expand All @@ -31,5 +34,21 @@ module.exports = {

### Live Reload

This plugin create a socket connection for each Nova that is running with `webpack-dev-server` in development mode. Then the page is reload everytime that the Nova code is compiled with webpack.
The plugin creates a socket connection for each Nova that is running with `webpack-dev-server` in development mode. Then the page is reload everytime that the Nova code is compiled with webpack.


### Lazy Load

Lazy load is enabled by default when webpack runs in production mode. It generates a script file that loads the Nova `entry` when a view listed in the `views` field is placed in the page using the [Nova Bridge](https://ara-framework.github.io/website/docs/nova-bridge)

Example using [nova-vue-bridge](https://www.npmjs.com/package/nova-vue-bridge):

```vue
<template>
<div class="container">
<nova name="ExampleView" :data="{ title: 'Ara Framework' }" />
</div>
</template>
```

The entry point `http://localhost:8080/client.js` is loaded when Vue.js mounts the previous component.
40 changes: 28 additions & 12 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const url = require('url');
const qs = require('querystring');

class NovaConsumerPlugin {
constructor(opts = {}) {
Expand All @@ -21,23 +22,38 @@ class NovaConsumerPlugin {
}
});
});
}

compiler.hooks.compilation.tap('NovaConsumerPlugin', (context) => {
context.hooks.htmlWebpackPluginBeforeHtmlProcessing.tapAsync('NovaConsumerPlugin', (data, cb) => {
const { assets } = data;
} else {
compiler.hooks.entryOption.tap('NovaConsumerPlugin', (context, entry) => {
const { novas = [] } = this.opts;

novas.forEach((nova) => {
const { entry } = nova;
const viewsMap = novas.reduce((acc, { views = [], entry: novaEntry }) => {
return views.reduce((acc2, view) => {
acc2[view] = novaEntry; // eslint-disable-line no-param-reassign
return acc2;
}, acc);
}, {});

if (entry) {
assets.js.push(entry);
}
entry['nova-lazy-load'] = `@ara/webpack-nova-consumer/lazy?${qs.encode(viewsMap)}`; // eslint-disable-line no-param-reassign
});
}

if (compiler.options.mode === 'development') {
compiler.hooks.compilation.tap('NovaConsumerPlugin', (context) => {
context.hooks.htmlWebpackPluginBeforeHtmlProcessing.tapAsync('NovaConsumerPlugin', (data, cb) => {
const { assets } = data;
const { novas = [] } = this.opts;

novas.forEach((nova) => {
const { entry } = nova;

if (entry) {
assets.js.push(entry);
}
});
cb();
});
cb();
});
});
}
}
}

Expand Down
32 changes: 32 additions & 0 deletions lazy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* eslint-disable no-undef */

const querystring = require('querystring');

const loadScript = (src) => new Promise((resolve) => {
if (document.querySelector(`script[src="${src}"]`)) {
return resolve();
}

const el = document.createElement('script');

el.type = 'text/javascript';
el.async = true;
el.src = src;

document.head.appendChild(el);
return resolve();
});

if (__resourceQuery) {
const viewsMap = querystring.parse(__resourceQuery.slice(1));

document.addEventListener('NovaMount', ({ detail }) => {
const { name } = detail;

const src = viewsMap[name];

if (src) {
loadScript(src);
}
});
}

0 comments on commit e747b71

Please sign in to comment.