Skip to content

Commit 15f1e15

Browse files
kevinkacetivac
authored andcommitted
feat: Update Webpack plugin to accept existing processor (#535)
1 parent 6d29447 commit 15f1e15

File tree

4 files changed

+186
-25
lines changed

4 files changed

+186
-25
lines changed

packages/webpack/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ This package contains two entry points, you will need to use **both** in tandem
1717
- [Usage](#usage)
1818
- [Options](#options)
1919

20+
## Install
21+
22+
```bash
23+
> npm i @modular-css/webpack
24+
```
25+
2026
## Usage
2127

2228
```js
@@ -58,6 +64,10 @@ Location to write the generated CSS file to, relative to `output.path` just like
5864

5965
Location to write out the JSON mapping file to, relative to `output.path` just like `output.filename`
6066

67+
#### `processor`
68+
69+
Pass an already-instantiated `Processor` instance to the Webpack plugin. It will then add any files found when traversing the modules to it and both the Webpack-discovered and any already-existing files will be output in the final CSS.
70+
6171
#### Shared Options
6272

6373
All other options are passed to the underlying `Processor` instance, see [Options](../processor/README.md#options).

packages/webpack/plugin.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function ModularCSS(args) {
2626
}
2727

2828
this.prev = {};
29-
this.processor = new Processor(options);
29+
this.processor = options.processor || new Processor(options);
3030
this.options = options;
3131
}
3232

@@ -47,10 +47,10 @@ ModularCSS.prototype.apply = function(compiler) {
4747
// Runs before compilation begins
4848
compiler.plugin("this-compilation", (compilation) => {
4949
var files;
50-
50+
5151
// Make processor instance available to the loader
5252
compilation.options.processor = this.processor;
53-
53+
5454
// This code is only useful when calling .run() multiple times
5555
// watching handles its own invalidations
5656
if(!watching) {
@@ -66,7 +66,7 @@ ModularCSS.prototype.apply = function(compiler) {
6666

6767
// Remove changed/removed files from processor instance
6868
this.processor.remove(files);
69-
69+
7070
this.prev = compilation.fileTimestamps;
7171
}
7272
});
@@ -86,15 +86,15 @@ ModularCSS.prototype.apply = function(compiler) {
8686
new sources.RawSource(
8787
data.css
8888
);
89-
89+
9090
// Write out external source map if it exists
9191
if(data.map) {
9292
compilation.assets[`${this.options.css}.map`] = new sources.RawSource(
9393
data.map.toString()
9494
);
9595
}
9696
}
97-
97+
9898
if(this.options.json) {
9999
compilation.assets[this.options.json] = new sources.RawSource(
100100
JSON.stringify(data.compositions, null, 4)

packages/webpack/test/__snapshots__/webpack.test.js.snap

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,129 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`/webpack.js should accept an existing processor instance 1`] = `
4+
"/******/ (function(modules) { // webpackBootstrap
5+
/******/ // The module cache
6+
/******/ var installedModules = {};
7+
/******/
8+
/******/ // The require function
9+
/******/ function __webpack_require__(moduleId) {
10+
/******/
11+
/******/ // Check if module is in cache
12+
/******/ if(installedModules[moduleId]) {
13+
/******/ return installedModules[moduleId].exports;
14+
/******/ }
15+
/******/ // Create a new module (and put it into the cache)
16+
/******/ var module = installedModules[moduleId] = {
17+
/******/ i: moduleId,
18+
/******/ l: false,
19+
/******/ exports: {}
20+
/******/ };
21+
/******/
22+
/******/ // Execute the module function
23+
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
24+
/******/
25+
/******/ // Flag the module as loaded
26+
/******/ module.l = true;
27+
/******/
28+
/******/ // Return the exports of the module
29+
/******/ return module.exports;
30+
/******/ }
31+
/******/
32+
/******/
33+
/******/ // expose the modules object (__webpack_modules__)
34+
/******/ __webpack_require__.m = modules;
35+
/******/
36+
/******/ // expose the module cache
37+
/******/ __webpack_require__.c = installedModules;
38+
/******/
39+
/******/ // define getter function for harmony exports
40+
/******/ __webpack_require__.d = function(exports, name, getter) {
41+
/******/ if(!__webpack_require__.o(exports, name)) {
42+
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
43+
/******/ }
44+
/******/ };
45+
/******/
46+
/******/ // define __esModule on exports
47+
/******/ __webpack_require__.r = function(exports) {
48+
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
49+
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
50+
/******/ }
51+
/******/ Object.defineProperty(exports, '__esModule', { value: true });
52+
/******/ };
53+
/******/
54+
/******/ // create a fake namespace object
55+
/******/ // mode & 1: value is a module id, require it
56+
/******/ // mode & 2: merge all properties of value into the ns
57+
/******/ // mode & 4: return value when already ns object
58+
/******/ // mode & 8|1: behave like require
59+
/******/ __webpack_require__.t = function(value, mode) {
60+
/******/ if(mode & 1) value = __webpack_require__(value);
61+
/******/ if(mode & 8) return value;
62+
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
63+
/******/ var ns = Object.create(null);
64+
/******/ __webpack_require__.r(ns);
65+
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
66+
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
67+
/******/ return ns;
68+
/******/ };
69+
/******/
70+
/******/ // getDefaultExport function for compatibility with non-harmony modules
71+
/******/ __webpack_require__.n = function(module) {
72+
/******/ var getter = module && module.__esModule ?
73+
/******/ function getDefault() { return module['default']; } :
74+
/******/ function getModuleExports() { return module; };
75+
/******/ __webpack_require__.d(getter, 'a', getter);
76+
/******/ return getter;
77+
/******/ };
78+
/******/
79+
/******/ // Object.prototype.hasOwnProperty.call
80+
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
81+
/******/
82+
/******/ // __webpack_public_path__
83+
/******/ __webpack_require__.p = \\"\\";
84+
/******/
85+
/******/
86+
/******/ // Load entry module and return exports
87+
/******/ return __webpack_require__(__webpack_require__.s = \\"./packages/webpack/test/specimens/simple.js\\");
88+
/******/ })
89+
/************************************************************************/
90+
/******/ ({
91+
92+
/***/ \\"./packages/webpack/test/specimens/simple.css\\":
93+
/*!****************************************************!*\\\\
94+
!*** ./packages/webpack/test/specimens/simple.css ***!
95+
\\\\****************************************************/
96+
/*! exports provided: default, wooga */
97+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
98+
99+
\\"use strict\\";
100+
eval(\\"__webpack_require__.r(__webpack_exports__);\\\\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \\\\\\"wooga\\\\\\", function() { return wooga; });\\\\n/* harmony default export */ __webpack_exports__[\\\\\\"default\\\\\\"] = ({\\\\n \\\\\\"wooga\\\\\\": \\\\\\"mc8d99986b_wooga\\\\\\"\\\\n});\\\\nvar wooga = \\\\\\"mc8d99986b_wooga\\\\\\";\\\\n\\\\n//# sourceURL=webpack:///./packages/webpack/test/specimens/simple.css?\\");
101+
102+
/***/ }),
103+
104+
/***/ \\"./packages/webpack/test/specimens/simple.js\\":
105+
/*!***************************************************!*\\\\
106+
!*** ./packages/webpack/test/specimens/simple.js ***!
107+
\\\\***************************************************/
108+
/*! no static exports found */
109+
/***/ (function(module, exports, __webpack_require__) {
110+
111+
eval(\\"__webpack_require__(/*! ./simple.css */ \\\\\\"./packages/webpack/test/specimens/simple.css\\\\\\");\\\\n\\\\n\\\\n//# sourceURL=webpack:///./packages/webpack/test/specimens/simple.js?\\");
112+
113+
/***/ })
114+
115+
/******/ });"
116+
`;
117+
118+
exports[`/webpack.js should accept an existing processor instance 2`] = `
119+
"/* packages/webpack/test/specimens/fake.css */
120+
.mc89f5ebd2_fake {
121+
color: yellow;
122+
}
123+
/* packages/webpack/test/specimens/simple.css */
124+
.mc8d99986b_wooga { color: red; }"
125+
`;
126+
3127
exports[`/webpack.js should generate correct builds in watch mode when files change 1`] = `
4128
"/******/ (function(modules) { // webpackBootstrap
5129
/******/ // The module cache

