189 lines
4.2 KiB
JavaScript
189 lines
4.2 KiB
JavaScript
|
'use strict'
|
||
|
|
||
|
const resolve = require('path').resolve
|
||
|
|
||
|
const config = require('lilconfig')
|
||
|
const yaml = require('yaml')
|
||
|
|
||
|
const loadOptions = require('./options.js')
|
||
|
const loadPlugins = require('./plugins.js')
|
||
|
|
||
|
/* istanbul ignore next */
|
||
|
const interopRequireDefault = (obj) => obj && obj.__esModule ? obj : { default: obj }
|
||
|
|
||
|
/**
|
||
|
* Process the result from cosmiconfig
|
||
|
*
|
||
|
* @param {Object} ctx Config Context
|
||
|
* @param {Object} result Cosmiconfig result
|
||
|
*
|
||
|
* @return {Object} PostCSS Config
|
||
|
*/
|
||
|
const processResult = (ctx, result) => {
|
||
|
const file = result.filepath || ''
|
||
|
let config = interopRequireDefault(result.config).default || {}
|
||
|
|
||
|
if (typeof config === 'function') {
|
||
|
config = config(ctx)
|
||
|
} else {
|
||
|
config = Object.assign({}, config, ctx)
|
||
|
}
|
||
|
|
||
|
if (!config.plugins) {
|
||
|
config.plugins = []
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
plugins: loadPlugins(config, file),
|
||
|
options: loadOptions(config, file),
|
||
|
file: file
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Builds the Config Context
|
||
|
*
|
||
|
* @param {Object} ctx Config Context
|
||
|
*
|
||
|
* @return {Object} Config Context
|
||
|
*/
|
||
|
const createContext = (ctx) => {
|
||
|
/**
|
||
|
* @type {Object}
|
||
|
*
|
||
|
* @prop {String} cwd=process.cwd() Config search start location
|
||
|
* @prop {String} env=process.env.NODE_ENV Config Enviroment, will be set to `development` by `postcss-load-config` if `process.env.NODE_ENV` is `undefined`
|
||
|
*/
|
||
|
ctx = Object.assign({
|
||
|
cwd: process.cwd(),
|
||
|
env: process.env.NODE_ENV
|
||
|
}, ctx)
|
||
|
|
||
|
if (!ctx.env) {
|
||
|
process.env.NODE_ENV = 'development'
|
||
|
}
|
||
|
|
||
|
return ctx
|
||
|
}
|
||
|
|
||
|
const addTypeScriptLoader = (options = {}, loader) => {
|
||
|
const moduleName = 'postcss'
|
||
|
|
||
|
return {
|
||
|
...options,
|
||
|
searchPlaces: [
|
||
|
...(options.searchPlaces || []),
|
||
|
'package.json',
|
||
|
`.${moduleName}rc`,
|
||
|
`.${moduleName}rc.json`,
|
||
|
`.${moduleName}rc.yaml`,
|
||
|
`.${moduleName}rc.yml`,
|
||
|
`.${moduleName}rc.ts`,
|
||
|
`.${moduleName}rc.js`,
|
||
|
`.${moduleName}rc.cjs`,
|
||
|
`${moduleName}.config.ts`,
|
||
|
`${moduleName}.config.js`,
|
||
|
`${moduleName}.config.cjs`
|
||
|
],
|
||
|
loaders: {
|
||
|
...options.loaders,
|
||
|
'.yaml': (filepath, content) => yaml.parse(content),
|
||
|
'.yml': (filepath, content) => yaml.parse(content),
|
||
|
'.ts': loader
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const withTypeScriptLoader = (rcFunc) => {
|
||
|
return (ctx, path, options) => {
|
||
|
return rcFunc(ctx, path, addTypeScriptLoader(options, (configFile) => {
|
||
|
let registerer = { enabled () {} }
|
||
|
|
||
|
try {
|
||
|
// Register TypeScript compiler instance
|
||
|
registerer = require('ts-node').register()
|
||
|
|
||
|
return require(configFile)
|
||
|
} catch (err) {
|
||
|
if (err.code === 'MODULE_NOT_FOUND') {
|
||
|
throw new Error(
|
||
|
`'ts-node' is required for the TypeScript configuration files. Make sure it is installed\nError: ${err.message}`
|
||
|
)
|
||
|
}
|
||
|
|
||
|
throw err
|
||
|
} finally {
|
||
|
registerer.enabled(false)
|
||
|
}
|
||
|
}))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load Config
|
||
|
*
|
||
|
* @method rc
|
||
|
*
|
||
|
* @param {Object} ctx Config Context
|
||
|
* @param {String} path Config Path
|
||
|
* @param {Object} options Config Options
|
||
|
*
|
||
|
* @return {Promise} config PostCSS Config
|
||
|
*/
|
||
|
const rc = withTypeScriptLoader((ctx, path, options) => {
|
||
|
/**
|
||
|
* @type {Object} The full Config Context
|
||
|
*/
|
||
|
ctx = createContext(ctx)
|
||
|
|
||
|
/**
|
||
|
* @type {String} `process.cwd()`
|
||
|
*/
|
||
|
path = path ? resolve(path) : process.cwd()
|
||
|
|
||
|
return config.lilconfig('postcss', options)
|
||
|
.search(path)
|
||
|
.then((result) => {
|
||
|
if (!result) {
|
||
|
throw new Error(`No PostCSS Config found in: ${path}`)
|
||
|
}
|
||
|
|
||
|
return processResult(ctx, result)
|
||
|
})
|
||
|
})
|
||
|
|
||
|
rc.sync = withTypeScriptLoader((ctx, path, options) => {
|
||
|
/**
|
||
|
* @type {Object} The full Config Context
|
||
|
*/
|
||
|
ctx = createContext(ctx)
|
||
|
|
||
|
/**
|
||
|
* @type {String} `process.cwd()`
|
||
|
*/
|
||
|
path = path ? resolve(path) : process.cwd()
|
||
|
|
||
|
const result = config.lilconfigSync('postcss', options).search(path)
|
||
|
|
||
|
if (!result) {
|
||
|
throw new Error(`No PostCSS Config found in: ${path}`)
|
||
|
}
|
||
|
|
||
|
return processResult(ctx, result)
|
||
|
})
|
||
|
|
||
|
/**
|
||
|
* Autoload Config for PostCSS
|
||
|
*
|
||
|
* @author Michael Ciniawsky @michael-ciniawsky <michael.ciniawsky@gmail.com>
|
||
|
* @license MIT
|
||
|
*
|
||
|
* @module postcss-load-config
|
||
|
* @version 2.1.0
|
||
|
*
|
||
|
* @requires comsiconfig
|
||
|
* @requires ./options
|
||
|
* @requires ./plugins
|
||
|
*/
|
||
|
module.exports = rc
|