Skip to content

Commit c0d86ea

Browse files
authored
feat(meta): merge head at runtime (#363)
* refactor: remove spa workaround * refactor: merge meta in runtime * refactor: SPA support * fix spa support * docs: recommand using buildModules * feat: warn when target is function * docs: add note about ssr: false
1 parent a18a79f commit c0d86ea

File tree

10 files changed

+197
-118
lines changed

10 files changed

+197
-118
lines changed

docs/content/en/setup.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ Add `@nuxtjs/pwa` dependency to your project:
1515
<code-block label="Yarn" active>
1616

1717
```bash
18-
yarn add @nuxtjs/pwa
18+
yarn add --dev @nuxtjs/pwa
1919
```
2020

2121
</code-block>
2222
<code-block label="NPM">
2323

2424
```bash
25-
npm i @nuxtjs/pwa
25+
npm i --dev @nuxtjs/pwa
2626
```
2727

2828
</code-block>
@@ -32,12 +32,14 @@ Edit your `nuxt.config.js` file to add pwa module::
3232

3333
```js{}[nuxt.config.js]
3434
{
35-
modules: [
35+
buildModules: [
3636
'@nuxtjs/pwa',
3737
]
3838
}
3939
```
4040

41+
**NOTE:** If using `ssr: false` with production mode without `nuxt generate`, you have to use `modules` instead of `buildModules`
42+
4143
### Add Icon
4244

4345
Ensure `static` dir exists and optionally create `static/icon.png`. (Recommended to be square png and >= `512x512px`)

lib/icon/module.js

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,10 @@ const { joinUrl, getRouteParams, sizeName } = require('../utils')
77
const { version } = require('../../package.json')
88

99
module.exports = function (pwa) {
10-
this.nuxt.hook('build:before', () => run.call(this, pwa, true))
11-
12-
if (this.options.mode === 'spa' && !this.options.dev) {
13-
return run.call(this, pwa, false) // Fill meta
14-
}
10+
this.nuxt.hook('build:before', () => run.call(this, pwa))
1511
}
1612

17-
async function run (pwa, _emitAssets) {
13+
async function run (pwa) {
1814
const { publicPath } = getRouteParams(this.options)
1915

2016
// Defaults
@@ -92,9 +88,7 @@ async function run (pwa, _emitAssets) {
9288
}
9389

9490
// Emit assets in background
95-
if (_emitAssets) {
96-
emitAssets.call(this, options)
97-
}
91+
emitAssets.call(this, options)
9892
}
9993

10094
async function findIcon (options) {
@@ -120,7 +114,7 @@ function addPlugin (options) {
120114
if (options.plugin) {
121115
this.addPlugin({
122116
src: path.resolve(__dirname, './plugin.js'),
123-
fileName: 'nuxt-icons.js',
117+
fileName: 'pwa/icons.js',
124118
options: {
125119
pluginName: options.pluginName,
126120
icons

lib/manifest/module.js

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,9 @@
11
const hash = require('hasha')
22

3-
const { joinUrl, getRouteParams, find } = require('../utils')
3+
const { joinUrl, getRouteParams } = require('../utils')
44

55
module.exports = function nuxtManifest (pwa) {
6-
const hook = () => {
7-
addManifest.call(this, pwa)
8-
}
9-
10-
if (this.options.mode === 'spa') {
11-
return hook()
12-
}
13-
14-
this.nuxt.hook('build:before', hook)
6+
this.nuxt.hook('build:before', () => addManifest.call(this, pwa))
157
}
168

179
function addManifest (pwa) {
@@ -67,11 +59,9 @@ function addManifest (pwa) {
6759
})
6860

6961
// Add manifest meta
70-
if (!find(this.options.head.link, 'rel', 'manifest')) {
71-
const baseAttribute = { rel: 'manifest', href: joinUrl(options.publicPath, manifestFileName) }
72-
const attribute = manifest.crossorigin ? Object.assign({}, baseAttribute, { crossorigin: manifest.crossorigin }) : baseAttribute
73-
this.options.head.link.push(attribute)
74-
} else {
75-
console.warn('Manifest meta already provided!') // eslint-disable-line no-console
62+
const manifestMeta = { rel: 'manifest', href: joinUrl(options.publicPath, manifestFileName), hid: 'manifest' }
63+
if (manifest.crossorigin) {
64+
manifestMeta.crossorigin = manifest.crossorigin
7665
}
66+
pwa._manifestMeta = manifestMeta
7767
}

lib/meta/meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<%= JSON.stringify(options.head, null, 2) %>

lib/meta/meta.merge.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
exports.mergeMeta = function mergeMeta (to, from) {
2+
if (typeof to === 'function') {
3+
// eslint-disable-next-line no-console
4+
console.warn('Cannot merge meta. Avoid using head as a function!')
5+
return
6+
}
7+
8+
for (const key in from) {
9+
const value = from[key]
10+
if (Array.isArray(value)) {
11+
to[key] = to[key] || []
12+
for (const item of value) {
13+
// Avoid duplicates
14+
if (
15+
(item.hid && hasMeta(to[key], 'hid', item.hid)) ||
16+
(item.name && hasMeta(to[key], 'name', item.name))
17+
) {
18+
continue
19+
}
20+
// Add meta
21+
to[key].push(item)
22+
}
23+
} else if (typeof value === 'object') {
24+
to[key] = to[key] || {}
25+
for (const attr in value) {
26+
to[key][attr] = value[attr]
27+
}
28+
} else if (to[key] === undefined) {
29+
to[key] = value
30+
}
31+
}
32+
}
33+
34+
function hasMeta (arr, key, val) {
35+
return arr.find(obj => val ? obj[key] === val : obj[key])
36+
}

0 commit comments

Comments
 (0)