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

Improve Sass Error #10982

Merged
merged 5 commits into from Mar 11, 2020
Merged
Show file tree
Hide file tree
Changes from 3 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
19 changes: 19 additions & 0 deletions errors/install-sass.md
@@ -0,0 +1,19 @@
# Install `sass` to Use Built-In Sass Support

#### Why This Error Occurred

Using Next.js' [built-in Sass support](https://nextjs.org/docs/basic-features/built-in-css-support#sass-support) requires that you bring your own version of Sass.

#### Possible Ways to Fix It

Please install the `sass` package in your project.

```bash
npm i sass
# or
yarn add sass
```

### Useful Links

- [Sass Support in Documentation](https://nextjs.org/docs/basic-features/built-in-css-support#sass-support)
Expand Up @@ -31,8 +31,7 @@ function isLikelyASyntaxError(message) {
}

// Cleans up webpack error messages.
// eslint-disable-next-line no-unused-vars
function formatMessage(message, isError) {
function formatMessage(message) {
let lines = message.split('\n')

// Strip Webpack-added headers off errors/warnings
Expand All @@ -58,9 +57,6 @@ function formatMessage(message, isError) {
/SyntaxError\s+\((\d+):(\d+)\)\s*(.+?)\n/g,
`${friendlySyntaxErrorLabel} $3 ($1:$2)\n`
)
// Remove columns from ESLint formatter output (we added these for more
// accurate syntax errors)
message = message.replace(/Line (\d+):\d+:/g, 'Line $1:')
// Clean up export errors
message = message.replace(
/^.*export '(.+?)' was not found in '(.+?)'.*$/gm,
Expand Down Expand Up @@ -93,6 +89,17 @@ function formatMessage(message, isError) {
]
}

// Add helpful message for users trying to use Sass for the first time
if (lines[1] && lines[1].match(/Cannot find module.+node-sass/)) {
// ./file.module.scss (<<loader info>>) => ./file.module.scss
lines[0] = lines[0].replace(/(.+) \(.+?(?=\?\?).+?\)/, '$1')

lines[1] =
"To use Next.js' built-in Sass support, you first need to install `sass`.\n"
lines[1] += 'Run `npm i sass` or `yarn add sass` inside your workspace.\n'
lines[1] += '\nLearn more: https://err.sh/next.js/install-sass'
}

message = lines.join('\n')
// Internal stacks are generally useless so we strip them... with the
// exception of stacks containing `webpack:` because they're normally
Expand Down
7 changes: 7 additions & 0 deletions test/integration/scss-fixtures/webpack-error/mock.js
@@ -0,0 +1,7 @@
let originalLoader
const M = require('module')
originalLoader = M._load
M._load = function hookedLoader(request, parent, isMain) {
if (request === 'node-sass') request = 'node-sass-begone'
return originalLoader(request, parent, isMain)
}
12 changes: 12 additions & 0 deletions test/integration/scss-fixtures/webpack-error/pages/_app.js
@@ -0,0 +1,12 @@
import React from 'react'
import App from 'next/app'
import '../styles/global.scss'

class MyApp extends App {
render() {
const { Component, pageProps } = this.props
return <Component {...pageProps} />
}
}

export default MyApp
3 changes: 3 additions & 0 deletions test/integration/scss-fixtures/webpack-error/pages/index.js
@@ -0,0 +1,3 @@
export default function Home() {
return <div className="red-text">This text should be red.</div>
}
@@ -0,0 +1,4 @@
$var: red;
.red-text {
color: $var;
}
41 changes: 35 additions & 6 deletions test/integration/scss/test/index.test.js
@@ -1,26 +1,55 @@
/* eslint-env jest */
/* global jasmine */
import cheerio from 'cheerio'
import 'flat-map-polyfill'
import { join } from 'path'
import { readdir, readFile, remove } from 'fs-extra'
import {
File,
findPort,
killApp,
launchApp,
nextBuild,
nextStart,
launchApp,
killApp,
File,
waitFor,
renderViaHTTP,
waitFor,
} from 'next-test-utils'
import webdriver from 'next-webdriver'
import cheerio from 'cheerio'
import { join } from 'path'
import { quote as shellQuote } from 'shell-quote'

jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 2

const fixturesDir = join(__dirname, '../..', 'scss-fixtures')

describe('SCSS Support', () => {
describe('Friendly Webpack Error', () => {
const appDir = join(fixturesDir, 'webpack-error')

const mockFile = join(appDir, 'mock.js')

beforeAll(async () => {
await remove(join(appDir, '.next'))
})

it('should be a friendly error successfully', async () => {
const { code, stderr } = await nextBuild(appDir, [], {
env: { NODE_OPTIONS: shellQuote([`--require`, mockFile]) },
stderr: true,
})
expect(code).toBe(1)
expect(stderr.split('Require stack:')[0]).toMatchInlineSnapshot(`
"Failed to compile.

./styles/global.scss
To use Next.js' built-in Sass support, you first need to install \`sass\`.
Run \`npm i sass\` or \`yarn add sass\` inside your workspace.

Learn more: https://err.sh/next.js/install-sass
"
`)
})
})

describe('Basic Global Support', () => {
const appDir = join(fixturesDir, 'single-global')

Expand Down