Skip to content

Commit 212b5de

Browse files
committedJun 17, 2017
Clean up the webpack recipe
1 parent f228401 commit 212b5de

File tree

1 file changed

+65
-50
lines changed

1 file changed

+65
-50
lines changed
 

‎docs/recipes/precompiling-with-webpack.md

+65-50
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ The AVA [readme](https://github.com/avajs/ava#transpiling-imported-modules) ment
88
- [Multiple test files](#multiple-test-files)
99

1010
### Single test file
11+
1112
This is the simplest use case. You might need this if you are [using aliases](https://github.com/avajs/ava/issues/1011).
1213

13-
###### webpack.config.js
14+
###### `webpack.config.js`
1415

1516
```js
1617
const path = require('path');
@@ -25,11 +26,15 @@ module.exports = {
2526
},
2627
externals: [nodeExternals()],
2728
module: {
28-
rules: [{
29-
test: /\.(js|jsx)$/,
30-
use: 'babel-loader',
31-
options: { cacheDirectory: true }
32-
}]
29+
rules: [
30+
{
31+
test: /\.(js|jsx)$/,
32+
use: 'babel-loader',
33+
options: {
34+
cacheDirectory: true
35+
}
36+
}
37+
]
3338
}
3439
};
3540
```
@@ -39,6 +44,7 @@ The important bits are `target: 'node'`, which ignores Node.js-specific `require
3944
You can now run `$ ava _build/test.js` to run the tests contained in this output.
4045

4146
### Multiple test files
47+
4248
Things are a little more complicated with multiple test files. We recommend [using babel-register](babelrc.md) until the performance penalty becomes too great.
4349

4450
The possible approaches are:
@@ -49,6 +55,7 @@ The possible approaches are:
4955
- [Test against precompiled sources](#test-against-precompiled-sources)
5056

5157
#### Refer precompiled source in tests
58+
5259
Source files can be compiled to `_src` folder and referenced in tests. While this is less than elegant, it performs well and the workflow can be optimized with [`babel-cli` watch mode](https://babeljs.io/docs/usage/cli/#babel).
5360

5461
```js
@@ -59,16 +66,16 @@ import fresh from '../_src';
5966
```
6067

6168
#### Single entry file
62-
Multiple test files can be compiled into a single file. This may have the best performance but that does come at a cost. All tests will be in the same file, which can make it harder to know which test has failed, since AVA can't show the file name the test was originally in. You'll also lose [process isolation](https://github.com/avajs/ava#process-isolation).
6369

64-
###### webpack.config.js
70+
Multiple test files can be compiled into a single file. This may have the best performance, but it does come at a cost. All tests will be in the same file, which can make it harder to know which test has failed, since AVA can't show the file name the test was originally in. You'll also lose [process isolation](https://github.com/avajs/ava#process-isolation).
71+
72+
###### `webpack.config.js`
6573

66-
[Related stackoverflow answer](http://stackoverflow.com/questions/32874025/how-to-add-wildcard-mapping-in-entry-of-webpack/34545812#34545812)
74+
[Related Stack Overflow answer](http://stackoverflow.com/questions/32874025/how-to-add-wildcard-mapping-in-entry-of-webpack/34545812#34545812)
6775

6876
```js
6977
const path = require('path');
7078
const glob = require('glob');
71-
7279
const nodeExternals = require('webpack-node-externals');
7380

7481
module.exports = {
@@ -80,13 +87,17 @@ module.exports = {
8087
},
8188
externals: [nodeExternals()],
8289
module: {
83-
rules: [{
84-
test: /\.(js|jsx)$/,
85-
use: {
86-
loader: 'babel-loader',
87-
options: { cacheDirectory: true }
90+
rules: [
91+
{
92+
test: /\.(js|jsx)$/,
93+
use: {
94+
loader: 'babel-loader',
95+
options: {
96+
cacheDirectory: true
97+
}
98+
}
8899
}
89-
}]
100+
]
90101
}
91102
};
92103
```
@@ -134,25 +145,24 @@ module.exports = {
134145
}
135146
136147
```
137-
138148
</details>
139149

140150
#### Multiple entry files
141-
We can ask webpack to generate multiple entry files. This helps retain file names so that error reports are easy to interpret. But each entry file gets it's own copy of the source files. This results in considerably larger file sizes. This can [perform quite poorly](https://github.com/avajs/ava/pull/1385#issuecomment-304684047) on the first execution.
142151

143-
###### webpack.config.js
152+
We can ask webpack to generate multiple entry files. This helps retain file names so that error reports are easy to interpret. But each entry file gets its own copy of the source files. This results in considerably larger file sizes. This can [perform quite poorly](https://github.com/avajs/ava/pull/1385#issuecomment-304684047) on the first execution.
153+
154+
###### `webpack.config.js`
144155

145156
```js
146157
const path = require('path');
147158
const glob = require('glob');
148-
149159
const nodeExternals = require('webpack-node-externals');
150160

151161
const entryObj = glob.sync('./test/**/*.js')
152-
.reduce((acc, file) => {
153-
acc[path.basename(file, path.extname(file))] = file;
154-
return acc;
155-
}, {}); // empty object as initial value
162+
.reduce((acc, file) => {
163+
acc[path.basename(file, path.extname(file))] = file;
164+
return acc;
165+
}, {});
156166

157167
module.exports = {
158168
target: 'node',
@@ -163,21 +173,27 @@ module.exports = {
163173
},
164174
externals: [nodeExternals()],
165175
module: {
166-
rules: [{
167-
test: /\.(js|jsx)$/,
168-
use: {
169-
loader: 'babel-loader',
170-
options: { cacheDirectory: true }
176+
rules: [
177+
{
178+
test: /\.(js|jsx)$/,
179+
use: {
180+
loader: 'babel-loader',
181+
options: {
182+
cacheDirectory: true
183+
}
184+
}
171185
}
172-
}]
186+
]
173187
}
174188
};
175189
```
176190

177191
#### Test against precompiled sources
192+
178193
This is the most complicated to setup but performs quite well and also retains file names. In this approach, we use the `babel-cli` to compile the source files but preserve file structure. Require paths in tests are rewritten when compiling them in webpack. The following example is for a specific file structure. Depending on how your source and test files are organised, you might need to make changes.
179194

180195
File structure:
196+
181197
```
182198
├───src
183199
│ ├───my-pkg-fldr
@@ -201,33 +217,32 @@ File structure:
201217
```
202218

203219
npm scripts:
220+
204221
```js
205222
{
206-
"scripts": {
207-
"precompile-src": "cross-env NODE_ENV=test babel src --out-dir _src",
208-
"precompile-tests": "cross-env NODE_ENV=test webpack --config webpack.config.test.js",
209-
"pretest": "npm run precompile-src && npm run precompile-tests",
210-
"test": "cross-env NODE_ENV=test nyc --cache ava _build --concurrency 3"
211-
}
223+
"scripts": {
224+
"precompile-src": "cross-env NODE_ENV=test babel src --out-dir _src",
225+
"precompile-tests": "cross-env NODE_ENV=test webpack --config webpack.config.test.js",
226+
"pretest": "npm run precompile-src && npm run precompile-tests",
227+
"test": "cross-env NODE_ENV=test nyc --cache ava _build --concurrency 3"
228+
}
212229
}
213230
```
214231

215-
###### webpack.config.js
232+
###### `webpack.config.js`
216233

217-
Webpack Externals Docs - https://webpack.js.org/configuration/externals/#function
234+
[Webpack `externals` docs](https://webpack.js.org/configuration/externals/#function)
218235

219236
```js
220237
const path = require('path');
221238
const glob = require('glob');
222-
223239
const nodeExternals = require('webpack-node-externals');
224240

225241
const entryObj = glob.sync('./test/**/*.js')
226-
.reduce((acc, file) => {
227-
acc[path.basename(file, path.extname(file))] = file;
228-
return acc;
229-
}, {}); // empty object as initial value
230-
242+
.reduce((acc, file) => {
243+
acc[path.basename(file, path.extname(file))] = file;
244+
return acc;
245+
}, {});
231246

232247
module.exports = {
233248
target: 'node',
@@ -238,22 +253,22 @@ module.exports = {
238253
},
239254
externals: [
240255
nodeExternals(),
241-
// Rewrite the require paths to use _src
256+
// Rewrite the require paths to use `_src`
242257
(context, request, callback) => {
243258
// This is a little messy because tests are not output in original file structure
244-
// test/index.test.js -> _build/index.test.js
245-
// => ../src -> ../_src
246-
// test/my-pkg-fldr/my-module.test.js -> _build/my-module.test.js
247-
// => ../../src -> ../_src
259+
// test/index.test.js _build/index.test.js
260+
//=> ../src ../_src
261+
// test/my-pkg-fldr/my-module.test.js _build/my-module.test.js
262+
//=> ../../src ../_src
248263
if (request.includes('/src')) {
249264
const requestReqwrite = request
250265
.replace('/src', '/_src')
251266
.replace('../../_src', '../_src');
252267
return callback(null, `commonjs ${requestReqwrite}`);
253268
}
269+
254270
callback();
255271
}
256272
]
257273
};
258274
```
259-

0 commit comments

Comments
 (0)
Please sign in to comment.