Skip to content

Commit

Permalink
feat(gatsby-ssr): Added the ability to exclude files that get removed.
Browse files Browse the repository at this point in the history
  • Loading branch information
itmayziii committed Jun 27, 2019
1 parent b3ac5e4 commit 395d4a1
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 34 deletions.
46 changes: 23 additions & 23 deletions src/fake-data.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const scriptsData = [
]

export const headComponentsData = [
{
{ // 0
type: 'style',
key: null,
ref: null,
Expand All @@ -21,21 +21,21 @@ export const headComponentsData = [
},
_owner: null
},
{
{ // 1
type: 'meta',
key: 'generator-2.6.0',
ref: null,
props: { name: 'generator', content: 'Gatsby 2.6.0' },
_owner: null
},
[{
[{ // 2
type: 'title',
key: 'Your Pickup Request Has Been Received | Budget Dumpster ',
ref: null,
props: {},
_owner: null
}],
[{
[{ // 3
type: 'link',
key: '0',
ref: null,
Expand All @@ -49,35 +49,35 @@ export const headComponentsData = [
props: {},
_owner: null
}],
[{
[{ // 4
type: 'meta',
key: '0',
ref: null,
props: {},
_owner: null
}],
{
{ // 5
type: 'script',
key: 'plugin-google-tagmanager',
ref: null,
props: { dangerouslySetInnerHTML: {} },
_owner: null
},
{
{ // 6
type: 'script',
key: 'invoca',
ref: null,
props: { dangerouslySetInnerHTML: {} },
_owner: null
},
[{
[{ // 7
type: 'title',
key: '',
ref: null,
props: {},
_owner: null
}],
{
{ // 8
type: 'link',
key: 'styles-fc78e7c610cb29615a01.js',
ref: null,
Expand All @@ -89,7 +89,7 @@ export const headComponentsData = [
},
_owner: null
},
{
{ // 9
type: 'link',
key: 'component---src-pages-schedule-a-pickup-php-js-a6d963769d2dc276611e.js',
ref: null,
Expand All @@ -101,7 +101,7 @@ export const headComponentsData = [
},
_owner: null
},
{
{ // 10
type: 'link',
key: '3-026f7b22973cd8a93202.js',
ref: null,
Expand All @@ -113,7 +113,7 @@ export const headComponentsData = [
},
_owner: null
},
{
{ // 11
type: 'link',
key: '1-aff5fb503cf05cb46096.js',
ref: null,
Expand All @@ -125,7 +125,7 @@ export const headComponentsData = [
},
_owner: null
},
{
{ // 12
type: 'link',
key: 'app-9df10a4ee487889eb94f.js',
ref: null,
Expand All @@ -137,7 +137,7 @@ export const headComponentsData = [
},
_owner: null
},
{
{ // 13
type: 'link',
key: 'webpack-runtime-d53148f285188e47861c.js',
ref: null,
Expand All @@ -149,7 +149,7 @@ export const headComponentsData = [
},
_owner: null
},
{
{ // 14
type: 'link',
key: '/static/d/991/path---schedule-a-pickup-thank-you-php-7-b-9-bc7-0SUcWyAf8ecbYDsMhQkEfPzV8.json',
ref: null,
Expand All @@ -165,14 +165,14 @@ export const headComponentsData = [
]

export const postBodyComponentsData = [
{
{ // 0
type: 'script',
key: 'google-auto-complete',
ref: null,
props: { defer: true, src: 'https://maps.googleapis.com/maps/api/js?key=&libraries=places' },
_owner: null
},
{
{ // 1
type: 'script',
key: 'script-loader',
ref: null,
Expand All @@ -183,7 +183,7 @@ export const postBodyComponentsData = [
},
_owner: null
},
{
{ // 2
type: 'script',
key: 'chunk-mapping',
ref: null,
Expand All @@ -194,35 +194,35 @@ export const postBodyComponentsData = [
},
_owner: null
},
{
{ // 3
type: 'script',
key: '/webpack-runtime-d53148f285188e47861c.js',
ref: null,
props: { src: '/webpack-runtime-d53148f285188e47861c.js', async: true },
_owner: null
},
{
{ // 4
type: 'script',
key: '/app-9df10a4ee487889eb94f.js',
ref: null,
props: { src: '/app-9df10a4ee487889eb94f.js', async: true },
_owner: null
},
{
{ // 5
type: 'script',
key: '/1-aff5fb503cf05cb46096.js',
ref: null,
props: { src: '/1-aff5fb503cf05cb46096.js', async: true },
_owner: null
},
{
{ // 6
type: 'script',
key: '/3-026f7b22973cd8a93202.js',
ref: null,
props: { src: '/3-026f7b22973cd8a93202.js', async: true },
_owner: null
},
{
{ // 7
type: 'script',
key: '/component---src-pages-schedule-a-pickup-php-js-a6d963769d2dc276611e.js',
ref: null,
Expand Down
38 changes: 32 additions & 6 deletions src/gatsby-ssr.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,23 @@ describe('gatsby-ssr.js', () => {
return []
}

onPreRenderHTML({ getHeadComponents, replaceHeadComponents: replaceHeadComponentsSpy, getPostBodyComponents, replacePostBodyComponents: replacePostBodyComponentsSpy })
onPreRenderHTML({ getHeadComponents, replaceHeadComponents: replaceHeadComponentsSpy, getPostBodyComponents, replacePostBodyComponents: replacePostBodyComponentsSpy }, {})
expect(replaceHeadComponentsSpy).toHaveBeenCalledWith([headComponentsData[2], headComponentsData[3]])
})

it('does not remove scripts in the head marked as excluded from plugin options', () => {
onRenderBody({ scripts: scriptsData })
function getHeadComponents () {
return [headComponentsData[13]]
}
function getPostBodyComponents () {
return []
}

onPreRenderHTML({ getHeadComponents, replaceHeadComponents: replaceHeadComponentsSpy, getPostBodyComponents, replacePostBodyComponents: replacePostBodyComponentsSpy }, { exclude: /webpack-runtime/ })
expect(replaceHeadComponentsSpy).toHaveBeenCalledWith([headComponentsData[13]])
})

it('should remove static files like JSON from the head as these files are always added by Gatsby', () => {
onRenderBody({ scripts: [] })
function getHeadComponents () {
Expand All @@ -39,7 +52,7 @@ describe('gatsby-ssr.js', () => {
return []
}

onPreRenderHTML({ getHeadComponents, replaceHeadComponents: replaceHeadComponentsSpy, getPostBodyComponents, replacePostBodyComponents: replacePostBodyComponentsSpy })
onPreRenderHTML({ getHeadComponents, replaceHeadComponents: replaceHeadComponentsSpy, getPostBodyComponents, replacePostBodyComponents: replacePostBodyComponentsSpy }, {})
expect(replaceHeadComponentsSpy).toHaveBeenCalledWith([headComponentsData[0], headComponentsData[1]])
})

Expand All @@ -56,7 +69,7 @@ describe('gatsby-ssr.js', () => {
return []
}

onPreRenderHTML({ getHeadComponents, replaceHeadComponents: replaceHeadComponentsSpy, getPostBodyComponents, replacePostBodyComponents: replacePostBodyComponentsSpy })
onPreRenderHTML({ getHeadComponents, replaceHeadComponents: replaceHeadComponentsSpy, getPostBodyComponents, replacePostBodyComponents: replacePostBodyComponentsSpy }, {})
expect(replaceHeadComponentsSpy).toHaveBeenCalledTimes(1)
expect(replaceHeadComponentsSpy.calls.argsFor(0)[0].length).toEqual(2)
expect(replaceHeadComponentsSpy).toHaveBeenCalledWith([headComponentsData[0], headComponentsData[1]])
Expand All @@ -80,10 +93,23 @@ describe('gatsby-ssr.js', () => {
return fakeBodyComponents
}

onPreRenderHTML({ getHeadComponents, replaceHeadComponents: replaceHeadComponentsSpy, getPostBodyComponents, replacePostBodyComponents: replacePostBodyComponentsSpy })
onPreRenderHTML({ getHeadComponents, replaceHeadComponents: replaceHeadComponentsSpy, getPostBodyComponents, replacePostBodyComponents: replacePostBodyComponentsSpy }, {})
expect(replacePostBodyComponentsSpy).toHaveBeenCalledWith(fakeBodyComponents)
})

it('does not remove scripts in the body marked as excluded from plugin options', () => {
onRenderBody({ scripts: scriptsData })
function getHeadComponents () {
return []
}
function getPostBodyComponents () {
return [postBodyComponentsData[3]]
}

onPreRenderHTML({ getHeadComponents, replaceHeadComponents: replaceHeadComponentsSpy, getPostBodyComponents, replacePostBodyComponents: replacePostBodyComponentsSpy }, { exclude: /webpack-runtime/ })
expect(replacePostBodyComponentsSpy).toHaveBeenCalledWith([postBodyComponentsData[3]])
})

it('should remove special Gatsby scripts from the body', () => {
onRenderBody({ scripts: [] })
function getHeadComponents () {
Expand All @@ -93,7 +119,7 @@ describe('gatsby-ssr.js', () => {
return [postBodyComponentsData[0], postBodyComponentsData[1], postBodyComponentsData[2]]
}

onPreRenderHTML({ getHeadComponents, replaceHeadComponents: replaceHeadComponentsSpy, getPostBodyComponents, replacePostBodyComponents: replacePostBodyComponentsSpy })
onPreRenderHTML({ getHeadComponents, replaceHeadComponents: replaceHeadComponentsSpy, getPostBodyComponents, replacePostBodyComponents: replacePostBodyComponentsSpy }, {})
expect(replacePostBodyComponentsSpy).toHaveBeenCalledWith([postBodyComponentsData[0]])
})

Expand All @@ -107,7 +133,7 @@ describe('gatsby-ssr.js', () => {
return [postBodyComponentsData[0], postBodyComponentsData[3], postBodyComponentsData[4], postBodyComponentsData[5], postBodyComponentsData[6], postBodyComponentsData[7]]
}

onPreRenderHTML({ getHeadComponents, replaceHeadComponents: replaceHeadComponentsSpy, getPostBodyComponents, replacePostBodyComponents: replacePostBodyComponentsSpy })
onPreRenderHTML({ getHeadComponents, replaceHeadComponents: replaceHeadComponentsSpy, getPostBodyComponents, replacePostBodyComponents: replacePostBodyComponentsSpy }, {})
expect(replacePostBodyComponentsSpy).toHaveBeenCalledTimes(1)
expect(replacePostBodyComponentsSpy.calls.argsFor(0)[0].length).toEqual(1)
expect(replacePostBodyComponentsSpy).toHaveBeenCalledWith([postBodyComponentsData[0]])
Expand Down
22 changes: 17 additions & 5 deletions src/gatsby-ssr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ export interface Script {
rel: string
}

export interface PluginOptions {
exclude?: RegExp | string
}

let pageScripts: Script[]

/*
Expand All @@ -32,18 +36,22 @@ export function onRenderBody ({ scripts }: OnRenderBodyArgs) {
}

// Here we rely on the fact that onPreRenderHTML is called after onRenderBody so we have access to the scripts Gatsby inserted into the HTML.
export function onPreRenderHTML ({ getHeadComponents, replaceHeadComponents, getPostBodyComponents, replacePostBodyComponents }: OnPreRenderHTMLArgs) {
replaceHeadComponents(getHeadComponentsNoJS(getHeadComponents()))
replacePostBodyComponents(getPostBodyComponentsNoJS(getPostBodyComponents()))
export function onPreRenderHTML ({ getHeadComponents, replaceHeadComponents, getPostBodyComponents, replacePostBodyComponents }: OnPreRenderHTMLArgs, pluginOptions: PluginOptions) {
replaceHeadComponents(getHeadComponentsNoJS(getHeadComponents(), pluginOptions))
replacePostBodyComponents(getPostBodyComponentsNoJS(getPostBodyComponents(), pluginOptions))
}

function getHeadComponentsNoJS (headComponents: ReactNode[]): ReactNode[] {
function getHeadComponentsNoJS (headComponents: ReactNode[], pluginOptions: PluginOptions): ReactNode[] {
return headComponents.filter((headComponent) => {
// Not a react component and therefore not a <script>.
if (!isReactElement(headComponent)) {
return true
}

if (pluginOptions.exclude && RegExp(pluginOptions.exclude).test(headComponent.props.href)) {
return true
}

// Gatsby puts JSON files in the head that should also be removed if javascript is removed, all these Gatsby files are in the "/static" directory.
if (headComponent.props.href && headComponent.props.href.startsWith('/static/')) {
return false
Expand All @@ -57,13 +65,17 @@ function getHeadComponentsNoJS (headComponents: ReactNode[]): ReactNode[] {
})
}

function getPostBodyComponentsNoJS (postBodyComponents: ReactNode[]): ReactNode[] {
function getPostBodyComponentsNoJS (postBodyComponents: ReactNode[], pluginOptions: PluginOptions): ReactNode[] {
return postBodyComponents.filter((postBodyComponent) => {
// Not a react component and therefore not a <script>.
if (!isReactElement(postBodyComponent)) {
return true
}

if (pluginOptions.exclude && RegExp(pluginOptions.exclude).test(postBodyComponent.props.src)) {
return true
}

// These are special Gatsby files we are calling out specifically.
if (postBodyComponent.props.id && (postBodyComponent.props.id === 'gatsby-script-loader' || postBodyComponent.props.id === 'gatsby-chunk-mapping')) {
return false
Expand Down

0 comments on commit 395d4a1

Please sign in to comment.