Skip to content

Commit

Permalink
Add support for .postcss files
Browse files Browse the repository at this point in the history
  • Loading branch information
Lyrkan committed Jun 19, 2019
1 parent cb36619 commit f42da34
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 5 deletions.
1 change: 1 addition & 0 deletions fixtures/css/postcss_extension.postcss
@@ -0,0 +1 @@
@import "autoprefixer_test.css";
15 changes: 14 additions & 1 deletion fixtures/vuejs-css-modules/App.vue
@@ -1,5 +1,5 @@
<template>
<div id="app" class="red large justified lowercase" :class="[$css.italic, $scss.bold, $less.underline, $stylus.rtl]"></div>
<div id="app" class="red large justified lowercase block" :class="[$css.italic, $scss.bold, $less.underline, $stylus.rtl, $postcss.hidden]"></div>
</template>

<style>
Expand All @@ -25,6 +25,13 @@
text-transform: lowercase
</style>
<style lang="postcss">
.block {
display: block;
}
</style>


<style module="$css">
.italic {
font-style: italic;
Expand All @@ -46,4 +53,10 @@
<style lang="styl" module="$stylus">
.rtl
direction: rtl;
</style>
<style lang="postcss" module="$postcss">
.hidden {
visibility: hidden;
}
</style>
13 changes: 11 additions & 2 deletions lib/config-generator.js
Expand Up @@ -236,6 +236,15 @@ class ConfigGenerator {
return applyOptionsCallback(this.webpackConfig.loaderConfigurationCallbacks[name], defaultRules);
};

// When the PostCSS loader is enabled, allow to use
// files with the `.postcss` extension. It also
// makes it possible to use `lang="postcss"` in Vue
// files.
const cssExtensions = ['css'];
if (this.webpackConfig.usePostCssLoader) {
cssExtensions.push('postcss');
}

let rules = [
applyRuleConfigurationCallback('javascript', {
// match .js and .jsx
Expand All @@ -246,9 +255,9 @@ class ConfigGenerator {
applyRuleConfigurationCallback('css', {
resolve: {
mainFields: ['style', 'main'],
extensions: ['.css'],
extensions: cssExtensions.map(ext => `.${ext}`),
},
test: /\.css$/,
test: new RegExp(`\\.(${cssExtensions.join('|')})$`),
oneOf: [
{
resourceQuery: /module/,
Expand Down
40 changes: 39 additions & 1 deletion test/config-generator.js
Expand Up @@ -1052,7 +1052,7 @@ describe('The config-generator function', () => {
});

const webpackConfig = configGenerator(config);
const rule = findRule(/\.css$/, webpackConfig.module.rules);
const rule = findRule(/\.(css)$/, webpackConfig.module.rules);

expect(rule.camelCase).to.be.true;
});
Expand Down Expand Up @@ -1210,4 +1210,42 @@ describe('The config-generator function', () => {
expect(rule.use[0].options.fooBar).to.be.equal('fooBar');
});
});

describe('enablePostCssLoader() makes the CSS rule process .postcss file', () => {
it('without enablePostCssLoader()', () => {
const config = createConfig();
config.outputPath = '/tmp/output/public-path';
config.publicPath = '/public-path';
config.enableSingleRuntimeChunk();
config.addEntry('main', './main');
// do not call disableImagesLoader

const actualConfig = configGenerator(config);

expect(function() {
findRule(/\.(css)$/, actualConfig.module.rules);
}).not.to.throw();
expect(function() {
findRule(/\.(css|postcss)$/, actualConfig.module.rules);
}).to.throw();
});

it('with enablePostCssLoader()', () => {
const config = createConfig();
config.outputPath = '/tmp/output/public-path';
config.publicPath = '/public-path';
config.addEntry('main', './main');
config.enableSingleRuntimeChunk();
config.enablePostCssLoader();

const actualConfig = configGenerator(config);

expect(function() {
findRule(/\.(css)$/, actualConfig.module.rules);
}).to.throw();
expect(function() {
findRule(/\.(css|postcss)$/, actualConfig.module.rules);
}).to.not.throw();
});
});
});
27 changes: 26 additions & 1 deletion test/functional.js
Expand Up @@ -948,6 +948,7 @@ module.exports = {
// load a file that @import's another file, so that we can
// test that @import resources are parsed through postcss
config.addStyleEntry('styles', ['./css/imports_autoprefixer.css']);
config.addStyleEntry('postcss', './css/postcss_extension.postcss');
config.enablePostCssLoader();

testSetup.runWebpack(config, (webpackAssert) => {
Expand All @@ -957,6 +958,14 @@ module.exports = {
'-webkit-full-screen'
);

// check that the .postcss file was also processed
// correctly (it also @import the autoprefixer_test.css
// file)
webpackAssert.assertOutputFileContains(
'postcss.css',
'-webkit-full-screen'
);

done();
});
});
Expand Down Expand Up @@ -1421,7 +1430,7 @@ module.exports = {
});
});

it('Vue.js supports CSS/Sass/Less/Stylus modules', (done) => {
it('Vue.js supports CSS/Sass/Less/Stylus/PostCSS modules', (done) => {
const appDir = testSetup.createTestAppDir();
const config = testSetup.createWebpackConfig(appDir, 'www/build', 'dev');
config.enableSingleRuntimeChunk();
Expand All @@ -1437,6 +1446,18 @@ module.exports = {
options.localIdentName = '[local]_foo';
});

// Enable the PostCSS loader so we can use `lang="postcss"`
config.enablePostCssLoader();
fs.writeFileSync(
path.join(appDir, 'postcss.config.js'),
`
module.exports = {
plugins: [
require('autoprefixer')()
]
} `
);

testSetup.runWebpack(config, (webpackAssert) => {
expect(config.outputPath).to.be.a.directory().with.deep.files([
'main.js',
Expand All @@ -1457,11 +1478,13 @@ module.exports = {
expectClassDeclaration('large'); // Standard SCSS
expectClassDeclaration('justified'); // Standard Less
expectClassDeclaration('lowercase'); // Standard Stylus
expectClassDeclaration('block'); // Standard Postcss

expectClassDeclaration('italic_foo'); // CSS Module
expectClassDeclaration('bold_foo'); // SCSS Module
expectClassDeclaration('underline_foo'); // Less Module
expectClassDeclaration('rtl_foo'); // Stylus Module
expectClassDeclaration('hidden_foo'); // Stylus Module

testSetup.requestTestPage(
path.join(config.getContext(), 'www'),
Expand All @@ -1474,11 +1497,13 @@ module.exports = {
browser.assert.hasClass('#app', 'large'); // Standard SCSS
browser.assert.hasClass('#app', 'justified'); // Standard Less
browser.assert.hasClass('#app', 'lowercase'); // Standard Stylus
browser.assert.hasClass('#app', 'block'); // Standard Stylus

browser.assert.hasClass('#app', 'italic_foo'); // CSS module
browser.assert.hasClass('#app', 'bold_foo'); // SCSS module
browser.assert.hasClass('#app', 'underline_foo'); // Less module
browser.assert.hasClass('#app', 'rtl_foo'); // Stylus module
browser.assert.hasClass('#app', 'hidden_foo'); // Stylus module

done();
}
Expand Down

0 comments on commit f42da34

Please sign in to comment.