Skip to content

Commit

Permalink
Add Support for CSS Module Value Imports (vercel#16973)
Browse files Browse the repository at this point in the history
  • Loading branch information
Timer authored and Piotr Bosak committed Sep 26, 2020
1 parent 4ccc659 commit 7e22009
Show file tree
Hide file tree
Showing 13 changed files with 127 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ export function getGlobalCssLoader(
// Resolve CSS `@import`s and `url()`s
loaders.push({
loader: require.resolve('css-loader'),
options: { importLoaders: 1 + preProcessors.length, sourceMap: true },
options: {
importLoaders: 1 + preProcessors.length,
sourceMap: true,
// Next.js controls CSS Modules eligibility:
modules: false,
},
})

// Compile CSS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,13 @@ export function getCssModuleLoader(
options: {
importLoaders: 1 + preProcessors.length,
sourceMap: true,
onlyLocals: ctx.isServer,
// Use CJS mode for backwards compatibility:
esModule: false,
modules: {
// Do not transform class names (CJS mode backwards compatibility):
exportLocalsConvention: 'asIs',
// Server-side (Node.js) rendering support:
exportOnlyLocals: ctx.isServer,
// Disallow global style exports so we can code-split CSS and
// not worry about loading order.
mode: 'pure',
Expand Down
2 changes: 1 addition & 1 deletion packages/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
"caniuse-lite": "^1.0.30001113",
"chokidar": "2.1.8",
"crypto-browserify": "3.12.0",
"css-loader": "3.5.3",
"css-loader": "4.3.0",
"cssnano-simple": "1.2.0",
"find-cache-dir": "3.3.1",
"jest-worker": "24.9.0",
Expand Down
2 changes: 1 addition & 1 deletion test/acceptance/ReactRefreshLogBox.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,7 @@ test('css syntax errors', async () => {
Syntax error: Selector \\"button\\" is not pure (pure selectors must contain at least one local class or id)
> 1 | button {}
| ^"
| ^"
`)

await cleanup()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"browserslist": [
"last 1 chrome version"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
:export {
w1: #ffffff;
b1: #000000;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import styles from './styles.module.css'

export default function () {
return <div>{JSON.stringify(styles)}</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@value b1 from "./colors.module.css";

.blk {
color: b1;
}
32 changes: 32 additions & 0 deletions test/integration/css-features/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,35 @@ describe('CSS Modules: Importing Invalid Global CSS', () => {
expect(stderr).toContain('Selector "a" is not pure')
})
})

describe('CSS Modules: Import Exports', () => {
const appDir = join(fixturesDir, 'module-import-exports')

let stdout
let code
beforeAll(async () => {
await remove(join(appDir, '.next'))
;({ code, stdout } = await nextBuild(appDir, [], {
stdout: true,
}))
})

it('should have compiled successfully', () => {
expect(code).toBe(0)
expect(stdout).toMatch(/Compiled successfully/)
})

it(`should've emitted a single CSS file`, async () => {
const cssFolder = join(appDir, '.next/static/css')

const files = await readdir(cssFolder)
const cssFiles = files.filter((f) => /\.css$/.test(f))

expect(cssFiles.length).toBe(1)
const cssContent = await readFile(join(cssFolder, cssFiles[0]), 'utf8')

expect(cssContent.replace(/\/\*.*?\*\//g, '').trim()).toMatchInlineSnapshot(
`".styles_blk__2ns7r{color:#000}"`
)
})
})
2 changes: 1 addition & 1 deletion test/integration/css-modules/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ describe('Valid Nested CSS Module Usage from within node_modules', () => {
const cssContent = await readFile(join(cssFolder, cssFiles[0]), 'utf8')

expect(cssContent.replace(/\/\*.*?\*\//g, '').trim()).toMatchInlineSnapshot(
`".other3_other3__1f9h7{color:violet}.other_className__bt_-E{background:red;color:#ff0}.other2_other2__2PUfY{color:red}.example_subClass__2YUgj{background:#00f}"`
`".other2_other2__2PUfY{color:red}.other3_other3__1f9h7{color:violet}.other_className__bt_-E{background:red;color:#ff0}.example_subClass__2YUgj{background:#00f}"`
)
})
})
Expand Down
8 changes: 4 additions & 4 deletions test/integration/css/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -737,7 +737,7 @@ describe('CSS Support', () => {
})
})

