Skip to content

Commit f42da34

Browse files
committed
Add support for .postcss files
1 parent cb36619 commit f42da34

File tree

5 files changed

+91
-5
lines changed

5 files changed

+91
-5
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@import "autoprefixer_test.css";

fixtures/vuejs-css-modules/App.vue

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div id="app" class="red large justified lowercase" :class="[$css.italic, $scss.bold, $less.underline, $stylus.rtl]"></div>
2+
<div id="app" class="red large justified lowercase block" :class="[$css.italic, $scss.bold, $less.underline, $stylus.rtl, $postcss.hidden]"></div>
33
</template>
44

55
<style>
@@ -25,6 +25,13 @@
2525
text-transform: lowercase
2626
</style>
2727
28+
<style lang="postcss">
29+
.block {
30+
display: block;
31+
}
32+
</style>
33+
34+
2835
<style module="$css">
2936
.italic {
3037
font-style: italic;
@@ -46,4 +53,10 @@
4653
<style lang="styl" module="$stylus">
4754
.rtl
4855
direction: rtl;
56+
</style>
57+
58+
<style lang="postcss" module="$postcss">
59+
.hidden {
60+
visibility: hidden;
61+
}
4962
</style>

lib/config-generator.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,15 @@ class ConfigGenerator {
236236
return applyOptionsCallback(this.webpackConfig.loaderConfigurationCallbacks[name], defaultRules);
237237
};
238238

239+
// When the PostCSS loader is enabled, allow to use
240+
// files with the `.postcss` extension. It also
241+
// makes it possible to use `lang="postcss"` in Vue
242+
// files.
243+
const cssExtensions = ['css'];
244+
if (this.webpackConfig.usePostCssLoader) {
245+
cssExtensions.push('postcss');
246+
}
247+
239248
let rules = [
240249
applyRuleConfigurationCallback('javascript', {
241250
// match .js and .jsx
@@ -246,9 +255,9 @@ class ConfigGenerator {
246255
applyRuleConfigurationCallback('css', {
247256
resolve: {
248257
mainFields: ['style', 'main'],
249-
extensions: ['.css'],
258+
extensions: cssExtensions.map(ext => `.${ext}`),
250259
},
251-
test: /\.css$/,
260+
test: new RegExp(`\\.(${cssExtensions.join('|')})$`),
252261
oneOf: [
253262
{
254263
resourceQuery: /module/,

test/config-generator.js

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1052,7 +1052,7 @@ describe('The config-generator function', () => {
10521052
});
10531053

10541054
const webpackConfig = configGenerator(config);
1055-
const rule = findRule(/\.css$/, webpackConfig.module.rules);
1055+
const rule = findRule(/\.(css)$/, webpackConfig.module.rules);
10561056

10571057
expect(rule.camelCase).to.be.true;
10581058
});
@@ -1210,4 +1210,42 @@ describe('The config-generator function', () => {
12101210
expect(rule.use[0].options.fooBar).to.be.equal('fooBar');
12111211
});
12121212
});
1213+
1214+
describe('enablePostCssLoader() makes the CSS rule process .postcss file', () => {
1215+
it('without enablePostCssLoader()', () => {
1216+
const config = createConfig();
1217+
config.outputPath = '/tmp/output/public-path';
1218+
config.publicPath = '/public-path';
1219+
config.enableSingleRuntimeChunk();
1220+
config.addEntry('main', './main');
1221+
// do not call disableImagesLoader
1222+
1223+
const actualConfig = configGenerator(config);
1224+
1225+
expect(function() {
1226+
findRule(/\.(css)$/, actualConfig.module.rules);
1227+
}).not.to.throw();
1228+
expect(function() {
1229+
findRule(/\.(css|postcss)$/, actualConfig.module.rules);
1230+
}).to.throw();
1231+
});
1232+
1233+
it('with enablePostCssLoader()', () => {
1234+
const config = createConfig();
1235+
config.outputPath = '/tmp/output/public-path';
1236+
config.publicPath = '/public-path';
1237+
config.addEntry('main', './main');
1238+
config.enableSingleRuntimeChunk();
1239+
config.enablePostCssLoader();
1240+
1241+
const actualConfig = configGenerator(config);
1242+
1243+
expect(function() {
1244+
findRule(/\.(css)$/, actualConfig.module.rules);
1245+
}).to.throw();
1246+
expect(function() {
1247+
findRule(/\.(css|postcss)$/, actualConfig.module.rules);
1248+
}).to.not.throw();
1249+
});
1250+
});
12131251
});

test/functional.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,7 @@ module.exports = {
948948
// load a file that @import's another file, so that we can
949949
// test that @import resources are parsed through postcss
950950
config.addStyleEntry('styles', ['./css/imports_autoprefixer.css']);
951+
config.addStyleEntry('postcss', './css/postcss_extension.postcss');
951952
config.enablePostCssLoader();
952953

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

961+
// check that the .postcss file was also processed
962+
// correctly (it also @import the autoprefixer_test.css
963+
// file)
964+
webpackAssert.assertOutputFileContains(
965+
'postcss.css',
966+
'-webkit-full-screen'
967+
);
968+
960969
done();
961970
});
962971
});
@@ -1421,7 +1430,7 @@ module.exports = {
14211430
});
14221431
});
14231432

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

1449+
// Enable the PostCSS loader so we can use `lang="postcss"`
1450+
config.enablePostCssLoader();
1451+
fs.writeFileSync(
1452+
path.join(appDir, 'postcss.config.js'),
1453+
`
1454+
module.exports = {
1455+
plugins: [
1456+
require('autoprefixer')()
1457+
]
1458+
} `
1459+
);
1460+
14401461
testSetup.runWebpack(config, (webpackAssert) => {
14411462
expect(config.outputPath).to.be.a.directory().with.deep.files([
14421463
'main.js',
@@ -1457,11 +1478,13 @@ module.exports = {
14571478
expectClassDeclaration('large'); // Standard SCSS
14581479
expectClassDeclaration('justified'); // Standard Less
14591480
expectClassDeclaration('lowercase'); // Standard Stylus
1481+
expectClassDeclaration('block'); // Standard Postcss
14601482

14611483
expectClassDeclaration('italic_foo'); // CSS Module
14621484
expectClassDeclaration('bold_foo'); // SCSS Module
14631485
expectClassDeclaration('underline_foo'); // Less Module
14641486
expectClassDeclaration('rtl_foo'); // Stylus Module
1487+
expectClassDeclaration('hidden_foo'); // Stylus Module
14651488

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

14781502
browser.assert.hasClass('#app', 'italic_foo'); // CSS module
14791503
browser.assert.hasClass('#app', 'bold_foo'); // SCSS module
14801504
browser.assert.hasClass('#app', 'underline_foo'); // Less module
14811505
browser.assert.hasClass('#app', 'rtl_foo'); // Stylus module
1506+
browser.assert.hasClass('#app', 'hidden_foo'); // Stylus module
14821507

14831508
done();
14841509
}

0 commit comments

Comments
 (0)