Adds support for tailwind.config.cjs files (#3181)
* feat: automatically init and resolve tailwind.config.cjs files * test: add tests for default tailwind.config.cjs resolution * fix `cjsConfigFile` constant * Fix JSDoc type of isModule
This commit is contained in:
parent
1ca32b90b2
commit
f1ee046685
8 changed files with 150 additions and 19 deletions
|
|
@ -8,6 +8,7 @@ import runInTempDirectory from '../jest/runInTempDirectory'
|
|||
describe('cli', () => {
|
||||
const inputCssPath = path.resolve(__dirname, 'fixtures/tailwind-input.css')
|
||||
const customConfigPath = path.resolve(__dirname, 'fixtures/custom-config.js')
|
||||
const esmPackageJsonPath = path.resolve(__dirname, 'fixtures/esm-package.json')
|
||||
const defaultConfigFixture = utils.readFile(constants.defaultConfigStubFile)
|
||||
const simpleConfigFixture = utils.readFile(constants.simpleConfigStubFile)
|
||||
const defaultPostCssConfigFixture = utils.readFile(constants.defaultPostCssConfigStubFile)
|
||||
|
|
@ -47,6 +48,27 @@ describe('cli', () => {
|
|||
})
|
||||
})
|
||||
|
||||
it('creates a .cjs Tailwind config file inside of an ESM project', () => {
|
||||
return runInTempDirectory(() => {
|
||||
utils.writeFile('package.json', utils.readFile(esmPackageJsonPath))
|
||||
return cli(['init']).then(() => {
|
||||
expect(utils.readFile(constants.cjsConfigFile)).toEqual(simpleConfigFixture)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('creates a .cjs Tailwind config file and a postcss.config.cjs file inside of an ESM project', () => {
|
||||
return runInTempDirectory(() => {
|
||||
utils.writeFile('package.json', utils.readFile(esmPackageJsonPath))
|
||||
return cli(['init', '-p']).then(() => {
|
||||
expect(utils.readFile(constants.cjsConfigFile)).toEqual(simpleConfigFixture)
|
||||
expect(utils.readFile(constants.cjsPostCssConfigFile)).toEqual(
|
||||
defaultPostCssConfigFixture
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('creates a Tailwind config file in a custom location', () => {
|
||||
return runInTempDirectory(() => {
|
||||
return cli(['init', 'custom.js']).then(() => {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import fs from 'fs'
|
|||
import path from 'path'
|
||||
import postcss from 'postcss'
|
||||
import tailwind from '../src/index'
|
||||
import { defaultConfigFile } from '../src/constants'
|
||||
import { cjsConfigFile, defaultConfigFile } from '../src/constants'
|
||||
import inTempDirectory from '../jest/runInTempDirectory'
|
||||
|
||||
test('it uses the values from the custom config file', () => {
|
||||
|
|
@ -133,6 +133,45 @@ test('custom config can be passed under the `config` property', () => {
|
|||
})
|
||||
})
|
||||
|
||||
test('tailwind.config.cjs is picked up by default', () => {
|
||||
return inTempDirectory(() => {
|
||||
fs.writeFileSync(
|
||||
path.resolve(cjsConfigFile),
|
||||
`module.exports = {
|
||||
theme: {
|
||||
screens: {
|
||||
mobile: '400px',
|
||||
},
|
||||
},
|
||||
}`
|
||||
)
|
||||
|
||||
return postcss([tailwind])
|
||||
.process(
|
||||
`
|
||||
@responsive {
|
||||
.foo {
|
||||
color: blue;
|
||||
}
|
||||
}
|
||||
`,
|
||||
{ from: undefined }
|
||||
)
|
||||
.then((result) => {
|
||||
expect(result.css).toMatchCss(`
|
||||
.foo {
|
||||
color: blue;
|
||||
}
|
||||
@media (min-width: 400px) {
|
||||
.mobile\\:foo {
|
||||
color: blue;
|
||||
}
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('tailwind.config.js is picked up by default', () => {
|
||||
return inTempDirectory(() => {
|
||||
fs.writeFileSync(
|
||||
|
|
@ -172,6 +211,45 @@ test('tailwind.config.js is picked up by default', () => {
|
|||
})
|
||||
})
|
||||
|
||||
test('tailwind.config.cjs is picked up by default when passing an empty object', () => {
|
||||
return inTempDirectory(() => {
|
||||
fs.writeFileSync(
|
||||
path.resolve(cjsConfigFile),
|
||||
`module.exports = {
|
||||
theme: {
|
||||
screens: {
|
||||
mobile: '400px',
|
||||
},
|
||||
},
|
||||
}`
|
||||
)
|
||||
|
||||
return postcss([tailwind({})])
|
||||
.process(
|
||||
`
|
||||
@responsive {
|
||||
.foo {
|
||||
color: blue;
|
||||
}
|
||||
}
|
||||
`,
|
||||
{ from: undefined }
|
||||
)
|
||||
.then((result) => {
|
||||
expect(result.css).toMatchCss(`
|
||||
.foo {
|
||||
color: blue;
|
||||
}
|
||||
@media (min-width: 400px) {
|
||||
.mobile\\:foo {
|
||||
color: blue;
|
||||
}
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('tailwind.config.js is picked up by default when passing an empty object', () => {
|
||||
return inTempDirectory(() => {
|
||||
fs.writeFileSync(
|
||||
|
|
|
|||
3
__tests__/fixtures/esm-package.json
Normal file
3
__tests__/fixtures/esm-package.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"type": "module"
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@ export const options = [
|
|||
},
|
||||
{
|
||||
usage: '-p',
|
||||
description: 'Generate postcss.config.js file.',
|
||||
description: 'Generate PostCSS config file.',
|
||||
},
|
||||
]
|
||||
|
||||
|
|
@ -35,8 +35,9 @@ export function run(cliParams, cliOptions) {
|
|||
return new Promise((resolve) => {
|
||||
utils.header()
|
||||
|
||||
const isModule = utils.isModule()
|
||||
const full = cliOptions.full
|
||||
const file = cliParams[0] || constants.defaultConfigFile
|
||||
const file = cliParams[0] || (isModule ? constants.cjsConfigFile : constants.defaultConfigFile)
|
||||
const simplePath = utils.getSimplePath(file)
|
||||
|
||||
utils.exists(file) && utils.die(colors.file(simplePath), 'already exists.')
|
||||
|
|
@ -52,10 +53,13 @@ export function run(cliParams, cliOptions) {
|
|||
utils.log(emoji.yes, 'Created Tailwind config file:', colors.file(simplePath))
|
||||
|
||||
if (cliOptions.postcss) {
|
||||
const path = utils.getSimplePath(constants.defaultPostCssConfigFile)
|
||||
const postCssConfigFile = isModule
|
||||
? constants.cjsPostCssConfigFile
|
||||
: constants.defaultPostCssConfigFile
|
||||
const path = utils.getSimplePath(postCssConfigFile)
|
||||
utils.exists(constants.defaultPostCssConfigFile) &&
|
||||
utils.die(colors.file(path), 'already exists.')
|
||||
utils.copyFile(constants.defaultPostCssConfigStubFile, constants.defaultPostCssConfigFile)
|
||||
utils.copyFile(constants.defaultPostCssConfigStubFile, postCssConfigFile)
|
||||
utils.log(emoji.yes, 'Created PostCSS config file:', colors.file(path))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { copyFileSync, ensureFileSync, existsSync, outputFileSync, readFileSync } from 'fs-extra'
|
||||
import { findKey, mapValues, startsWith, trimStart } from 'lodash'
|
||||
import path from 'path'
|
||||
|
||||
import * as colors from './colors'
|
||||
import * as emoji from './emoji'
|
||||
|
|
@ -119,6 +120,20 @@ export function readFile(path) {
|
|||
return readFileSync(path, 'utf-8')
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if current package.json uses type "module"
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function isModule() {
|
||||
const pkgPath = path.resolve('./package.json')
|
||||
if (exists(pkgPath)) {
|
||||
const pkg = JSON.parse(readFile(pkgPath))
|
||||
return pkg.type && pkg.type === 'module'
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes content to file.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -3,6 +3,11 @@ import path from 'path'
|
|||
export const cli = 'tailwind'
|
||||
export const defaultConfigFile = './tailwind.config.js'
|
||||
export const defaultPostCssConfigFile = './postcss.config.js'
|
||||
export const cjsConfigFile = './tailwind.config.cjs'
|
||||
export const cjsPostCssConfigFile = './postcss.config.cjs'
|
||||
|
||||
export const supportedConfigFiles = [cjsConfigFile, defaultConfigFile]
|
||||
export const supportedPostCssConfigFile = [cjsPostCssConfigFile, defaultPostCssConfigFile]
|
||||
|
||||
export const defaultConfigStubFile = path.resolve(__dirname, '../stubs/defaultConfig.stub.js')
|
||||
export const simpleConfigStubFile = path.resolve(__dirname, '../stubs/simpleConfig.stub.js')
|
||||
|
|
|
|||
16
src/index.js
16
src/index.js
|
|
@ -9,7 +9,7 @@ import processTailwindFeatures from './processTailwindFeatures'
|
|||
import formatCSS from './lib/formatCSS'
|
||||
import resolveConfig from './util/resolveConfig'
|
||||
import getAllConfigs from './util/getAllConfigs'
|
||||
import { defaultConfigFile } from './constants'
|
||||
import { supportedConfigFiles } from './constants'
|
||||
import defaultConfig from '../stubs/defaultConfig.stub.js'
|
||||
|
||||
function resolveConfigPath(filePath) {
|
||||
|
|
@ -34,13 +34,15 @@ function resolveConfigPath(filePath) {
|
|||
}
|
||||
|
||||
// require('tailwindcss')
|
||||
try {
|
||||
const defaultConfigPath = path.resolve(defaultConfigFile)
|
||||
fs.accessSync(defaultConfigPath)
|
||||
return defaultConfigPath
|
||||
} catch (err) {
|
||||
return undefined
|
||||
for (const configFile of supportedConfigFiles) {
|
||||
try {
|
||||
const configPath = path.resolve(configFile)
|
||||
fs.accessSync(configPath)
|
||||
return configPath
|
||||
} catch (err) {}
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
const getConfigFunction = (config) => () => {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import processTailwindFeatures from './processTailwindFeatures'
|
|||
import formatCSS from './lib/formatCSS'
|
||||
import resolveConfig from './util/resolveConfig'
|
||||
import getAllConfigs from './util/getAllConfigs'
|
||||
import { defaultConfigFile } from './constants'
|
||||
import { supportedConfigFiles } from './constants'
|
||||
import defaultConfig from '../stubs/defaultConfig.stub.js'
|
||||
|
||||
function resolveConfigPath(filePath) {
|
||||
|
|
@ -35,13 +35,15 @@ function resolveConfigPath(filePath) {
|
|||
}
|
||||
|
||||
// require('tailwindcss')
|
||||
try {
|
||||
const defaultConfigPath = path.resolve(defaultConfigFile)
|
||||
fs.accessSync(defaultConfigPath)
|
||||
return defaultConfigPath
|
||||
} catch (err) {
|
||||
return undefined
|
||||
for (const configFile of supportedConfigFiles) {
|
||||
try {
|
||||
const configPath = path.resolve(configFile)
|
||||
fs.accessSync(configPath)
|
||||
return configPath
|
||||
} catch (err) {}
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
const getConfigFunction = (config) => () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue