Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error on CSS in Custom Document #10091

Merged
merged 3 commits into from Jan 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 23 additions & 0 deletions packages/next/build/webpack/config/blocks/css/index.ts
Expand Up @@ -6,6 +6,7 @@ import { loader, plugin } from '../../helpers'
import { ConfigurationContext, ConfigurationFn, pipe } from '../../utils'
import { getCssModuleLocalIdent } from './getCssModuleLocalIdent'
import {
getCustomDocumentError,
getGlobalImportError,
getGlobalModuleImportError,
getLocalModuleImportError,
Expand Down Expand Up @@ -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(
Expand Down
6 changes: 6 additions & 0 deletions packages/next/build/webpack/config/blocks/css/messages.ts
Expand Up @@ -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')}.`
}
@@ -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 (
<Html>
<Head />
<body className={styles['red-text']}>
<Main />
<NextScript />
</body>
</Html>
)
}
}

export default MyDocument
@@ -0,0 +1,3 @@
export default function Home() {
return <div>Hello</div>
}
@@ -0,0 +1,3 @@
.red-text {
color: red;
}
20 changes: 20 additions & 0 deletions test/integration/css/test/index.test.js
Expand Up @@ -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')

Expand Down