Skip to content

Commit cd6bd7f

Browse files
committed
feat(@angular/cli): allow component css imports
Fix #4285
1 parent d22e9ae commit cd6bd7f

File tree

8 files changed

+84
-163
lines changed

8 files changed

+84
-163
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"ember-cli-normalize-entity-name": "^1.0.0",
5656
"ember-cli-string-utils": "^1.0.0",
5757
"enhanced-resolve": "^3.1.0",
58+
"exports-loader": "^0.6.3",
5859
"extract-text-webpack-plugin": "^2.0.0-rc.3",
5960
"file-loader": "^0.10.0",
6061
"findup": "0.1.5",

packages/@angular/cli/models/webpack-configs/styles.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -86,21 +86,27 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
8686
}
8787
];
8888

89-
const commonLoaders = ['postcss-loader'];
89+
const commonLoaders = [
90+
// css-loader doesn't support webpack.LoaderOptionsPlugin properly,
91+
// so we need to add options in its query
92+
`css-loader?${JSON.stringify({ sourceMap: cssSourceMap })}`,
93+
'postcss-loader'
94+
];
9095

9196
// load component css as raw strings
9297
let rules: any = baseRules.map(({test, loaders}) => ({
93-
exclude: globalStylePaths, test, loaders: ['raw-loader', ...commonLoaders, ...loaders]
98+
exclude: globalStylePaths, test, loaders: [
99+
'exports-loader?module.exports.toString()',
100+
...commonLoaders,
101+
...loaders
102+
]
94103
}));
95104

96105
// load global css as css files
97106
if (globalStylePaths.length > 0) {
98107
rules.push(...baseRules.map(({test, loaders}) => ({
99108
include: globalStylePaths, test, loaders: ExtractTextPlugin.extract({
100109
use: [
101-
// css-loader doesn't support webpack.LoaderOptionsPlugin properly,
102-
// so we need to add options in its query
103-
`css-loader?${JSON.stringify({ sourceMap: cssSourceMap })}`,
104110
...commonLoaders,
105111
...loaders
106112
],

packages/@angular/cli/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"diff": "^3.1.0",
4040
"ember-cli-normalize-entity-name": "^1.0.0",
4141
"ember-cli-string-utils": "^1.0.0",
42+
"exports-loader": "^0.6.3",
4243
"extract-text-webpack-plugin": "^2.0.0-rc.3",
4344
"file-loader": "^0.10.0",
4445
"findup": "0.1.5",

tests/e2e/tests/build/styles/css.ts

-32
This file was deleted.
+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import {
2+
writeMultipleFiles,
3+
deleteFile,
4+
expectFileToMatch,
5+
replaceInFile
6+
} from '../../../utils/fs';
7+
import { expectToFail } from '../../../utils/utils';
8+
import { ng } from '../../../utils/process';
9+
import { stripIndents } from 'common-tags';
10+
import { updateJsonFile } from '../../../utils/project';
11+
12+
export default function () {
13+
const extensions = ['css', 'scss', 'less', 'styl'];
14+
let promise = Promise.resolve();
15+
16+
extensions.forEach(ext => {
17+
promise = promise.then(() => {
18+
return writeMultipleFiles({
19+
[`src/styles.${ext}`]: stripIndents`
20+
@import './imported-styles.${ext}';
21+
body { background-color: #00f; }
22+
`,
23+
[`src/imported-styles.${ext}`]: stripIndents`
24+
p { background-color: #f00; }
25+
`,
26+
[`src/app/app.component.${ext}`]: stripIndents`
27+
@import './imported-component-styles.${ext}';
28+
.outer {
29+
.inner {
30+
background: #fff;
31+
}
32+
}
33+
`,
34+
[`src/imported-component-styles.${ext}`]: stripIndents`
35+
h1 { background: #000; }
36+
`})
37+
.then(() => deleteFile('src/app/app.component.css'))
38+
// change files to use preprocessor
39+
.then(() => updateJsonFile('angular-cli.json', configJson => {
40+
const app = configJson['apps'][0];
41+
app['styles'] = [`styles.${ext}`];
42+
}))
43+
.then(() => replaceInFile('src/app/app.component.ts',
44+
'./app.component.css', `./app.component.${ext}`))
45+
// run build app
46+
.then(() => ng('build', '--extract-css', '--sourcemap'))
47+
// verify global styles
48+
.then(() => expectFileToMatch('dist/styles.bundle.css',
49+
/body\s*{\s*background-color: #00f;\s*}/))
50+
.then(() => expectFileToMatch('dist/styles.bundle.css',
51+
/p\s*{\s*background-color: #f00;\s*}/))
52+
// verify global styles sourcemap
53+
.then(() => expectToFail(() =>
54+
expectFileToMatch('dist/styles.bundle.css', '"mappings":""')))
55+
// verify component styles
56+
.then(() => expectFileToMatch('dist/main.bundle.js',
57+
/.outer.*.inner.*background:\s*#[fF]+/))
58+
.then(() => expectFileToMatch('dist/main.bundle.js',
59+
/h1.*background:\s*#000+/))
60+
// change files back
61+
.then(() => updateJsonFile('angular-cli.json', configJson => {
62+
const app = configJson['apps'][0];
63+
app['styles'] = ['styles.css'];
64+
}))
65+
.then(() => replaceInFile('src/app/app.component.ts',
66+
`./app.component.${ext}`, './app.component.css'));
67+
});
68+
});
69+
70+
return promise;
71+
}

tests/e2e/tests/build/styles/less.ts

-42
This file was deleted.

tests/e2e/tests/build/styles/scss.ts

-42
This file was deleted.

tests/e2e/tests/build/styles/stylus.ts

-42
This file was deleted.

0 commit comments

Comments
 (0)