Skip to content

Commit

Permalink
Added NextScript component (#101)
Browse files Browse the repository at this point in the history
* Added NextScriptDeferred component that allows you to import scripts with defer instead of async in _document.js.

* Add mode

* add missing files
  • Loading branch information
markbrocato authored Jun 9, 2020
1 parent 4e29c0e commit d3624bc
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-storefront",
"version": "8.7.3",
"version": "8.8.0",
"description": "Build and deploy e-commerce progressive web apps (PWAs) in record time.",
"module": "./index.js",
"license": "Apache-2.0",
Expand Down
30 changes: 30 additions & 0 deletions src/NextScript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react'
import { NextScript as OriginalNextScript } from 'next/document'
import PropTypes from 'prop-types'

/**
* A replacement for NextScript from `next/document` that gives you greater control over how script elements are rendered.
* This should be used in the body of `pages/_document.js` in place of `NextScript`.
*/
export default class NextScript extends OriginalNextScript {
static propTypes = {
/**
* Set to `defer` to use `defer` instead of `async` when rendering script elements.
*/
mode: PropTypes.oneOf(['async', 'defer']),
}

static defaultProps = {
mode: 'async',
}

getScripts() {
return super.getScripts().map(script => {
return React.cloneElement(script, {
key: script.props.src,
defer: this.props.mode === 'defer' ? true : undefined,
async: this.props.mode === 'async' ? true : undefined,
})
})
}
}
38 changes: 38 additions & 0 deletions test/NextScript.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React, { Component } from 'react'
import { mount } from 'enzyme'

describe('NextScriptDeferred', () => {
let NextScript

beforeEach(() => {
jest.isolateModules(() => {
jest.doMock('next/document', () => ({
NextScript: class OriginalNextScript extends Component {
getScripts() {
return [<script src="foo.js" async />]
}

render() {
return <>{this.getScripts()}</>
}
},
}))

NextScript = require('react-storefront/NextScript').default
})
})

it('should remove async and add defer to all script tags returned from super.getScripts', () => {
const wrapper = mount(<NextScript mode="defer" />)
const scriptProps = wrapper.find('script').props()
expect(scriptProps.async).toBe(undefined)
expect(scriptProps.defer).toBe(true)
})

it('should use async by default', () => {
const wrapper = mount(<NextScript />)
const scriptProps = wrapper.find('script').props()
expect(scriptProps.async).toBe(true)
expect(scriptProps.defer).toBe(undefined)
})
})

0 comments on commit d3624bc

Please sign in to comment.