Skip to content

Commit

Permalink
Improve Sass Error (#10982)
Browse files Browse the repository at this point in the history
* Improve Sass Error

* test sass error massage

* use quotes

Co-authored-by: JJ Kasper <jj@jjsweb.site>
  • Loading branch information
Timer and ijjk committed Mar 11, 2020
1 parent e52048d commit 9d9f7a5
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 11 deletions.
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)
17 changes: 12 additions & 5 deletions packages/next/client/dev/error-overlay/format-webpack-messages.js
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

0 comments on commit 9d9f7a5

Please sign in to comment.