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 c169b904d25ed..ef8fb5a60185a 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 4a7703ad464fc..40878a6b41cf7 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 0000000000000..7bcd5eb23ad07
--- /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 0000000000000..08fe48e9b56c8
--- /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 0000000000000..8e1524022baf8
--- /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 531c448ba4586..8d2b401e62a54 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')