Skip to content

Commit e798a23

Browse files
committed
add hack for imports
1 parent edcc5c8 commit e798a23

File tree

7 files changed

+80
-14
lines changed

7 files changed

+80
-14
lines changed

src/index.js

+33-14
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@ const { Template } = webpack;
99
const NS = path.dirname(fs.realpathSync(__filename));
1010

1111
class CssDependency extends webpack.Dependency {
12-
constructor({ identifier, content, media, sourceMap }, context) {
12+
constructor({ identifier, content, media, sourceMap }, context, identifierIndex) {
1313
super();
1414
this.identifier = identifier;
15+
this.identifierIndex = identifierIndex;
1516
this.content = content;
1617
this.media = media;
1718
this.sourceMap = sourceMap;
1819
this.context = context;
1920
}
2021

2122
getResourceIdentifier() {
22-
return `css-module-${this.identifier}`;
23+
return `css-module-${this.identifier}-${this.identifierIndex}`;
2324
}
2425
}
2526

@@ -31,6 +32,7 @@ class CssModule extends webpack.Module {
3132
constructor(dependency) {
3233
super(NS, dependency.context);
3334
this._identifier = dependency.identifier;
35+
this._identifierIndex = dependency.identifierIndex;
3436
this.content = dependency.content;
3537
this.media = dependency.media;
3638
this.sourceMap = dependency.sourceMap;
@@ -46,11 +48,11 @@ class CssModule extends webpack.Module {
4648
}
4749

4850
identifier() {
49-
return `css ${this._identifier}`;
51+
return `css ${this._identifier} ${this._identifierIndex}`;
5052
}
5153

5254
readableIdentifier(requestShortener) {
53-
return `css ${requestShortener.shorten(this._identifier)}`;
55+
return `css ${requestShortener.shorten(this._identifier)}${this._identifierIndex ? ` (${this._identifierIndex})` : ''}`;
5456
}
5557

5658
build(options, compilation, resolver, fileSystem, callback) {
@@ -86,8 +88,11 @@ class MiniCssExtractPlugin {
8688
if (!Array.isArray(content) && content != null) {
8789
throw new Error(`Exported value was not extracted as an array: ${JSON.stringify(content)}`);
8890
}
91+
const identifierCountMap = new Map();
8992
for (const line of content) {
90-
module.addDependency(new CssDependency(line, m.context));
93+
const count = identifierCountMap.get(line.identifier) || 0;
94+
module.addDependency(new CssDependency(line, m.context, count));
95+
identifierCountMap.set(line.identifier, count + 1);
9196
}
9297
};
9398
});
@@ -190,19 +195,33 @@ class MiniCssExtractPlugin {
190195

191196
renderContentAsset(modules) {
192197
modules.sort((a, b) => a.index2 - b.index2);
193-
// TODO put @import on top
194198
const source = new ConcatSource();
199+
const externalsSource = new ConcatSource();
195200
for (const m of modules) {
196-
if (m.media) {
197-
source.add(`@media ${m.media} {\n`);
198-
}
199-
source.add(m.content);
200-
source.add('\n');
201-
if (m.media) {
202-
source.add('}\n');
201+
if (/^@import url/.test(m.content)) {
202+
// HACK for IE
203+
// http://stackoverflow.com/a/14676665/1458162
204+
let { content } = m;
205+
if (m.media) {
206+
// insert media into the @import
207+
// this is rar
208+
// TODO improve this and parse the CSS to support multiple medias
209+
content = content.replace(/;|\s*$/, m.media);
210+
}
211+
externalsSource.add(content);
212+
externalsSource.add('\n');
213+
} else {
214+
if (m.media) {
215+
source.add(`@media ${m.media} {\n`);
216+
}
217+
source.add(m.content);
218+
source.add('\n');
219+
if (m.media) {
220+
source.add('}\n');
221+
}
203222
}
204223
}
205-
return source;
224+
return new ConcatSource(externalsSource, source);
206225
}
207226
}
208227

test/cases/import/a.css

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
body { background: red; }

test/cases/import/b.css

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.b { background: red; }
2+
3+
@import url("https://some/external/css");
4+
5+
.b { color: yellow; }

test/cases/import/c.css

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.c { background: red; }
2+
3+
@import url("https://some/other/external/css");
4+
5+
.c { color: yellow; }

test/cases/import/expected/main.css

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@import url(https://some/other/external/css);
2+
@import url(https://some/external/css);
3+
.c { background: red; }
4+
5+
.c { color: yellow; }
6+
7+
body { background: red; }
8+
9+
.b { background: red; }
10+
11+
.b { color: yellow; }
12+

test/cases/import/index.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import './c.css';
2+
import './a.css';
3+
import './b.css';

test/cases/import/webpack.config.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const Self = require('../../../');
2+
3+
module.exports = {
4+
entry: './index.js',
5+
module: {
6+
rules: [
7+
{
8+
test: /\.css$/,
9+
use: [
10+
Self.loader,
11+
'css-loader',
12+
],
13+
},
14+
],
15+
},
16+
plugins: [
17+
new Self({
18+
filename: '[name].css',
19+
}),
20+
],
21+
};

0 commit comments

Comments
 (0)