From 695f372da9871b1cc246ed4b6a61e2a504af0346 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 14 Sep 2018 11:34:08 +0200 Subject: [PATCH] Compile away next/link proptypes in production (#5155) This saves 7KB as prop-types-exact is not needed in production. --- build/webpack.js | 9 +++++++++ lib/error.js | 10 ++++++---- lib/link.js | 49 +++++++++++++++++++++++++----------------------- 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/build/webpack.js b/build/webpack.js index 3fa51d75..bfa78d2b 100644 --- a/build/webpack.js +++ b/build/webpack.js @@ -245,6 +245,15 @@ export default async function getBaseWebpackConfig (dir: string, {dev = false, i }), dev && !isServer && new FriendlyErrorsWebpackPlugin(), new webpack.IgnorePlugin(/(precomputed)/, /node_modules.+(elliptic)/), + // This removes prop-types-exact in production, as it's not used there. + !dev && new webpack.IgnorePlugin({ + checkResource: (resource) => { + return /prop-types-exact/.test(resource) + }, + checkContext: (context) => { + return context.indexOf(NEXT_PROJECT_ROOT_DIST) !== -1 + } + }), // Even though require.cache is server only we have to clear assets from both compilations // This is because the client compilation generates the build manifest that's used on the server side dev && new NextJsRequireCacheHotReloader(), diff --git a/lib/error.js b/lib/error.js index c5a5ce3f..9d22f02f 100644 --- a/lib/error.js +++ b/lib/error.js @@ -9,10 +9,6 @@ export default class Error extends React.Component { return { statusCode } } - static propTypes = { - statusCode: PropTypes.number - } - render () { const { statusCode } = this.props const title = statusCode === 404 @@ -35,6 +31,12 @@ export default class Error extends React.Component { } } +if (process.env.NODE_ENV === 'development') { + Error.propTypes = { + statusCode: PropTypes.number + } +} + const styles = { error: { color: '#000', diff --git a/lib/link.js b/lib/link.js index d9897847..edf986ab 100644 --- a/lib/link.js +++ b/lib/link.js @@ -3,7 +3,6 @@ import { resolve, format, parse } from 'url' import React, { Component, Children } from 'react' import PropTypes from 'prop-types' -import exact from 'prop-types-exact' import Router, { _rewriteUrlForNextExport } from './router' import { warn, execOnce, getLocationOrigin } from './utils' @@ -35,28 +34,6 @@ function memoizedFormatUrl (formatUrl) { } class Link extends Component { - static propTypes = exact({ - href: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired, - as: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), - prefetch: PropTypes.bool, - replace: PropTypes.bool, - shallow: PropTypes.bool, - passHref: PropTypes.bool, - scroll: PropTypes.bool, - children: PropTypes.oneOfType([ - PropTypes.element, - (props, propName) => { - const value = props[propName] - - if (typeof value === 'string') { - warnLink(`Warning: You're using a string directly inside . This usage has been deprecated. Please add an tag as child of `) - } - - return null - } - ]).isRequired - }) - componentDidMount () { this.prefetch() } @@ -177,4 +154,30 @@ class Link extends Component { } } +if (process.env.NODE_ENV === 'development') { + // This module gets removed by webpack.IgnorePlugin + const exact = require('prop-types-exact') + Link.propTypes = exact({ + href: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired, + as: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), + prefetch: PropTypes.bool, + replace: PropTypes.bool, + shallow: PropTypes.bool, + passHref: PropTypes.bool, + scroll: PropTypes.bool, + children: PropTypes.oneOfType([ + PropTypes.element, + (props, propName) => { + const value = props[propName] + + if (typeof value === 'string') { + warnLink(`Warning: You're using a string directly inside . This usage has been deprecated. Please add an tag as child of `) + } + + return null + } + ]).isRequired + }) +} + export default Link