From d9d9545f30073507d57fb06b3d1e9568b4ff56be Mon Sep 17 00:00:00 2001 From: Joe Haddad Date: Tue, 14 Jan 2020 14:53:42 -0500 Subject: [PATCH] Error on CSS in Custom Document (#10091) --- .../build/webpack/config/blocks/css/index.ts | 23 +++++++++++++++++++ .../webpack/config/blocks/css/messages.ts | 6 +++++ .../pages/_document.js | 23 +++++++++++++++++++ .../invalid-module-document/pages/index.js | 3 +++ .../invalid-module-document/styles.module.css | 3 +++ test/integration/css/test/index.test.js | 20 ++++++++++++++++ 6 files changed, 78 insertions(+) create mode 100644 test/integration/css-fixtures/invalid-module-document/pages/_document.js create mode 100644 test/integration/css-fixtures/invalid-module-document/pages/index.js create mode 100644 test/integration/css-fixtures/invalid-module-document/styles.module.css diff --git a/packages/next/build/webpack/config/blocks/css/index.ts b/packages/next/build/webpack/config/blocks/css/index.ts index c169b904d25e..ef8fb5a60185 100644 --- a/packages/next/build/webpack/config/blocks/css/index.ts +++ b/packages/next/build/webpack/config/blocks/css/index.ts @@ -6,6 +6,7 @@ import { loader, plugin } from '../../helpers' import { ConfigurationContext, ConfigurationFn, pipe } from '../../utils' import { getCssModuleLocalIdent } from './getCssModuleLocalIdent' import { + getCustomDocumentError, getGlobalImportError, getGlobalModuleImportError, getLocalModuleImportError, @@ -130,6 +131,28 @@ export const css = curry(async function css( // function argument. true ) + + // CSS cannot be imported in _document. This comes before everything because + // global CSS nor CSS modules work in said file. + fns.push( + loader({ + oneOf: [ + { + test: /\.css$/, + // Use a loose regex so we don't have to crawl the file system to + // find the real file name (if present). + issuer: { test: /pages[\\/]_document\./ }, + use: { + loader: 'error-loader', + options: { + reason: getCustomDocumentError(), + }, + }, + }, + ], + }) + ) + // CSS Modules support must be enabled on the server and client so the class // names are availble for SSR or Prerendering. fns.push( diff --git a/packages/next/build/webpack/config/blocks/css/messages.ts b/packages/next/build/webpack/config/blocks/css/messages.ts index 4a7703ad464f..40878a6b41cf 100644 --- a/packages/next/build/webpack/config/blocks/css/messages.ts +++ b/packages/next/build/webpack/config/blocks/css/messages.ts @@ -25,3 +25,9 @@ export function getLocalModuleImportError() { 'node_modules' )}.\nRead more: https://err.sh/next.js/css-modules-npm` } + +export function getCustomDocumentError() { + return `CSS ${chalk.bold('cannot')} be imported within ${chalk.cyan( + 'pages/_document.js' + )}. Please move global styles to ${chalk.cyan('pages/_app.js')}.` +} diff --git a/test/integration/css-fixtures/invalid-module-document/pages/_document.js b/test/integration/css-fixtures/invalid-module-document/pages/_document.js new file mode 100644 index 000000000000..7bcd5eb23ad0 --- /dev/null +++ b/test/integration/css-fixtures/invalid-module-document/pages/_document.js @@ -0,0 +1,23 @@ +import Document, { Head, Html, Main, NextScript } from 'next/document' +import styles from '../styles.module.css' + +class MyDocument extends Document { + static async getInitialProps(ctx) { + const initialProps = await Document.getInitialProps(ctx) + return { ...initialProps } + } + + render() { + return ( + + + +
+ + + + ) + } +} + +export default MyDocument diff --git a/test/integration/css-fixtures/invalid-module-document/pages/index.js b/test/integration/css-fixtures/invalid-module-document/pages/index.js new file mode 100644 index 000000000000..08fe48e9b56c --- /dev/null +++ b/test/integration/css-fixtures/invalid-module-document/pages/index.js @@ -0,0 +1,3 @@ +export default function Home() { + return
Hello
+} diff --git a/test/integration/css-fixtures/invalid-module-document/styles.module.css b/test/integration/css-fixtures/invalid-module-document/styles.module.css new file mode 100644 index 000000000000..8e1524022baf --- /dev/null +++ b/test/integration/css-fixtures/invalid-module-document/styles.module.css @@ -0,0 +1,3 @@ +.red-text { + color: red; +} diff --git a/test/integration/css/test/index.test.js b/test/integration/css/test/index.test.js index 531c448ba458..8d2b401e62a5 100644 --- a/test/integration/css/test/index.test.js +++ b/test/integration/css/test/index.test.js @@ -205,6 +205,26 @@ describe('CSS Support', () => { }) }) + describe('Invalid CSS in _document', () => { + const appDir = join(fixturesDir, 'invalid-module-document') + + beforeAll(async () => { + await remove(join(appDir, '.next')) + }) + + it('should fail to build', async () => { + const { stderr } = await nextBuild(appDir, [], { + stderr: true, + }) + expect(stderr).toContain('Failed to compile') + expect(stderr).toContain('styles.module.css') + expect(stderr).toMatch( + /CSS.*cannot.*be imported within.*pages[\\/]_document\.js/ + ) + expect(stderr).toMatch(/Location:.*pages[\\/]_document\.js/) + }) + }) + describe('Invalid Global CSS', () => { const appDir = join(fixturesDir, 'invalid-global')