Skip to content

Commit 889a351

Browse files
committed
initial POC
1 parent e6c8c39 commit 889a351

File tree

11 files changed

+1890
-931
lines changed

11 files changed

+1890
-931
lines changed

.eslintignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
lib/
21
node_modules/
32
test/fixtures/
43
test/integration/

.prettierignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
**/coverage/**
2-
**/lib/**
32
**/fixtures/**
43
**/__file_snapshots__/**
54
**/flow-typed/**

lib/loader.js

Lines changed: 22 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
const Processor = require('@modular-css/processor');
2-
const path = require('path');
32
const { promisify } = require('util');
43
const { getOptions } = require('loader-utils');
5-
64
const getLocalName = require('./getLocalName');
75

86
const PROCESSOR = Symbol('@modular-css processor');
97
const CACHE = Symbol('loadModule cache module');
108

11-
129
function getLoadFilePrefix(loaderContext) {
1310
// loads a file with all loaders configured after this one
1411
const loadersRequest = loaderContext.loaders
@@ -24,73 +21,54 @@ function loader(src) {
2421
const cb = this.async();
2522

2623
const options = getOptions(this) || {};
27-
const dir = path.dirname(resourcePath);
2824

2925
const prefix = getLoadFilePrefix(this);
3026

3127
const loadFile = promisify((file, done) => {
3228
if (compilation[CACHE].has(file)) {
33-
return done(null, compilation[CACHE].get(file))
29+
done(null, compilation[CACHE].get(file));
30+
return;
3431
}
3532

3633
this.loadModule(`${prefix}${file}`, (err, moduleSource) => {
37-
const content = JSON.parse(moduleSource.toString())
34+
const content = JSON.parse(moduleSource.toString());
3835
// console.log('CACHE', file)
39-
compilation[CACHE].set(file, content)
36+
compilation[CACHE].set(file, content);
4037
done(err, content);
41-
})
42-
}
43-
);
38+
});
39+
});
4440

4541
if (!compilation[CACHE]) {
4642
compilation[CACHE] = new Map();
4743
}
44+
4845
if (!compilation[PROCESSOR]) {
4946
compilation[PROCESSOR] = new Processor({
5047
loadFile,
51-
namer: (filename, localName) => getLocalName(filename, localName, this, options),
48+
namer: (filename, localName) =>
49+
getLocalName(filename, localName, this, options),
50+
processing: [require('./plugins/icss-import-export')],
5251
});
5352
}
5453

5554
const processor = compilation[PROCESSOR];
5655

57-
const process = async () => {
58-
const { details, exports } = await processor.string(resourcePath, src);
59-
60-
const deps = processor.dependencies(resourcePath);
61-
62-
const icssImport = deps.reduce(
63-
(acc, dep) => `${acc}@import "${path.relative(dir, dep)}";\n`,
64-
'',
65-
);
66-
67-
let icssExport = ':export {\n';
68-
for (const [key, value] of Object.entries(exports)) {
69-
icssExport += ` ${key}: ${[].concat(value).join(' ')};\n`;
70-
}
71-
icssExport += '}';
72-
73-
74-
75-
return `${details.result.css}\n\n${icssImport}\n\n${icssExport}`;
76-
};
77-
78-
return process().then(
79-
r => cb(null, r),
56+
return processor.string(resourcePath, src).then(
57+
({ details }) => {
58+
const { result } = details;
59+
60+
cb(null, result.css, result.map, {
61+
ast: {
62+
type: 'postcss',
63+
version: result.processor.version,
64+
root: result.root,
65+
},
66+
});
67+
},
8068
err => {
8169
cb(err);
8270
},
8371
);
8472
}
8573

8674
module.exports = loader;
87-
88-
// module.exports.pitch = function pitch(remainingRequest) {
89-
// const cache = this._compilation[CACHE];
90-
91-
// if (cache && cache.has(this.resourcePath)) {
92-
// console.log('cache hit!', this.resourcePath)
93-
// return loader.call(this, cache.get(this.resourcePath))
94-
// // return cache.get(this.resourcePath)
95-
// }
96-
// }

lib/plugins/icss-import-export.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
const plugin = 'css-modules-loader-import/exports';
2+
const mapValues = require('lodash/mapValues');
3+
const findLast = require('lodash/findLast');
4+
const path = require('path');
5+
const postcss = require('postcss');
6+
7+
function getExports(file, messages, opts = {}) {
8+
const lastClsMsg = findLast(messages, 'classes');
9+
10+
return Object.assign(
11+
{},
12+
opts.exportValues ? mapValues(file.values, ({ value }) => value) : null,
13+
lastClsMsg.classes,
14+
...messages
15+
.filter(m => m.plugin && m.plugin.startsWith('modular-css-export'))
16+
.map(m => m.exports),
17+
);
18+
}
19+
20+
module.exports = (css, { opts, messages }) => {
21+
const { files, graph, from } = opts;
22+
23+
const file = files[from];
24+
25+
// We only want direct dependencies, since those will be required
26+
// in the css-loader output, the dep tree will be realized
27+
const imported = graph.outgoingEdges[from];
28+
const exported = getExports(file, messages, opts);
29+
30+
imported.forEach(dep =>
31+
css.prepend(
32+
postcss.rule({
33+
selector: `:import("${path.relative(path.dirname(from), dep)}")`,
34+
// We need a dummy value here so css-loader doesn't remove it
35+
// need to pick something that is not likely to match a word in the css tho
36+
nodes: [postcss.decl({ prop: '____a', value: 'a' })],
37+
}),
38+
),
39+
);
40+
41+
css.append(
42+
postcss.rule({
43+
selector: `:export`,
44+
nodes: Object.entries(exported).map(([prop, value]) =>
45+
postcss.decl({ prop, value: [].concat(value).join(' ') }),
46+
),
47+
}),
48+
);
49+
};
50+
51+
module.exports.postcssPlugin = plugin;

package.json

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@
2929
},
3030
"lint-staged": {
3131
"!(__file_snapshots__/)*.js": [
32-
"yarn 4c lint --fix",
33-
"git add"
32+
"yarn 4c lint --fix"
3433
]
3534
},
3635
"jest": {
@@ -46,35 +45,37 @@
4645
},
4746
"release": {},
4847
"devDependencies": {
49-
"@4c/cli": "^1.0.1",
48+
"@4c/cli": "^1.0.5",
5049
"@4c/import-sort": "^4.3.6",
51-
"@4c/jest-preset": "^1.3.0",
50+
"@4c/jest-preset": "^1.4.4",
5251
"@4c/prettier-config": "^1.1.0",
53-
"css-loader": "^3.2.0",
54-
"eslint": "^6.6.0",
55-
"eslint-config-4catalyzer": "^1.0.0",
56-
"eslint-config-4catalyzer-jest": "^2.0.1",
57-
"eslint-config-prettier": "^6.5.0",
58-
"eslint-plugin-import": "^2.8.0",
59-
"eslint-plugin-jest": "^23.0.2",
60-
"eslint-plugin-prettier": "^3.1.1",
61-
"husky": "^3.0.9",
62-
"jest": "^24.0.0",
63-
"jest-file-snapshot": "^0.3.7",
64-
"lint-staged": "^9.4.2",
65-
"mini-css-extract-plugin": "^0.8.0",
66-
"prettier": "^1.15.3",
67-
"sass": "^1.23.3",
68-
"strip-ansi": "^5.2.0"
52+
"css-loader": "^3.4.2",
53+
"eslint": "^6.8.0",
54+
"eslint-config-4catalyzer": "^1.0.2",
55+
"eslint-config-4catalyzer-jest": "^2.0.3",
56+
"eslint-config-prettier": "^6.10.0",
57+
"eslint-plugin-import": "^2.20.1",
58+
"eslint-plugin-jest": "^23.6.0",
59+
"eslint-plugin-prettier": "^3.1.2",
60+
"husky": "^4.2.1",
61+
"jest": "^25.1.0",
62+
"jest-file-snapshot": "^0.3.8",
63+
"lint-staged": "^10.0.7",
64+
"mini-css-extract-plugin": "^0.9.0",
65+
"prettier": "^1.19.1",
66+
"sass": "^1.25.0",
67+
"strip-ansi": "^6.0.0"
6968
},
7069
"dependencies": {
71-
"@modular-css/processor": "^25.2.0",
70+
"@modular-css/processor": "^25.3.1",
7271
"cssesc": "^3.0.0",
7372
"fs-extra": "^8.1.0",
7473
"loader-utils": "^1.2.3",
74+
"lodash": "^4.17.15",
7575
"memory-fs": "^0.5.0",
76-
"sass-loader": "^8.0.0",
77-
"webpack": "^4.41.2"
76+
"postcss": "^7.0.26",
77+
"sass-loader": "^8.0.2",
78+
"webpack": "^4.41.5"
7879
},
7980
"bugs": {
8081
"url": "https://github.com/4Catalyzer/css-module-loader/issues"

test/__file_snapshots__/nested-deps-js.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ __webpack_require__(/*! ./nested/three.scss */ "./test/fixtures/nested/three.scs
2222
/***/ (function(module, exports, __webpack_require__) {
2323

2424
// extracted by mini-css-extract-plugin
25-
module.exports = {"base":"one--base--2z77O"};
25+
module.exports = {"red":"rgb(255, 0 ,0)","base":"one--base--2z77O"};
2626

2727
/***/ }),
2828

