Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit cd5dd47

Browse files
MiniGodevilebottnawi
authored andcommitted
feat: pass loaderContext as 2nd parameter (#47)
1 parent 2c11d27 commit cd5dd47

File tree

7 files changed

+109
-5
lines changed

7 files changed

+109
-5
lines changed

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ the loader changes a module from code to a result.
2121
Another way to view `val-loader`, is that it allows a user a way to make their
2222
own custom loader logic, without having to write a custom loader.
2323

24+
The target module is called with two arguments: `(options, loaderContext)`
25+
26+
- `options`: The loader options (for instance provided in the webpack config. See the [example](#examples) below).
27+
- `loaderContext`: [The loader context](https://webpack.js.org/api/loaders/#the-loader-context).
28+
2429
## Getting Started
2530

2631
To begin, you'll need to install `val-loader`:
@@ -34,7 +39,7 @@ Then add the loader to your `webpack` config. For example:
3439
**target-file.js**
3540

3641
```js
37-
module.exports = () => {
42+
module.exports = (options, loaderContext) => {
3843
return { code: 'module.exports = 42;' };
3944
};
4045
```
@@ -104,6 +109,8 @@ Default: `[]`
104109
An array of absolute, native paths to file dependencies that should be watched
105110
by webpack for changes.
106111

112+
Dependencies can also be added using [`loaderContext.addDependency(file: string)`](https://webpack.js.org/api/loaders/#thisadddependency).
113+
107114
### `contextDependencies`
108115

109116
Type: `Array[String]`
@@ -112,6 +119,8 @@ Default: `[]`
112119
An array of absolute, native paths to directory dependencies that should be
113120
watched by webpack for changes.
114121

122+
Context dependencies can also be added using [`loaderContext.addContextDependency(directory: string)`](https://webpack.js.org/api/loaders/#thisaddcontextdependency).
123+
115124
### `cacheable`
116125

117126
Type: `Boolean`

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export default function loader(content) {
9393
let result;
9494

9595
try {
96-
result = func(options);
96+
result = func(options, this);
9797
} catch (error) {
9898
throw new Error(`Module "${this.resource}" throw error: ${error}`);
9999
}

test/__snapshots__/loader.test.js.snap

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

3+
exports[`loader should allow adding dependencies and contextDependencies via loader context: errors 1`] = `Array []`;
4+
5+
exports[`loader should allow adding dependencies and contextDependencies via loader context: result 1`] = `
6+
"{
7+
\\"content\\": \\"module.exports = \\\\\\"hello world\\\\\\";\\",
8+
\\"map\\": null,
9+
\\"meta\\": null,
10+
\\"dependencies\\": [
11+
\\"test/fixtures/dependencies-via-context.js\\",
12+
\\"test/fixtures/args.js\\",
13+
\\"test/fixtures/simple.js\\"
14+
],
15+
\\"contextDependencies\\": [
16+
\\"test/fixtures\\"
17+
]
18+
}"
19+
`;
20+
21+
exports[`loader should allow adding dependencies and contextDependencies via loader context: warnings 1`] = `Array []`;
22+
323
exports[`loader should call the function with the loader options: errors 1`] = `Array []`;
424

525
exports[`loader should call the function with the loader options: result 1`] = `
@@ -101,6 +121,31 @@ exports[`loader should has module.parent: result 1`] = `
101121

102122
exports[`loader should has module.parent: warnings 1`] = `Array []`;
103123

124+
exports[`loader should keep dependencies if errors are emitted: errors 1`] = `
125+
Array [
126+
"ModuleError: Module Error (from /src/index.js):
127+
(Emitted value instead of an instance of Error) Error: Calling the function failed",
128+
]
129+
`;
130+
131+
exports[`loader should keep dependencies if errors are emitted: result 1`] = `
132+
"{
133+
\\"content\\": \\"module.exports = \\\\\\"hello world\\\\\\";\\",
134+
\\"map\\": null,
135+
\\"meta\\": null,
136+
\\"dependencies\\": [
137+
\\"test/fixtures/error-emitted-with-dependencies.js\\",
138+
\\"test/fixtures/args.js\\",
139+
\\"test/fixtures/simple.js\\"
140+
],
141+
\\"contextDependencies\\": [
142+
\\"test/fixtures\\"
143+
]
144+
}"
145+
`;
146+
147+
exports[`loader should keep dependencies if errors are emitted: warnings 1`] = `Array []`;
148+
104149
exports[`loader should not swallow function call errors (async): errors 1`] = `
105150
Array [
106151
"ModuleBuildError: Module build failed (from /src/index.js):

test/fixtures/args.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
function args(...args) {
1+
function args(options) {
22
return {
33
code: 'module.exports = "hello world";',
4-
// We can't use rest parameters here because this code is not touched by babel
54
// We use the ast property because it is not validated
6-
ast: args, // eslint-disable-line prefer-rest-params
5+
ast: [options],
76
};
87
}
98

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
function dependencies(options, loaderContext) {
2+
loaderContext.addDependency(require.resolve('./args.js'));
3+
loaderContext.addDependency(require.resolve('./simple.js'));
4+
loaderContext.addContextDependency(__dirname);
5+
6+
return {
7+
code: 'module.exports = "hello world";',
8+
};
9+
}
10+
11+
module.exports = dependencies;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function errorEmittedWithDependencies(options, loaderOptions) {
2+
loaderOptions.emitError(new Error('Calling the function failed'));
3+
4+
return {
5+
dependencies: [
6+
require.resolve('./args.js'),
7+
require.resolve('./simple.js'),
8+
],
9+
contextDependencies: [__dirname],
10+
code: 'module.exports = "hello world";',
11+
};
12+
}
13+
14+
module.exports = errorEmittedWithDependencies;

test/loader.test.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,19 @@ describe('loader', () => {
119119
expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot('errors');
120120
});
121121

122+
it('should allow adding dependencies and contextDependencies via loader context', async () => {
123+
const compiler = getCompiler('dependencies-via-context.js');
124+
const stats = await compile(compiler);
125+
126+
expect(readAsset('val-loader.js', compiler, stats)).toMatchSnapshot(
127+
'result'
128+
);
129+
expect(normalizeErrors(stats.compilation.warnings)).toMatchSnapshot(
130+
'warnings'
131+
);
132+
expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot('errors');
133+
});
134+
122135
it('should work the same if a promise is returned', async () => {
123136
const compiler = getCompiler('promise.js');
124137
const stats = await compile(compiler);
@@ -171,6 +184,19 @@ describe('loader', () => {
171184
expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot('errors');
172185
});
173186

187+
it('should keep dependencies if errors are emitted', async () => {
188+
const compiler = getCompiler('error-emitted-with-dependencies.js');
189+
const stats = await compile(compiler);
190+
191+
expect(readAsset('val-loader.js', compiler, stats)).toMatchSnapshot(
192+
'result'
193+
);
194+
expect(normalizeErrors(stats.compilation.warnings)).toMatchSnapshot(
195+
'warnings'
196+
);
197+
expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot('errors');
198+
});
199+
174200
it('should report require() errors with a useful stacktrace', async () => {
175201
const compiler = getCompiler('error-require.js');
176202
const stats = await compile(compiler);

0 commit comments

Comments
 (0)