packages/webpack/test/webpack.test.js

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
/* eslint-disable max-statements */
22
"use strict";
33

4-
var fs = require("fs"),
5-
path = require("path"),
4+
const fs = require("fs");
5+
const path = require("path");
66

7-
webpack = require("webpack"),
8-
shell = require("shelljs"),
7+
const webpack = require("webpack");
8+
const dedent = require("dedent");
9+
const shell = require("shelljs");
910

10-
read = require("@modular-css/test-utils/read.js")(__dirname),
11-
namer = require("@modular-css/test-utils/namer.js"),
12-
13-
Plugin = require("../plugin.js"),
11+
const read = require("@modular-css/test-utils/read.js")(__dirname);
12+
const namer = require("@modular-css/test-utils/namer.js");
1413

15-
output = path.resolve(__dirname, "./output"),
16-
loader = require.resolve("../loader.js"),
17-
test = /\.css$/;
14+
const Processor = require("@modular-css/processor");
15+
16+
const Plugin = require("../plugin.js");
17+
18+
const output = path.resolve(__dirname, "./output");
19+
const loader = require.resolve("../loader.js");
20+
const test = /\.css$/;
1821

1922
function success(err, stats) {
2023
expect(err).toBeFalsy();
@@ -207,7 +210,7 @@ describe("/webpack.js", () => {
207210
it("should generate correct builds in watch mode when files change", (done) => {
208211
var changed = 0,
209212
compiler, watcher;
210-
213+
211214
// Create v1 of the file
212215
fs.writeFileSync(
213216
path.join(__dirname, "./output/watched.css"),
@@ -224,10 +227,10 @@ describe("/webpack.js", () => {
224227
// w/o it the build freezes forever!
225228
setTimeout(done, 50);
226229
});
227-
230+
228231
watcher = compiler.watch(null, (err, stats) => {
229232
changed++;
230-
233+
231234
success(err, stats);
232235

233236
expect(read("output.js")).toMatchSnapshot();
@@ -247,18 +250,18 @@ describe("/webpack.js", () => {
247250
it("should generate correct builds when files change", () => {
248251
var changed = "./packages/webpack/test/output/changed.css",
249252
compiler;
250-
253+
251254
// wrap compiler.run in a promise for easier chaining
252255
function run() {
253256
return new Promise((resolve, reject) =>
254257
compiler.run((err, stats) => {
255258
if(stats.hasErrors()) {
256259
return reject(stats);
257260
}
258-
261+
259262
expect(read("output.js")).toMatchSnapshot();
260263
expect(read("output.css")).toMatchSnapshot();
261-
264+
262265
return resolve(stats);
263266
})
264267
);
@@ -267,7 +270,7 @@ describe("/webpack.js", () => {
267270
compiler = webpack(config({
268271
entry : "./packages/webpack/test/specimens/change.js",
269272
}));
270-
273+
271274
// Create v1 of the file
272275
fs.writeFileSync(changed, ".one { color: red; }");
273276

@@ -287,10 +290,34 @@ describe("/webpack.js", () => {
287290
// This build fails because the file is missing
288291
.catch((stats) => {
289292
expect(stats.toJson().errors[0]).toMatch("no such file or directory");
290-
293+
291294
fs.writeFileSync(changed, ".three { color: green; }");
292295

293296
return run();
294297
});
295298
});
299+
300+
it("should accept an existing processor instance", async (done) => {
301+
const processor = new Processor();
302+
303+
await processor.string("./packages/webpack/test/specimens/fake.css", dedent(`
304+
.fake {
305+
color: yellow;
306+
}
307+
`));
308+
309+
webpack(config({
310+
entry : "./packages/webpack/test/specimens/simple.js",
311+
plugin : {
312+
processor
313+
},
314+
}), (err, stats) => {
315+
success(err, stats);
316+
317+
expect(read("output.js")).toMatchSnapshot();
318+
expect(read("output.css")).toMatchSnapshot();
319+
320+
done();
321+
});
322+
});
296323
});

0 commit comments

Comments
 (0)