diff --git a/packages/cli/package.json b/packages/cli/package.json index cc3c13d57..214595afd 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -54,6 +54,7 @@ }, "devDependencies": { "@mapbox/rehype-prism": "^0.5.0", + "postcss-nested": "^4.1.2", "rehype-autolink-headings": "^4.0.0", "rehype-slug": "^3.0.0" } diff --git a/packages/cli/src/config/rollup.config.js b/packages/cli/src/config/rollup.config.js index c0db4860b..ca9cef812 100644 --- a/packages/cli/src/config/rollup.config.js +++ b/packages/cli/src/config/rollup.config.js @@ -33,7 +33,7 @@ function greenwoodWorkspaceResolver (compilation) { // https://github.com/rollup/rollup/issues/2873 function greenwoodHtmlPlugin(compilation) { - const { userWorkspace, outputDir } = compilation.context; + const { projectDirectory, userWorkspace, outputDir } = compilation.context; return { name: 'greenwood-html-plugin', @@ -117,15 +117,27 @@ function greenwoodHtmlPlugin(compilation) { } // this is a giant work around because PostCSS and some plugins can only be run async - // and so have to use with awit but _outside_ sync code, like parser / rollup + // and so have to use with await but _outside_ sync code, like parser / rollup // https://github.com/cssnano/cssnano/issues/68 // https://github.com/postcss/postcss/issues/595 // TODO consider similar approach for emitting chunks? return Promise.all(Object.keys(mappedStyles).map(async (assetKey) => { const asset = mappedStyles[assetKey]; const filePath = path.join(userWorkspace, asset.name); - - const result = await postcss(postcssConfig.plugins) + // TODO we already process the user's CSS as part of serve lifecycle (dev / build commands) + // if we pull from .greenwood/ then maybe we could avoid re-postcss step here? + const userPostcssConfig = fs.existsSync(`${projectDirectory}/postcss.config.js`) + ? require(`${projectDirectory}/postcss.config`) + : {}; + const userPostcssPlugins = userPostcssConfig.plugins && userPostcssConfig.plugins.length > 0 + ? userPostcssConfig.plugins + : []; + const allPostcssPlugins = [ + ...userPostcssPlugins, + ...postcssConfig.plugins + ]; + + const result = await postcss(allPostcssPlugins) .use(postcssImport()) .process(asset.source, { from: filePath }); diff --git a/packages/cli/src/lifecycles/context.js b/packages/cli/src/lifecycles/context.js index 79affdc01..d4190b17a 100644 --- a/packages/cli/src/lifecycles/context.js +++ b/packages/cli/src/lifecycles/context.js @@ -9,6 +9,7 @@ module.exports = initContexts = async({ config }) => { return new Promise(async (resolve, reject) => { try { + const projectDirectory = process.cwd(); const userWorkspace = path.join(config.workspace); const pagesDir = path.join(userWorkspace, 'pages/'); const userTemplatesDir = path.join(userWorkspace, 'templates/'); @@ -19,7 +20,8 @@ module.exports = initContexts = async({ config }) => { userWorkspace, pagesDir, userTemplatesDir, - scratchDir + scratchDir, + projectDirectory }; if (!fs.existsSync(scratchDir)) { diff --git a/packages/cli/src/transforms/transform.css.js b/packages/cli/src/transforms/transform.css.js index 4cd34a5af..8430d65b7 100644 --- a/packages/cli/src/transforms/transform.css.js +++ b/packages/cli/src/transforms/transform.css.js @@ -1,5 +1,6 @@ +const fs = require('fs'); const path = require('path'); -const { promises: fsp } = require('fs'); +const postcss = require('postcss'); const TransformInterface = require('./transform.interface'); class CSSTransform extends TransformInterface { @@ -18,9 +19,22 @@ class CSSTransform extends TransformInterface { ? path.join(process.cwd(), url) : path.join(this.workspace, url); - const css = await fsp.readFile(cssPath, 'utf-8'); + let css = await fs.promises.readFile(cssPath, 'utf-8'); let body = '', contentType = ''; + // TODO try and use context.projectDirectory + if (fs.existsSync(path.join(process.cwd(), 'postcss.config.js'))) { + const userPostcssConfig = require(`${process.cwd()}/postcss.config`); + const userPostcssPlugins = userPostcssConfig.plugins || []; + + if (userPostcssPlugins.length > 0) { + const result = await postcss(userPostcssPlugins) + .process(css, { from: cssPath }); + + css = result.css; + } + } + //