未验证 提交 ec2ffb42 编写于 作者: J JJ Kasper 提交者: GitHub

Handle css-loader file resolving change (#17724)

This is a follow-up to https://github.com/vercel/next.js/pull/16973 which adds handling for the breaking change in the latest version of css-loader that causes unresolved file references in `url` or `import` to cause the build to fail. This fixes it by adding our own resolve checking and when it fails disabling the `css-loader`'s handling of it. 

Fixes: https://github.com/vercel/next.js/issues/17701
上级 c021662d
export function cssFileResolve(url: string, _resourcePath: string) {
if (url.startsWith('/')) {
return false
}
return true
}
......@@ -2,6 +2,7 @@ import postcss from 'postcss'
import webpack from 'webpack'
import { ConfigurationContext } from '../../../utils'
import { getClientStyleLoader } from './client'
import { cssFileResolve } from './file-resolve'
export function getGlobalCssLoader(
ctx: ConfigurationContext,
......@@ -29,6 +30,9 @@ export function getGlobalCssLoader(
sourceMap: true,
// Next.js controls CSS Modules eligibility:
modules: false,
url: cssFileResolve,
import: (url: string, _: any, resourcePath: string) =>
cssFileResolve(url, resourcePath),
},
})
......
......@@ -2,6 +2,7 @@ import postcss from 'postcss'
import webpack from 'webpack'
import { ConfigurationContext } from '../../../utils'
import { getClientStyleLoader } from './client'
import { cssFileResolve } from './file-resolve'
import { getCssModuleLocalIdent } from './getCssModuleLocalIdent'
export function getCssModuleLoader(
......@@ -30,6 +31,9 @@ export function getCssModuleLoader(
sourceMap: true,
// Use CJS mode for backwards compatibility:
esModule: false,
url: cssFileResolve,
import: (url: string, _: any, resourcePath: string) =>
cssFileResolve(url, resourcePath),
modules: {
// Do not transform class names (CJS mode backwards compatibility):
exportLocalsConvention: 'asIs',
......
p {
background-image: url('/vercel.svg');
}
p:nth-child(1) {
background-image: url(/vercel.svg);
}
/* p:nth-child(2) {
background-image: url('./vercel.svg');
}
p:nth-child(3) {
background-image: url(./vercel.svg);
} */
p:nth-child(4) {
background-image: url('./public/vercel.svg');
}
p:nth-child(5) {
background-image: url(./public/vercel.svg);
}
div {
background-image: url('https://vercel.com/vercel.svg');
}
div:nth-child(1) {
background-image: url('https://vercel.com/vercel.svg');
}
.p {
background-image: url('/vercel.svg');
}
.p:nth-child(1) {
background-image: url(/vercel.svg);
}
// .p:nth-child(2) {
// background-image: url('./vercel.svg');
// }
// .p:nth-child(3) {
// background-image: url(./vercel.svg);
// }
p:nth-child(4) {
background-image: url('./public/vercel.svg');
}
p:nth-child(5) {
background-image: url(./public/vercel.svg);
}
.div {
background-image: url('https://vercel.com/vercel.svg');
}
.div:nth-child(1) {
background-image: url('https://vercel.com/vercel.svg');
}
import '../global.css'
import '../global.scss'
export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
import styles from './another.module.scss'
export default function Page() {
return <p className={styles.first}>Hello from index</p>
}
.first {
background-image: url('/vercel.svg');
}
.first:nth-child(1) {
background-image: url(/vercel.svg);
}
// .first:nth-child(2) {
// background-image: url('./vercel.svg');
// }
// .first:nth-child(3) {
// background-image: url(./vercel.svg);
// }
.first:nth-child(4) {
background-image: url('../public/vercel.svg');
}
.first:nth-child(5) {
background-image: url(../public/vercel.svg);
}
.another {
background-image: url('https://vercel.com/vercel.svg');
}
.another:nth-child(1) {
background-image: url('https://vercel.com/vercel.svg');
}
import styles from './index.module.css'
export default function Page() {
return <p className={styles.first}>Hello from index</p>
}
.first {
background-image: url('/vercel.svg');
}
.first:nth-child(1) {
background-image: url(/vercel.svg);
}
/* .first:nth-child(2) {
background-image: url('./vercel.svg');
}
.first:nth-child(3) {
background-image: url(./vercel.svg);
} */
.first:nth-child(4) {
background-image: url('../public/vercel.svg');
}
.first:nth-child(5) {
background-image: url(../public/vercel.svg);
}
.another {
background-image: url('https://vercel.com/vercel.svg');
}
.another:nth-child(1) {
background-image: url('https://vercel.com/vercel.svg');
}
<svg width="70" height="16" viewBox="0 0 283 64" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/></svg>
......@@ -1532,4 +1532,37 @@ describe('CSS Support', () => {
tests()
})
})
describe('should handle unresolved files gracefully', () => {
const workDir = join(fixturesDir, 'unresolved-css-url')
it('should build correctly', async () => {
await remove(join(workDir, '.next'))
const { code } = await nextBuild(workDir)
expect(code).toBe(0)
})
it('should have correct file references in CSS output', async () => {
const cssFiles = await readdir(join(workDir, '.next/static/css'))
for (const file of cssFiles) {
if (file.endsWith('.css.map')) continue
const content = await readFile(
join(workDir, '.next/static/css', file),
'utf8'
)
console.log(file, content)
// if it is the combined global CSS file there are double the expected
// results
const howMany = content.includes('p{') ? 4 : 2
expect(content.match(/\(\/vercel\.svg/g).length).toBe(howMany)
// expect(content.match(/\(vercel\.svg/g).length).toBe(howMany)
expect(content.match(/\(\/_next\/static\/media/g).length).toBe(2)
expect(content.match(/\(https:\/\//g).length).toBe(howMany)
}
})
})
})
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册