Skip to content

Commit

Permalink
feat: pass loaderContext as 2nd parameter (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
MiniGod authored and evilebottnawi committed Dec 13, 2019
1 parent 2c11d27 commit cd5dd47
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 5 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ the loader changes a module from code to a result.
Another way to view `val-loader`, is that it allows a user a way to make their
own custom loader logic, without having to write a custom loader.

The target module is called with two arguments: `(options, loaderContext)`

- `options`: The loader options (for instance provided in the webpack config. See the [example](#examples) below).
- `loaderContext`: [The loader context](https://webpack.js.org/api/loaders/#the-loader-context).

## Getting Started

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

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

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

### `contextDependencies`

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

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

### `cacheable`

Type: `Boolean`
Expand Down
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export default function loader(content) {
let result;

try {
result = func(options);
result = func(options, this);
} catch (error) {
throw new Error(`Module "${this.resource}" throw error: ${error}`);
}
Expand Down
45 changes: 45 additions & 0 deletions test/__snapshots__/loader.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`loader should allow adding dependencies and contextDependencies via loader context: errors 1`] = `Array []`;

exports[`loader should allow adding dependencies and contextDependencies via loader context: result 1`] = `
"{
\\"content\\": \\"module.exports = \\\\\\"hello world\\\\\\";\\",
\\"map\\": null,
\\"meta\\": null,
\\"dependencies\\": [
\\"test/fixtures/dependencies-via-context.js\\",
\\"test/fixtures/args.js\\",
\\"test/fixtures/simple.js\\"
],
\\"contextDependencies\\": [
\\"test/fixtures\\"
]
}"
`;

exports[`loader should allow adding dependencies and contextDependencies via loader context: warnings 1`] = `Array []`;

exports[`loader should call the function with the loader options: errors 1`] = `Array []`;

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

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

exports[`loader should keep dependencies if errors are emitted: errors 1`] = `
Array [
"ModuleError: Module Error (from /src/index.js):
(Emitted value instead of an instance of Error) Error: Calling the function failed",
]
`;

exports[`loader should keep dependencies if errors are emitted: result 1`] = `
"{
\\"content\\": \\"module.exports = \\\\\\"hello world\\\\\\";\\",
\\"map\\": null,
\\"meta\\": null,
\\"dependencies\\": [
\\"test/fixtures/error-emitted-with-dependencies.js\\",
\\"test/fixtures/args.js\\",
\\"test/fixtures/simple.js\\"
],
\\"contextDependencies\\": [
\\"test/fixtures\\"
]
}"
`;

exports[`loader should keep dependencies if errors are emitted: warnings 1`] = `Array []`;

exports[`loader should not swallow function call errors (async): errors 1`] = `
Array [
"ModuleBuildError: Module build failed (from /src/index.js):
Expand Down
5 changes: 2 additions & 3 deletions test/fixtures/args.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
function args(...args) {
function args(options) {
return {
code: 'module.exports = "hello world";',
// We can't use rest parameters here because this code is not touched by babel
// We use the ast property because it is not validated
ast: args, // eslint-disable-line prefer-rest-params
ast: [options],
};
}

Expand Down
11 changes: 11 additions & 0 deletions test/fixtures/dependencies-via-context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function dependencies(options, loaderContext) {
loaderContext.addDependency(require.resolve('./args.js'));
loaderContext.addDependency(require.resolve('./simple.js'));
loaderContext.addContextDependency(__dirname);

return {
code: 'module.exports = "hello world";',
};
}

module.exports = dependencies;
14 changes: 14 additions & 0 deletions test/fixtures/error-emitted-with-dependencies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
function errorEmittedWithDependencies(options, loaderOptions) {
loaderOptions.emitError(new Error('Calling the function failed'));

return {
dependencies: [
require.resolve('./args.js'),
require.resolve('./simple.js'),
],
contextDependencies: [__dirname],
code: 'module.exports = "hello world";',
};
}

module.exports = errorEmittedWithDependencies;
26 changes: 26 additions & 0 deletions test/loader.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,19 @@ describe('loader', () => {
expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot('errors');
});

it('should allow adding dependencies and contextDependencies via loader context', async () => {
const compiler = getCompiler('dependencies-via-context.js');
const stats = await compile(compiler);

expect(readAsset('val-loader.js', compiler, stats)).toMatchSnapshot(
'result'
);
expect(normalizeErrors(stats.compilation.warnings)).toMatchSnapshot(
'warnings'
);
expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot('errors');
});

it('should work the same if a promise is returned', async () => {
const compiler = getCompiler('promise.js');
const stats = await compile(compiler);
Expand Down Expand Up @@ -171,6 +184,19 @@ describe('loader', () => {
expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot('errors');
});

it('should keep dependencies if errors are emitted', async () => {
const compiler = getCompiler('error-emitted-with-dependencies.js');
const stats = await compile(compiler);

expect(readAsset('val-loader.js', compiler, stats)).toMatchSnapshot(
'result'
);
expect(normalizeErrors(stats.compilation.warnings)).toMatchSnapshot(
'warnings'
);
expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot('errors');
});

it('should report require() errors with a useful stacktrace', async () => {
const compiler = getCompiler('error-require.js');
const stats = await compile(compiler);
Expand Down

0 comments on commit cd5dd47

Please sign in to comment.