Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement/issue 426 restore userland postcss #453

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
Expand Down
20 changes: 16 additions & 4 deletions packages/cli/src/config/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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 });

Expand Down
4 changes: 3 additions & 1 deletion packages/cli/src/lifecycles/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -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/');
Expand All @@ -19,7 +20,8 @@ module.exports = initContexts = async({ config }) => {
userWorkspace,
pagesDir,
userTemplatesDir,
scratchDir
scratchDir,
projectDirectory
};

if (!fs.existsSync(scratchDir)) {
Expand Down
18 changes: 16 additions & 2 deletions packages/cli/src/transforms/transform.css.js
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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;
}
}

// <style> tag used
if (destHeader === 'style') {
contentType = 'text/css';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
/*
* Use Case
* Run Greenwood with a custom postcss config
* Run Greenwood with a custom PostCSS config
*
* User Result
* Should generate a bare bones Greenwood build with a hello page containing a component with a
* @custom-media query
* Should generate a bare bones Greenwood build with the user's CSS file correctly un-nested and minified
*
* User Command
* greenwood build
Expand All @@ -13,16 +12,18 @@
* Greenwood default
* src/
* pages/
* hello.md
* index.md
* index.html
* styles/
* main.css
*/
const { JSDOM } = require('jsdom');
const fs = require('fs');
const glob = require('glob-promise');
const path = require('path');
const expect = require('chai').expect;
const runSmokeTest = require('../../../../../test/smoke-test');
const TestBed = require('../../../../../test/test-bed');

xdescribe('Build Greenwood With: ', function() {
describe('Build Greenwood With: ', function() {
const LABEL = 'Custom PostCSS configuration';
let setup;

Expand All @@ -37,27 +38,17 @@ xdescribe('Build Greenwood With: ', function() {
await setup.runGreenwoodCommand('build');
});

runSmokeTest(['public', 'index', 'not-found', 'hello'], LABEL);
// TODO runSmokeTest(['public', 'index', 'not-found'], LABEL);
runSmokeTest(['public', 'index'], LABEL);

describe('Hello page with working @custom-media queries', function() {
let dom;
describe('Page referencing external nested CSS file', function() {
it('should output correctly processed nested CSS as non nested', function() {
const expectedCss = 'body{color:red}body h1{color:#00f}';
const cssFiles = glob.sync(path.join(this.context.publicDir, 'styles', '*.css'));
const css = fs.readFileSync(cssFiles[0], 'utf-8');

beforeEach(async function() {
dom = await JSDOM.fromFile(path.resolve(this.context.publicDir, './hello/index.html'));
});

it('should resolve the correct @custom-media queries for eve-container', function() {
// check @media (--screen-xs) resolves to @media (max-width:576px) via postcss preset-env: stage 1
const expectedStyle = 'eve-container .container.eve-container,eve-container ' +
'.container-fluid.eve-container {\n margin-right:auto;margin-left:auto;padding-left:15px;' +
'padding-right:15px\n}\n\n@media (max-width:576px) {\neve-container .container.eve-container ' +
'{\n width:calc(100% - 30px)\n}\n\n}\n\n@media (min-width:576px) {\neve-container ' +
'.container.eve-container {\n width:540px\n}\n\n}\n\n@media (min-width:768px) {\neve-container ' +
'.container.eve-container {\n width:720px\n}\n\n}\n\n@media (min-width:992px) {\neve-container ' +
'.container.eve-container {\n width:960px\n}\n\n}\n\n@media (min-width:1200px) {\neve-container ' +
'.container.eve-container {\n width:1140px\n}\n\n}';
const containerStyle = dom.window.document.head.querySelector('style[scope="eve-container"]');
expect(containerStyle.innerHTML).to.equal(expectedStyle);
expect(cssFiles.length).to.equal(1);
expect(css).to.equal(expectedCss);
});
});
});
Expand Down
10 changes: 3 additions & 7 deletions packages/cli/test/cases/build.config.postcss/postcss.config.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
module.exports = {
plugins: {
'postcss-preset-env': {
stage: 1
},
'postcss-nested': {},
'cssnano': {}
}
plugins: [
require('postcss-nested')
]
};
11 changes: 0 additions & 11 deletions packages/cli/test/cases/build.config.postcss/src/pages/hello.md

This file was deleted.

12 changes: 12 additions & 0 deletions packages/cli/test/cases/build.config.postcss/src/pages/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en" prefix="og:http://ogp.me/ns#">

<head>
<link rel="stylesheet" href="/styles/main.css"></link>
</head>

<body>
<h1>Hello World!</h1>
</body>

</html>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
body {
color: red;

& h1 {
color: blue;
}

}
10 changes: 3 additions & 7 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
module.exports = {
// plugins: {
// 'postcss-preset-env': {
// stage: 1
// },
// 'postcss-nested': {},
// 'cssnano': {}
// }
plugins: [
require('postcss-nested')
]
};
113 changes: 57 additions & 56 deletions www/components/banner/banner.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* TODO restore to nested styles */
@keyframes fadeOut {
from {
opacity: 1;
Expand All @@ -19,73 +18,75 @@
}
}

:host .banner {
background-color: #F6F2F4;
min-height: 60vh;
}

:host .content {
padding: 5vh 10px;
font-size:1.7rem;
text-align:center;
}

:host .content hr {
border-radius:25px;
border-style:none;
height:3px;
margin:0 auto;
background-color:white;
border:1px solid rgba(0, 0, 0, 0.6);
width: 160px;
}

:host .content h1 {
font-size:3.5rem;
text-shadow: 1px 1px rgba(0, 0, 0, 0.6);
}

:host .content h3 {
padding-top: 10px;
text-shadow: 1px 1px rgba(0, 0, 0, 0.6);
}

:host .content img {
width: 300px;
height: 300px;
}

:host .content span.off {
animation: 1s fadeOut ease-in-out;
}

:host .content span.on {
animation: 1s fadeIn linear;
}
:host {

/* @media (max-width: 980px) {
& .banner {
min-height: 40vh;
background-color: #F6F2F4;
min-height: 60vh;

& .content {
font-size: 1.5rem;
padding: 5vh 10px;
font-size:1.7rem;
text-align:center;

& hr {
border-radius:25px;
border-style:none;
height:3px;
margin:0 auto;
background-color:white;
border:1px solid rgba(0, 0, 0, 0.6);
width: 160px;
}

& h1 {
font-size: 3rem;
font-size:3.5rem;
text-shadow: 1px 1px rgba(0, 0, 0, 0.6);
}
& h3 {
padding-top: 10px;
text-shadow: 1px 1px rgba(0, 0, 0, 0.6);
}

& img {
width: 250px;
height: 250px;
width: 300px;
height: 300px;
}
}

& span.off {
animation: 1s fadeOut ease-in-out;
}

& span.on {
animation: 1s fadeIn linear;
}
}
}

@media (max-width: 756px) {
& .banner {
padding:0px;
@media (max-width: 980px) {
& .banner {
min-height: 40vh;

& .content {
margin-top: 0;
font-size: 1.5rem;
& h1 {
font-size: 3rem;
}
& img {
width: 250px;
height: 250px;
}
}
}
}

@media (max-width: 756px) {
& .banner {
padding:0px;

& .content {
margin-top: 0;
}
}
}
} */
}
Loading