describe('Bad CSS Import from node_modules', () => {
describe('CSS Import from node_modules', () => {
const appDir = join(fixturesDir, 'npm-import-bad')

beforeAll(async () => {
Expand All @@ -747,9 +747,9 @@ describe('CSS Support', () => {
it('should fail the build', async () => {
const { code, stderr } = await nextBuild(appDir, [], { stderr: true })

expect(code).not.toBe(0)
expect(stderr).toMatch(/Can't resolve '[^']*?nprogress[^']*?'/)
expect(stderr).toMatch(/Build error occurred/)
expect(code).toBe(0)
expect(stderr).not.toMatch(/Can't resolve '[^']*?nprogress[^']*?'/)
expect(stderr).not.toMatch(/Build error occurred/)
})
})

Expand Down
8 changes: 4 additions & 4 deletions test/integration/scss/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ describe('SCSS Support', () => {
})
})

describe('Bad CSS Import from node_modules', () => {
describe('CSS Import from node_modules', () => {
const appDir = join(fixturesDir, 'npm-import-bad')

beforeAll(async () => {
Expand All @@ -819,9 +819,9 @@ describe('SCSS Support', () => {
it('should fail the build', async () => {
const { code, stderr } = await nextBuild(appDir, [], { stderr: true })

expect(code).not.toBe(0)
expect(stderr).toMatch(/Can't resolve '[^']*?nprogress[^']*?'/)
expect(stderr).toMatch(/Build error occurred/)
expect(code).toBe(0)
expect(stderr).not.toMatch(/Can't resolve '[^']*?nprogress[^']*?'/)
expect(stderr).not.toMatch(/Build error occurred/)
})
})

Expand Down
71 changes: 53 additions & 18 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3202,6 +3202,11 @@
version "7.0.4"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339"

"@types/json-schema@^7.0.5":
version "7.0.6"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0"
integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==

"@types/json5@0.0.30":
version "0.0.30"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.30.tgz#44cb52f32a809734ca562e685c6473b5754a7818"
Expand Down Expand Up @@ -3805,6 +3810,11 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da"

ajv-keywords@^3.5.2:
version "3.5.2"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==

ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.5.5:
version "6.12.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7"
Expand All @@ -3814,6 +3824,16 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.5.5:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"

ajv@^6.12.4:
version "6.12.4"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.4.tgz#0614facc4522127fa713445c6bfd3ebd376e2234"
integrity sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==
dependencies:
fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"

ally.js@1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/ally.js/-/ally.js-1.4.1.tgz#9fb7e6ba58efac4ee9131cb29aa9ee3b540bcf1e"
Expand Down Expand Up @@ -5945,23 +5965,23 @@ css-loader@1.0.0:
postcss-value-parser "^3.3.0"
source-list-map "^2.0.0"

css-loader@3.5.3:
version "3.5.3"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.5.3.tgz#95ac16468e1adcd95c844729e0bb167639eb0bcf"
css-loader@4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-4.3.0.tgz#c888af64b2a5b2e85462c72c0f4a85c7e2e0821e"
integrity sha512-rdezjCjScIrsL8BSYszgT4s476IcNKt6yX69t0pHjJVnPUTDpn4WfIpDQTN3wCJvUvfsz/mFjuGOekf3PY3NUg==
dependencies:
camelcase "^5.3.1"
camelcase "^6.0.0"
cssesc "^3.0.0"
icss-utils "^4.1.1"
loader-utils "^1.2.3"
normalize-path "^3.0.0"
postcss "^7.0.27"
loader-utils "^2.0.0"
postcss "^7.0.32"
postcss-modules-extract-imports "^2.0.0"
postcss-modules-local-by-default "^3.0.2"
postcss-modules-local-by-default "^3.0.3"
postcss-modules-scope "^2.2.0"
postcss-modules-values "^3.0.0"
postcss-value-parser "^4.0.3"
schema-utils "^2.6.6"
semver "^6.3.0"
postcss-value-parser "^4.1.0"
schema-utils "^2.7.1"
semver "^7.3.2"

css-modules-loader-core@^1.1.0:
version "1.1.0"
Expand Down Expand Up @@ -13062,14 +13082,15 @@ postcss-modules-local-by-default@1.2.0, postcss-modules-local-by-default@^1.2.0:
css-selector-tokenizer "^0.7.0"
postcss "^6.0.1"

postcss-modules-local-by-default@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz#e8a6561be914aaf3c052876377524ca90dbb7915"
postcss-modules-local-by-default@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0"
integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==
dependencies:
icss-utils "^4.1.1"
postcss "^7.0.16"
postcss "^7.0.32"
postcss-selector-parser "^6.0.2"
postcss-value-parser "^4.0.0"
postcss-value-parser "^4.1.0"

postcss-modules-scope@1.1.0, postcss-modules-scope@^1.1.0:
version "1.1.0"
Expand Down Expand Up @@ -13446,10 +13467,15 @@ postcss-value-parser@^3.0.0, postcss-value-parser@^3.0.1, postcss-value-parser@^
version "3.3.1"
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281"

postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.0.3:
postcss-value-parser@^4.0.2:
version "4.0.3"
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz#651ff4593aa9eda8d5d0d66593a2417aeaeb325d"

postcss-value-parser@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==

postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz#da8b472d901da1e205b47bdc98637b9e9e550e5f"
Expand Down Expand Up @@ -13516,7 +13542,7 @@ postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.21, postcss@^6.0.23, postcss@^6.0.9
source-map "^0.6.1"
supports-color "^5.4.0"

postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.11, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.17, postcss@^7.0.18, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7:
postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.11, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.18, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7:
version "7.0.27"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.27.tgz#cc67cdc6b0daa375105b7c424a85567345fc54d9"
dependencies:
Expand Down Expand Up @@ -14948,6 +14974,15 @@ schema-utils@^1.0.0:
ajv-errors "^1.0.0"
ajv-keywords "^3.1.0"

schema-utils@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7"
integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==
dependencies:
"@types/json-schema" "^7.0.5"
ajv "^6.12.4"
ajv-keywords "^3.5.2"

scss-tokenizer@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1"
Expand Down

0 comments on commit 7e22009

Please sign in to comment.