Skip to content

Commit

Permalink
Don't rewrite source maps for @layer rules (#8971)
Browse files Browse the repository at this point in the history
* Cleanup

* Don’t rewrite source maps for `@layer` rules

* Update changelog
  • Loading branch information
thecrypticace committed Jul 27, 2022
1 parent da268f6 commit a1346c9
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 10 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- Don't rewrite source maps for `@layer` rules ([#8971](https://github.com/tailwindlabs/tailwindcss/pull/8971))

### Added

- Added types for `resolveConfig` ([#8924](https://github.com/tailwindlabs/tailwindcss/pull/8924))
Expand Down
6 changes: 5 additions & 1 deletion src/lib/generateRules.js
Expand Up @@ -471,7 +471,11 @@ function splitWithSeparator(input, separator) {

function* recordCandidates(matches, classCandidate) {
for (const match of matches) {
match[1].raws.tailwind = { ...match[1].raws.tailwind, classCandidate }
match[1].raws.tailwind = {
...match[1].raws.tailwind,
classCandidate,
preserveSource: match[0].options?.preserveSource ?? false,
}

yield match
}
Expand Down
6 changes: 4 additions & 2 deletions src/lib/setupContextUtils.js
Expand Up @@ -289,6 +289,7 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
},
addComponents(components, options) {
let defaultOptions = {
preserveSource: false,
respectPrefix: true,
respectImportant: false,
}
Expand All @@ -311,6 +312,7 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
},
addUtilities(utilities, options) {
let defaultOptions = {
preserveSource: false,
respectPrefix: true,
respectImportant: true,
}
Expand Down Expand Up @@ -579,14 +581,14 @@ function collectLayerPlugins(root) {
} else if (layerRule.params === 'components') {
for (let node of layerRule.nodes) {
layerPlugins.push(function ({ addComponents }) {
addComponents(node, { respectPrefix: false })
addComponents(node, { respectPrefix: false, preserveSource: true })
})
}
layerRule.remove()
} else if (layerRule.params === 'utilities') {
for (let node of layerRule.nodes) {
layerPlugins.push(function ({ addUtilities }) {
addUtilities(node, { respectPrefix: false })
addUtilities(node, { respectPrefix: false, preserveSource: true })
})
}
layerRule.remove()
Expand Down
6 changes: 5 additions & 1 deletion src/util/cloneNodes.js
Expand Up @@ -2,7 +2,11 @@ export default function cloneNodes(nodes, source = undefined, raws = undefined)
return nodes.map((node) => {
let cloned = node.clone()

if (source !== undefined) {
// We always want override the source map
// except when explicitly told not to
let shouldOverwriteSource = node.raws.tailwind?.preserveSource !== true || !cloned.source

if (source !== undefined && shouldOverwriteSource) {
cloned.source = source

if ('walk' in cloned) {
Expand Down
14 changes: 14 additions & 0 deletions tests/__snapshots__/source-maps.test.js.snap
Expand Up @@ -347,3 +347,17 @@ Array [
"2:18 -> 440:0",
]
`;

exports[`source maps for layer rules are not rewritten to point to @tailwind directives 1`] = `
Array [
"2:6 -> 1:0",
"2:6 -> 2:10",
"2:25 -> 3:0",
"3:8 -> 4:8",
"4:10-31 -> 5:10-31",
"5:8 -> 6:8",
"3:8 -> 7:8",
"4:10-31 -> 8:10-31",
"5:8 -> 9:8",
]
`;
52 changes: 47 additions & 5 deletions tests/source-maps.test.js
@@ -1,4 +1,5 @@
import { runWithSourceMaps as run, html, css } from './util/run'
import postcss from 'postcss'
import { runWithSourceMaps as run, html, css, map } from './util/run'
import { parseSourceMaps } from './util/source-maps'

it('apply generates source maps', async () => {
Expand Down Expand Up @@ -39,7 +40,6 @@ it('apply generates source maps', async () => {
expect(sources).not.toContain('<no source>')
expect(sources.length).toBe(1)

// It would make the tests nicer to read and write
expect(annotations).toMatchSnapshot()
})

Expand All @@ -60,7 +60,6 @@ it('preflight + base have source maps', async () => {
expect(sources).not.toContain('<no source>')
expect(sources.length).toBe(1)

// It would make the tests nicer to read and write
expect(annotations).toMatchSnapshot()
})

Expand All @@ -81,7 +80,6 @@ it('utilities have source maps', async () => {
expect(sources).not.toContain('<no source>')
expect(sources.length).toBe(1)

// It would make the tests nicer to read and write
expect(annotations).toStrictEqual(['2:4 -> 1:0', '2:4-23 -> 2:4-24', '2:4 -> 3:4', '2:23 -> 4:0'])
})

Expand All @@ -102,6 +100,50 @@ it('components have source maps', async () => {
expect(sources).not.toContain('<no source>')
expect(sources.length).toBe(1)

// It would make the tests nicer to read and write
expect(annotations).toMatchSnapshot()
})

it('source maps for layer rules are not rewritten to point to @tailwind directives', async () => {
let config = {
content: [{ raw: `font-normal foo hover:foo` }],
}

let utilitiesFile = postcss.parse(
css`
@tailwind utilities;
`,
{ from: 'components.css', map: { prev: map } }
)

let mainCssFile = postcss.parse(
css`
@layer utilities {
.foo {
background-color: red;
}
}
`,
{ from: 'input.css', map: { prev: map } }
)

// Just pretend that there's an @import in `mainCssFile` that imports the nodes from `utilitiesFile`
let input = postcss.root({
nodes: [...utilitiesFile.nodes, ...mainCssFile.nodes],
source: mainCssFile.source,
})

let result = await run(input, config)

let { sources, annotations } = parseSourceMaps(result)

// All CSS generated by Tailwind CSS should be annotated with source maps
// And always be able to point to the original source file
expect(sources).not.toContain('<no source>')

// And we should see that the source map for the layer rule is not rewritten
// to point to the @tailwind directive but instead points to the original
expect(sources.length).toBe(2)
expect(sources).toEqual(['components.css', 'input.css'])

expect(annotations).toMatchSnapshot()
})
2 changes: 1 addition & 1 deletion tests/util/run.js
Expand Up @@ -5,7 +5,7 @@ import tailwind from '../../src'
export * from './strings'
export * from './defaults'

let map = JSON.stringify({
export let map = JSON.stringify({
version: 3,
file: null,
sources: [],
Expand Down

0 comments on commit a1346c9

Please sign in to comment.