From 74cd1187e3e22f18c18c532041e2394196f75088 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 17 Jun 2021 13:00:50 +0200 Subject: [PATCH 01/10] add nesting plugin --- plugins/nesting/README.md | 48 ++++++++++ plugins/nesting/index.js | 46 +++++++++ plugins/nesting/index.test.js | 176 ++++++++++++++++++++++++++++++++++ 3 files changed, 270 insertions(+) create mode 100644 plugins/nesting/README.md create mode 100644 plugins/nesting/index.js create mode 100644 plugins/nesting/index.test.js diff --git a/plugins/nesting/README.md b/plugins/nesting/README.md new file mode 100644 index 000000000000..090f826c7617 --- /dev/null +++ b/plugins/nesting/README.md @@ -0,0 +1,48 @@ +# @tailwindcss/nesting + +This is a PostCSS plugin that wraps [postcss-nested](https://github.com/postcss/postcss-nested) or [postcss-nesting](https://github.com/jonathantneal/postcss-nesting) and acts as a compatibility layer to make sure your nesting plugin of choice properly understands custom syntax like `@apply` and `@screen`. + +To use it, install it via npm: + +```shell +npm install @tailwindcss/nesting +``` + +Then add it to your PostCSS configuration, somewhere before Tailwind itself: + +```js +// postcss.config.js +module.exports = { + plugins: [ + require('postcss-import'), + require('@tailwindcss/nesting'), + require('tailwindcss'), + require('autoprefixer'), + ] +} +``` + +By default, it uses the [postcss-nested](https://github.com/postcss/postcss-nested) plugin under the hood, which uses a Sass-like syntax and is the plugin that powers nesting support in the [Tailwind CSS plugin API](https://tailwindcss.com/docs/plugins#css-in-js-syntax). + +If you'd rather use [postcss-nesting](https://github.com/jonathantneal/postcss-nesting) (which is based on the work-in-progress [CSS Nesting](https://drafts.csswg.org/css-nesting-1/) specification), first install the plugin alongside `@tailwindcss/nesting`: + +```shell +npm install @tailwindcss/nesting postcss-nesting +``` + +Then pass the plugin itself as an argument to `@tailwindcss/nesting` in your PostCSS configuration: + +```js +// postcss.config.js +module.exports = { + plugins: [ + require('postcss-import'), + require('@tailwindcss/nesting')(require('postcss-nesting')), + require('tailwindcss'), + require('autoprefixer'), + ] +} +``` + +This can also be helpful if for whatever reason you need to use a very specific version of `postcss-nested` and want to override the version we bundle with `@tailwindcss/nesting` itself. + diff --git a/plugins/nesting/index.js b/plugins/nesting/index.js new file mode 100644 index 000000000000..8ff7f63ef499 --- /dev/null +++ b/plugins/nesting/index.js @@ -0,0 +1,46 @@ +let postcss = require('postcss') +let postcssNested = require('postcss-nested') + +module.exports = (opts = postcssNested) => { + return { + postcssPlugin: '@tailwindcss/nesting', + Once(root, { result }) { + root.walkAtRules('screen', (rule) => { + rule.name = 'media' + rule.params = `screen(${rule.params})` + }) + + root.walkAtRules('apply', (rule) => { + rule.before(postcss.decl({ prop: '__apply', value: rule.params })) + rule.remove() + }) + + let plugin = (() => { + if (typeof opts === 'function') { + return opts + } + + if (typeof opts === 'string') { + return require(opts) + } + + if (Object.keys(opts).length <= 0) { + return postcssNested + } + + throw new Error('@tailwindcss/nesting should be loaded with a nesting plugin.') + })() + + postcss([plugin]).process(root, result.opts).sync() + + root.walkDecls('__apply', (decl) => { + decl.before(postcss.atRule({ name: 'apply', params: decl.value })) + decl.remove() + }) + + return root + }, + } +} + +module.exports.postcss = true diff --git a/plugins/nesting/index.test.js b/plugins/nesting/index.test.js new file mode 100644 index 000000000000..1dbe38c6bda5 --- /dev/null +++ b/plugins/nesting/index.test.js @@ -0,0 +1,176 @@ +let postcss = require('postcss') +let postcssNested = require('postcss-nested') +let plugin = require('.') + +it('should be possible to load a custom nesting plugin', async () => { + let input = css` + .foo { + color: black; + @screen md { + color: blue; + } + } + ` + + expect( + await run(input, function (root) { + root.walkRules((rule) => { + rule.selector += '-modified' + }) + }) + ).toMatchCss(css` + .foo-modified { + color: black; + @media screen(md) { + color: blue; + } + } + `) +}) + +it('should be possible to load a custom nesting plugin by name (string) instead', async () => { + let input = css` + .foo { + color: black; + @screen md { + color: blue; + } + } + ` + + expect(await run(input, 'postcss-nested')).toMatchCss(css` + .foo { + color: black; + } + + @media screen(md) { + .foo { + color: blue; + } + } + `) +}) + +it('should default to the bundled postcss-nested plugin (no options)', async () => { + let input = css` + .foo { + color: black; + @screen md { + color: blue; + } + } + ` + + expect(await run(input)).toMatchCss(css` + .foo { + color: black; + } + + @media screen(md) { + .foo { + color: blue; + } + } + `) +}) + +it('should default to the bundled postcss-nested plugin (empty ooptions)', async () => { + let input = css` + .foo { + color: black; + @screen md { + color: blue; + } + } + ` + + expect(await run(input, {})).toMatchCss(css` + .foo { + color: black; + } + + @media screen(md) { + .foo { + color: blue; + } + } + `) +}) + +test('@screen rules are replaced with media queries', async () => { + let input = css` + .foo { + color: black; + @screen md { + color: blue; + } + } + ` + + expect(await run(input, postcssNested)).toMatchCss(css` + .foo { + color: black; + } + + @media screen(md) { + .foo { + color: blue; + } + } + `) +}) + +test('@screen rules can work with `@apply`', async () => { + let input = css` + .foo { + @apply bg-black; + @screen md { + @apply bg-blue-500; + } + } + ` + + expect(await run(input, postcssNested)).toMatchCss(css` + .foo { + @apply bg-black; + } + + @media screen(md) { + .foo { + @apply bg-blue-500; + } + } + `) +}) + +// --- + +function indentRecursive(node, indent = 0) { + node.each && + node.each((child, i) => { + if (!child.raws.before || child.raws.before.includes('\n')) { + child.raws.before = `\n${node.type !== 'rule' && i > 0 ? '\n' : ''}${' '.repeat(indent)}` + } + child.raws.after = `\n${' '.repeat(indent)}` + indentRecursive(child, indent + 1) + }) +} + +function formatNodes(root) { + indentRecursive(root) + if (root.first) { + root.first.raws.before = '' + } +} + +async function run(input, options) { + return ( + await postcss([options === undefined ? plugin : plugin(options), formatNodes]).process(input, { + from: undefined, + }) + ).toString() +} + +function css(templates) { + return templates.join('') +} From b4b571a7dd87517e793e52660d8bb38d741e1d82 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 17 Jun 2021 13:02:11 +0200 Subject: [PATCH 02/10] rename @tailwindcss/nesting to tailwindcss/nesting --- plugins/nesting/README.md | 22 ++++++++-------------- plugins/nesting/index.js | 4 ++-- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/plugins/nesting/README.md b/plugins/nesting/README.md index 090f826c7617..2d85579d8bf1 100644 --- a/plugins/nesting/README.md +++ b/plugins/nesting/README.md @@ -1,21 +1,15 @@ -# @tailwindcss/nesting +# tailwindcss/nesting This is a PostCSS plugin that wraps [postcss-nested](https://github.com/postcss/postcss-nested) or [postcss-nesting](https://github.com/jonathantneal/postcss-nesting) and acts as a compatibility layer to make sure your nesting plugin of choice properly understands custom syntax like `@apply` and `@screen`. -To use it, install it via npm: - -```shell -npm install @tailwindcss/nesting -``` - -Then add it to your PostCSS configuration, somewhere before Tailwind itself: +Add it to your PostCSS configuration, somewhere before Tailwind itself: ```js // postcss.config.js module.exports = { plugins: [ require('postcss-import'), - require('@tailwindcss/nesting'), + require('tailwindcss/nesting'), require('tailwindcss'), require('autoprefixer'), ] @@ -24,25 +18,25 @@ module.exports = { By default, it uses the [postcss-nested](https://github.com/postcss/postcss-nested) plugin under the hood, which uses a Sass-like syntax and is the plugin that powers nesting support in the [Tailwind CSS plugin API](https://tailwindcss.com/docs/plugins#css-in-js-syntax). -If you'd rather use [postcss-nesting](https://github.com/jonathantneal/postcss-nesting) (which is based on the work-in-progress [CSS Nesting](https://drafts.csswg.org/css-nesting-1/) specification), first install the plugin alongside `@tailwindcss/nesting`: +If you'd rather use [postcss-nesting](https://github.com/jonathantneal/postcss-nesting) (which is based on the work-in-progress [CSS Nesting](https://drafts.csswg.org/css-nesting-1/) specification), first install the plugin alongside `tailwindcss/nesting`: ```shell -npm install @tailwindcss/nesting postcss-nesting +npm install postcss-nesting ``` -Then pass the plugin itself as an argument to `@tailwindcss/nesting` in your PostCSS configuration: +Then pass the plugin itself as an argument to `tailwindcss/nesting` in your PostCSS configuration: ```js // postcss.config.js module.exports = { plugins: [ require('postcss-import'), - require('@tailwindcss/nesting')(require('postcss-nesting')), + require('tailwindcss/nesting')(require('postcss-nesting')), require('tailwindcss'), require('autoprefixer'), ] } ``` -This can also be helpful if for whatever reason you need to use a very specific version of `postcss-nested` and want to override the version we bundle with `@tailwindcss/nesting` itself. +This can also be helpful if for whatever reason you need to use a very specific version of `postcss-nested` and want to override the version we bundle with `tailwindcss/nesting` itself. diff --git a/plugins/nesting/index.js b/plugins/nesting/index.js index 8ff7f63ef499..6364ed965a1b 100644 --- a/plugins/nesting/index.js +++ b/plugins/nesting/index.js @@ -3,7 +3,7 @@ let postcssNested = require('postcss-nested') module.exports = (opts = postcssNested) => { return { - postcssPlugin: '@tailwindcss/nesting', + postcssPlugin: 'tailwindcss/nesting', Once(root, { result }) { root.walkAtRules('screen', (rule) => { rule.name = 'media' @@ -28,7 +28,7 @@ module.exports = (opts = postcssNested) => { return postcssNested } - throw new Error('@tailwindcss/nesting should be loaded with a nesting plugin.') + throw new Error('tailwindcss/nesting should be loaded with a nesting plugin.') })() postcss([plugin]).process(root, result.opts).sync() From f821a511958e235f53f697ef5c79731acf3456f0 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 17 Jun 2021 13:19:38 +0200 Subject: [PATCH 03/10] ignore the built `nesting` plugin --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 8e6db035b669..2bfdf621a35a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,8 @@ index.html yarn.lock yarn-error.log +# "External" plugins +/nesting + # Perf related files isolate*.log From ec051828f0cddd832d28a35fcd51cbf127bb00a5 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 17 Jun 2021 13:37:11 +0200 Subject: [PATCH 04/10] add a postcss7 compat version --- plugins/nesting/index.js | 40 +++--------------------------- plugins/nesting/index.postcss7.js | 4 +++ plugins/nesting/plugin.js | 41 +++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 37 deletions(-) create mode 100644 plugins/nesting/index.postcss7.js create mode 100644 plugins/nesting/plugin.js diff --git a/plugins/nesting/index.js b/plugins/nesting/index.js index 6364ed965a1b..273814a75b2d 100644 --- a/plugins/nesting/index.js +++ b/plugins/nesting/index.js @@ -1,44 +1,10 @@ -let postcss = require('postcss') -let postcssNested = require('postcss-nested') +let nesting = require('./plugin') -module.exports = (opts = postcssNested) => { +module.exports = (opts) => { return { postcssPlugin: 'tailwindcss/nesting', Once(root, { result }) { - root.walkAtRules('screen', (rule) => { - rule.name = 'media' - rule.params = `screen(${rule.params})` - }) - - root.walkAtRules('apply', (rule) => { - rule.before(postcss.decl({ prop: '__apply', value: rule.params })) - rule.remove() - }) - - let plugin = (() => { - if (typeof opts === 'function') { - return opts - } - - if (typeof opts === 'string') { - return require(opts) - } - - if (Object.keys(opts).length <= 0) { - return postcssNested - } - - throw new Error('tailwindcss/nesting should be loaded with a nesting plugin.') - })() - - postcss([plugin]).process(root, result.opts).sync() - - root.walkDecls('__apply', (decl) => { - decl.before(postcss.atRule({ name: 'apply', params: decl.value })) - decl.remove() - }) - - return root + return nesting(opts)(root, result) }, } } diff --git a/plugins/nesting/index.postcss7.js b/plugins/nesting/index.postcss7.js new file mode 100644 index 000000000000..54f3056890b6 --- /dev/null +++ b/plugins/nesting/index.postcss7.js @@ -0,0 +1,4 @@ +let postcss = require('postcss') +let nesting = require('./plugin') + +module.exports = postcss.plugin('tailwindcss/nesting', nesting) diff --git a/plugins/nesting/plugin.js b/plugins/nesting/plugin.js new file mode 100644 index 000000000000..6ba557594fc2 --- /dev/null +++ b/plugins/nesting/plugin.js @@ -0,0 +1,41 @@ +let postcss = require('postcss') +let postcssNested = require('postcss-nested') + +module.exports = function nesting(opts = postcssNested) { + return (root, result) => { + root.walkAtRules('screen', (rule) => { + rule.name = 'media' + rule.params = `screen(${rule.params})` + }) + + root.walkAtRules('apply', (rule) => { + rule.before(postcss.decl({ prop: '__apply', value: rule.params })) + rule.remove() + }) + + let plugin = (() => { + if (typeof opts === 'function') { + return opts + } + + if (typeof opts === 'string') { + return require(opts) + } + + if (Object.keys(opts).length <= 0) { + return postcssNested + } + + throw new Error('tailwindcss/nesting should be loaded with a nesting plugin.') + })() + + postcss([plugin]).process(root, result.opts).sync() + + root.walkDecls('__apply', (decl) => { + decl.before(postcss.atRule({ name: 'apply', params: decl.value })) + decl.remove() + }) + + return root + } +} From 33ca23ee28cbf51ee064479846b31e5b161abf59 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 17 Jun 2021 13:56:13 +0200 Subject: [PATCH 05/10] include `nesting` plugin when publishing --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index bb2737073261..f4b72ebe3c0a 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "peers/*", "scripts/*.js", "stubs/*.stub.js", + "nesting/*", "*.css", "*.js" ], From d3e048e681f4358e22e3881d4e77e060ffa504f8 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 17 Jun 2021 13:56:48 +0200 Subject: [PATCH 06/10] add `build-plugins` script This will allow us to keep the plugins in their dedicated folders + tests + postcss7 compatibility files. However, when we copy over the plugins to the root. For example `plugins/nesting/` -> `nesting/` we skip files like `.test.js` and `.postcss7.js`. --- scripts/build-plugins.js | 47 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 scripts/build-plugins.js diff --git a/scripts/build-plugins.js b/scripts/build-plugins.js new file mode 100644 index 000000000000..2ac5e281bfe0 --- /dev/null +++ b/scripts/build-plugins.js @@ -0,0 +1,47 @@ +let fs = require('fs') +let path = require('path') + +let plugins = fs.readdirSync(fromRootPath('plugins')) + +for (let plugin of plugins) { + // Cleanup + let pluginDest = fromRootPath(plugin) + if (fs.existsSync(pluginDest)) { + fs.rmdirSync(pluginDest, { recursive: true }) + } + + // Copy plugin over + copyFolder(fromRootPath('plugins', plugin), pluginDest, (file) => { + // Ignore test files + if (file.endsWith('.test.js')) return false + // Ignore postcss7 files + if (file.endsWith('.postcss7.js')) return false + // Ignore postcss8 files + if (file.endsWith('.postcss8.js')) return false + + return true + }) +} + +// --- + +function fromRootPath(...paths) { + return path.resolve(process.cwd(), ...paths) +} + +function copy(fromPath, toPath) { + fs.mkdirSync(path.dirname(toPath), { recursive: true }) // Ensure folder exists + fs.copyFileSync(fromPath, toPath) +} + +function copyFolder(fromPath, toPath, shouldCopy = () => true) { + let stats = fs.statSync(fromPath) + if (stats.isDirectory()) { + let filesAndFolders = fs.readdirSync(fromPath) + for (let file of filesAndFolders) { + copyFolder(path.resolve(fromPath, file), path.resolve(toPath, file), shouldCopy) + } + } else if (shouldCopy(fromPath)) { + copy(fromPath, toPath) + } +} From 4fe270cac5c1a4d464daa0a1d1c49154ee900bb3 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 17 Jun 2021 13:58:31 +0200 Subject: [PATCH 07/10] build plugins when running `prepublishOnly` --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f4b72ebe3c0a..9a4900be0c74 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "babelify": "babel src --out-dir lib --copy-files", "postbabelify": "ncc build lib/cli-peer-dependencies.js -o peers", "rebuild-fixtures": "npm run babelify && babel-node scripts/rebuildFixtures.js", - "prepublishOnly": "npm run babelify && babel-node scripts/build.js", + "prepublishOnly": "npm run babelify && babel-node scripts/build.js && node scripts/build-plugins.js", "style": "eslint .", "test": "cross-env TAILWIND_MODE=build jest", "test:integrations": "npm run test --prefix ./integrations", From 93a8dd911c97f6557e04886c5f909358f4d388f7 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 17 Jun 2021 14:19:06 +0200 Subject: [PATCH 08/10] improve compat mode We will use a glob so that we can move all *.postcss7.* files to just *.* likewise we will also backup to *.* to *.postcss8.* for restoring purposes. Concrete example: - Current state: - index.js // PostCSS 8 implementation - index.postcss7.js // PostCSS 7 implementation - Run "compat" - index.js // PostCSS 7 implementation - index.postcss7.js // PostCSS 7 implementation - index.postcss8.js // PostCSS 8 implementation (Backup of original) - Run "compat:restore" - index.js // PostCSS 8 implementation - index.postcss7.js // PostCSS 7 implementation - X index.postcss8.js // PostCSS 8 implementation (Removed) --- scripts/compat.js | 88 +++++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 42 deletions(-) diff --git a/scripts/compat.js b/scripts/compat.js index db7efe34106e..aef701a07fc8 100644 --- a/scripts/compat.js +++ b/scripts/compat.js @@ -1,81 +1,85 @@ -const fs = require('fs') -const path = require('path') -const merge = require('lodash/merge') +let fs = require('fs') +let path = require('path') +let merge = require('lodash/merge') +let fastGlob = require('fast-glob') -function fromRootPath(...paths) { - return path.resolve(process.cwd(), ...paths) -} - -function copy(fromPath, toPath) { - fs.copyFileSync(fromPath, toPath) -} +let postcss7 = fastGlob.sync(['./**/*.postcss7.*']).filter((file) => !file.startsWith('lib/')) +let postcss8 = fastGlob.sync(['./**/*.postcss8.*']).filter((file) => !file.startsWith('lib/')) if (process.argv.includes('--prepare')) { - if ( - fs.existsSync(fromRootPath('package.postcss8.json')) || - fs.existsSync(fromRootPath('src', 'index.postcss8.js')) - ) { + if (postcss8.length > 0) { console.error('\n\n[ABORT] Already in PostCSS 7 compatibility mode!\n\n') process.exit(1) } - const mainPackageJson = require('../package.json') - const compatPackageJson = require('../package.postcss7.json') + let mainPackageJson = require('../package.json') + let compatPackageJson = require('../package.postcss7.json') - // 1. Backup original package.json file - copy(fromRootPath('package.json'), fromRootPath('package.postcss8.json')) + // Use postcss7 files + for (let file of postcss7) { + let bareFile = file.replace('.postcss7', '') + let postcss8File = file.replace('.postcss7', '.postcss8') - // 2. Backup src/index.js file - copy(fromRootPath('src', 'index.js'), fromRootPath('src', 'index.postcss8.js')) + // Backup + copy(fromRootPath(bareFile), fromRootPath(postcss8File)) - // 3. Use the PostCSS 7 compat file - copy(fromRootPath('src', 'index.postcss7.js'), fromRootPath('src', 'index.js')) + // Swap + copy(fromRootPath(file), fromRootPath(bareFile)) + } - // 4. Deep merge package.json contents - const packageJson = merge({}, mainPackageJson, compatPackageJson) + // Deep merge package.json contents + let packageJson = merge({}, mainPackageJson, compatPackageJson) - // 5. Remove peerDependencies + // Remove peerDependencies delete packageJson.peerDependencies - // 6. Cleanup devDependencies + // Cleanup devDependencies for (let key in packageJson.devDependencies) { if (key.includes('postcss')) delete packageJson.devDependencies[key] } - // 7. Use new name + // Use new name packageJson.name = '@tailwindcss/postcss7-compat' - // 8. Make sure you can publish + // Make sure you can publish packageJson.publishConfig = { access: 'public' } - // 9. Write package.json with the new contents + // Write package.json with the new contents fs.writeFileSync(fromRootPath('package.json'), JSON.stringify(packageJson, null, 2), 'utf8') - // 10. Print some useful information to make publishing easy + // Print some useful information to make publishing easy console.log() console.log('You can safely publish `tailwindcss` in PostCSS 7 compatibility mode:\n') console.log() } else if (process.argv.includes('--restore')) { - if ( - !fs.existsSync(fromRootPath('package.postcss8.json')) || - !fs.existsSync(fromRootPath('src', 'index.postcss8.js')) - ) { + if (postcss8.length === 0) { console.error('\n\n[ABORT] Already in latest PostCSS mode!\n\n') process.exit(1) } - // 1. Restore original package.json file - copy(fromRootPath('package.postcss8.json'), fromRootPath('package.json')) + // Use postcss8 files + for (let file of postcss8) { + let bareFile = file.replace('.postcss8', '') - // 2. Restore src/index.js file - copy(fromRootPath('src', 'index.postcss8.js'), fromRootPath('src', 'index.js')) + // Restore + copy(fromRootPath(file), fromRootPath(bareFile)) - // 3. Cleanup PostCSS 8 related files - fs.unlinkSync(fromRootPath('package.postcss8.json')) - fs.unlinkSync(fromRootPath('src', 'index.postcss8.js')) + // Remove + fs.unlinkSync(fromRootPath(file)) + } - // 4. Done + // Done console.log() console.log('Restored from PostCSS 7 mode to latest PostCSS mode!') console.log() } + +// --- + +function fromRootPath(...paths) { + return path.resolve(process.cwd(), ...paths) +} + +function copy(fromPath, toPath) { + fs.copyFileSync(fromPath, toPath) +} From 6a4d1a2be84aaff7afd13824dd89a5ba0f768576 Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Thu, 17 Jun 2021 08:51:24 -0400 Subject: [PATCH 09/10] Update README.md --- plugins/nesting/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/nesting/README.md b/plugins/nesting/README.md index 2d85579d8bf1..e983434cf073 100644 --- a/plugins/nesting/README.md +++ b/plugins/nesting/README.md @@ -1,6 +1,6 @@ # tailwindcss/nesting -This is a PostCSS plugin that wraps [postcss-nested](https://github.com/postcss/postcss-nested) or [postcss-nesting](https://github.com/jonathantneal/postcss-nesting) and acts as a compatibility layer to make sure your nesting plugin of choice properly understands custom syntax like `@apply` and `@screen`. +This is a PostCSS plugin that wraps [postcss-nested](https://github.com/postcss/postcss-nested) or [postcss-nesting](https://github.com/jonathantneal/postcss-nesting) and acts as a compatibility layer to make sure your nesting plugin of choice properly understands Tailwind's custom syntax like `@apply` and `@screen`. Add it to your PostCSS configuration, somewhere before Tailwind itself: @@ -18,7 +18,7 @@ module.exports = { By default, it uses the [postcss-nested](https://github.com/postcss/postcss-nested) plugin under the hood, which uses a Sass-like syntax and is the plugin that powers nesting support in the [Tailwind CSS plugin API](https://tailwindcss.com/docs/plugins#css-in-js-syntax). -If you'd rather use [postcss-nesting](https://github.com/jonathantneal/postcss-nesting) (which is based on the work-in-progress [CSS Nesting](https://drafts.csswg.org/css-nesting-1/) specification), first install the plugin alongside `tailwindcss/nesting`: +If you'd rather use [postcss-nesting](https://github.com/jonathantneal/postcss-nesting) (which is based on the work-in-progress [CSS Nesting](https://drafts.csswg.org/css-nesting-1/) specification), first install the plugin alongside: ```shell npm install postcss-nesting From dd02ae1485b60200023828f3c8a9b6b83e8a7bfb Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 17 Jun 2021 15:36:44 +0200 Subject: [PATCH 10/10] ensure we `npm install` before publishing --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9a4900be0c74..227bc1161c88 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "babelify": "babel src --out-dir lib --copy-files", "postbabelify": "ncc build lib/cli-peer-dependencies.js -o peers", "rebuild-fixtures": "npm run babelify && babel-node scripts/rebuildFixtures.js", - "prepublishOnly": "npm run babelify && babel-node scripts/build.js && node scripts/build-plugins.js", + "prepublishOnly": "npm install --force && npm run babelify && babel-node scripts/build.js && node scripts/build-plugins.js", "style": "eslint .", "test": "cross-env TAILWIND_MODE=build jest", "test:integrations": "npm run test --prefix ./integrations",