@@ -46,7 +46,7 @@ module.exports = {"blue":"rgb(0, 0, 255)","inner":"three--inner--2a-T6"};
4646
/***/ (function(module, exports, __webpack_require__) {
4747

4848
// extracted by mini-css-extract-plugin
49-
module.exports = {"red":"rgb(255, 0 ,0)","base":"two--base--2113t"};
49+
module.exports = {"base":"two--base--2113t"};
5050

5151
/***/ })
5252

test/__file_snapshots__/nested-deps-styles.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
color: rgb(0, 0, 255);
44
}
55
.one--base--2z77O .three--inner--2a-T6 {
6-
color: red;
6+
color: rgb(255, 0 ,0);
77
}
88
.two--base--2113t .three--inner--2a-T6 {
9-
color: rgb(255, 0 ,0);
9+
color: red;
1010
}

test/__file_snapshots__/onlyLocals.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,52 @@
11
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["main"],{
22

3+
/***/ "./node_modules/css-loader/dist/cjs.js?!./lib/loader.js!./node_modules/sass-loader/dist/cjs.js?!./test/fixtures/common/base.scss":
4+
/*!*********************************************************************************************************************************************************!*\
5+
!*** ./node_modules/css-loader/dist/cjs.js??ref--4-0!./lib/loader.js!./node_modules/sass-loader/dist/cjs.js??ref--4-2!./test/fixtures/common/base.scss ***!
6+
\*********************************************************************************************************************************************************/
7+
/*! no static exports found */
8+
/***/ (function(module, exports) {
9+
10+
// Exports
11+
module.exports = {
12+
"base": "base--base--1uAtd"
13+
};
14+
15+
16+
/***/ }),
17+
18+
/***/ "./node_modules/css-loader/dist/cjs.js?!./lib/loader.js!./node_modules/sass-loader/dist/cjs.js?!./test/fixtures/common/button.scss":
19+
/*!***********************************************************************************************************************************************************!*\
20+
!*** ./node_modules/css-loader/dist/cjs.js??ref--4-0!./lib/loader.js!./node_modules/sass-loader/dist/cjs.js??ref--4-2!./test/fixtures/common/button.scss ***!
21+
\***********************************************************************************************************************************************************/
22+
/*! no static exports found */
23+
/***/ (function(module, exports, __webpack_require__) {
24+
25+
// Imports
26+
var ___CSS_LOADER_ICSS_IMPORT_0___ = __webpack_require__(/*! -!../../../node_modules/css-loader/dist/cjs.js??ref--4-0!../../../lib/loader.js!../../../node_modules/sass-loader/dist/cjs.js??ref--4-2!./base.scss */ "./node_modules/css-loader/dist/cjs.js?!./lib/loader.js!./node_modules/sass-loader/dist/cjs.js?!./test/fixtures/common/base.scss");
27+
// Exports
28+
module.exports = {
29+
"button": "base--base--1uAtd button--button--32Qrn"
30+
};
31+
32+
33+
/***/ }),
34+
335
/***/ "./test/fixtures/common/externals.scss":
436
/*!*********************************************!*\
537
!*** ./test/fixtures/common/externals.scss ***!
638
\*********************************************/
739
/*! no static exports found */
8-
/***/ (function(module, exports) {
40+
/***/ (function(module, exports, __webpack_require__) {
941

42+
// Imports
43+
var ___CSS_LOADER_ICSS_IMPORT_0___ = __webpack_require__(/*! -!../../../node_modules/css-loader/dist/cjs.js??ref--4-0!../../../lib/loader.js!../../../node_modules/sass-loader/dist/cjs.js??ref--4-2!./button.scss */ "./node_modules/css-loader/dist/cjs.js?!./lib/loader.js!./node_modules/sass-loader/dist/cjs.js?!./test/fixtures/common/button.scss");
1044
// Exports
1145
module.exports = {
1246
"toolbar": "externals--toolbar--3HGQb"
1347
};
1448

49+
1550
/***/ }),
1651

1752
/***/ "./test/fixtures/externals.js":

test/fixtures/nested/one.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
@import './theme.scss';
22

3+
@value red from './shared.scss';
4+
35
.base :external(inner from './three.scss') {
46
color: red;
57
}

test/fixtures/nested/two.scss

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
@import './theme.scss';
22

3-
@value red from './shared.scss';
4-
53
.base :external(inner from './three.scss') {
64
color: red;
75
}

0 commit comments

Comments
 (0)