Skip to content

Commit

Permalink
feat: add webpackImporter option (#377)
Browse files Browse the repository at this point in the history
  • Loading branch information
cap-Bernardito authored Aug 24, 2020
1 parent 919c3b9 commit 12dca5b
Show file tree
Hide file tree
Showing 9 changed files with 212 additions and 35 deletions.
44 changes: 39 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@ And run `webpack` via your preferred method.

## Options

| Name | Type | Default | Description |
| :-------------------------------------: | :------------------: | :----------------------: | :----------------------------------------------------- |
| **[`lessOptions`](#lessoptions)** | `{Object\|Function}` | `{ relativeUrls: true }` | Options for Less. |
| **[`additionalData`](#additionalData)** | `{String\|Function}` | `undefined` | Prepends/Appends `Less` code to the actual entry file. |
| **[`sourceMap`](#sourcemap)** | `{Boolean}` | `compiler.devtool` | Enables/Disables generation of source maps. |
| Name | Type | Default | Description |
| :---------------------------------------: | :------------------: | :----------------------: | :----------------------------------------------------- |
| **[`lessOptions`](#lessoptions)** | `{Object\|Function}` | `{ relativeUrls: true }` | Options for Less. |
| **[`additionalData`](#additionalData)** | `{String\|Function}` | `undefined` | Prepends/Appends `Less` code to the actual entry file. |
| **[`sourceMap`](#sourcemap)** | `{Boolean}` | `compiler.devtool` | Enables/Disables generation of source maps. |
| **[`webpackImporter`](#webpackimporter)** | `{Boolean}` | `true` | Enables/Disables the default Webpack importer. |

### `lessOptions`

Expand Down Expand Up @@ -296,6 +297,39 @@ module.exports = {
};
```

### `webpackImporter`

Type: `Boolean`
Default: `true`

Enables/Disables the default Webpack importer.

This can improve performance in some cases. Use it with caution because aliases and `@import` at-rules starting with `~` will not work.

**webpack.config.js**

```js
module.exports = {
module: {
rules: [
{
test: /\.less$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'less-loader',
options: {
webpackImporter: false,
},
},
],
},
],
},
};
```

## Examples

### Normal usage
Expand Down
4 changes: 4 additions & 0 deletions src/options.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
"sourceMap": {
"description": "Enables/Disables generation of source maps (https://github.com/webpack-contrib/less-loader#sourcemap).",
"type": "boolean"
},
"webpackImporter": {
"description": "Enables/Disables default `webpack` importer (https://github.com/webpack-contrib/less-loader#webpackimporter).",
"type": "boolean"
}
},
"additionalProperties": false
Expand Down
9 changes: 8 additions & 1 deletion src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,14 @@ function getLessOptions(loaderContext, loaderOptions) {
...options,
};

lessOptions.plugins.unshift(createWebpackLessPlugin(loaderContext));
const shouldUseWebpackImporter =
typeof loaderOptions.webpackImporter === 'boolean'
? loaderOptions.webpackImporter
: true;

if (shouldUseWebpackImporter) {
lessOptions.plugins.unshift(createWebpackLessPlugin(loaderContext));
}

const useSourceMap =
typeof loaderOptions.sourceMap === 'boolean'
Expand Down
16 changes: 0 additions & 16 deletions test/__snapshots__/loader.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -379,26 +379,10 @@ exports[`loader should resolve all imports from node_modules using webpack's res
"
`;
exports[`loader should resolve all imports from node_modules using webpack's resolver: css 2`] = `
"@import \\"~@scope/css.css\\";
.modules-dir-scope-module,
#it-works {
color: hotpink;
}
#it-works {
margin: 10px;
}
"
`;
exports[`loader should resolve all imports from node_modules using webpack's resolver: errors 1`] = `Array []`;
exports[`loader should resolve all imports from node_modules using webpack's resolver: errors 2`] = `Array []`;
exports[`loader should resolve all imports from node_modules using webpack's resolver: warnings 1`] = `Array []`;
exports[`loader should resolve all imports from node_modules using webpack's resolver: warnings 2`] = `Array []`;
exports[`loader should resolve all imports from the given paths using Less resolver: css 1`] = `
".modules-dir-some-module {
color: hotpink;
Expand Down
54 changes: 54 additions & 0 deletions test/__snapshots__/validate-options.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,57 @@ exports[`validate options should throw an error on the "sourceMap" option with "
- options.sourceMap should be a boolean.
-> Enables/Disables generation of source maps (https://github.com/webpack-contrib/less-loader#sourcemap)."
`;

exports[`validate options should throw an error on the "unknown" option with "/test/" value 1`] = `
"Invalid options object. Less Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { lessOptions?, additionalData?, sourceMap?, webpackImporter? }"
`;
exports[`validate options should throw an error on the "unknown" option with "[]" value 1`] = `
"Invalid options object. Less Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { lessOptions?, additionalData?, sourceMap?, webpackImporter? }"
`;
exports[`validate options should throw an error on the "unknown" option with "{"foo":"bar"}" value 1`] = `
"Invalid options object. Less Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { lessOptions?, additionalData?, sourceMap?, webpackImporter? }"
`;
exports[`validate options should throw an error on the "unknown" option with "{}" value 1`] = `
"Invalid options object. Less Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { lessOptions?, additionalData?, sourceMap?, webpackImporter? }"
`;
exports[`validate options should throw an error on the "unknown" option with "1" value 1`] = `
"Invalid options object. Less Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { lessOptions?, additionalData?, sourceMap?, webpackImporter? }"
`;
exports[`validate options should throw an error on the "unknown" option with "false" value 1`] = `
"Invalid options object. Less Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { lessOptions?, additionalData?, sourceMap?, webpackImporter? }"
`;
exports[`validate options should throw an error on the "unknown" option with "test" value 1`] = `
"Invalid options object. Less Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { lessOptions?, additionalData?, sourceMap?, webpackImporter? }"
`;
exports[`validate options should throw an error on the "unknown" option with "true" value 1`] = `
"Invalid options object. Less Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { lessOptions?, additionalData?, sourceMap?, webpackImporter? }"
`;
exports[`validate options should throw an error on the "webpackImporter" option with "string" value 1`] = `
"Invalid options object. Less Loader has been initialized using an options object that does not match the API schema.
- options.webpackImporter should be a boolean.
-> Enables/Disables default \`webpack\` importer (https://github.com/webpack-contrib/less-loader#webpackimporter)."
`;
50 changes: 50 additions & 0 deletions test/__snapshots__/webpackImporter-options.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`webpackImporter option not specify webpackImporter option: css 1`] = `
"@import \\"~some/css.css\\";
@import \\"~some/css.css\\";
#it-works {
color: hotpink;
}
.modules-dir-some-module,
#it-works {
background: hotpink;
}
#it-works {
margin: 10px;
}
"
`;

exports[`webpackImporter option not specify webpackImporter option: errors 1`] = `Array []`;

exports[`webpackImporter option not specify webpackImporter option: warnings 1`] = `Array []`;

exports[`webpackImporter option webpackImporter option is false: errors 1`] = `
Array [
"ModuleBuildError: Module build failed (from \`replaced original path\`):
",
]
`;

exports[`webpackImporter option webpackImporter option is false: warnings 1`] = `Array []`;

exports[`webpackImporter option webpackImporter option is true: css 1`] = `
"@import \\"~some/css.css\\";
@import \\"~some/css.css\\";
#it-works {
color: hotpink;
}
.modules-dir-some-module,
#it-works {
background: hotpink;
}
#it-works {
margin: 10px;
}
"
`;

exports[`webpackImporter option webpackImporter option is true: errors 1`] = `Array []`;

exports[`webpackImporter option webpackImporter option is true: warnings 1`] = `Array []`;
13 changes: 0 additions & 13 deletions test/loader.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,19 +176,6 @@ describe('loader', () => {
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it("should resolve all imports from node_modules using webpack's resolver", async () => {
const testId = './import-scope.less';
const compiler = getCompiler(testId);
const stats = await compile(compiler);
const codeFromBundle = getCodeFromBundle(stats, compiler);
const codeFromLess = await getCodeFromLess(testId);

expect(codeFromBundle.css).toBe(codeFromLess.css);
expect(codeFromBundle.css).toMatchSnapshot('css');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should resolve aliases in diffrent variants', async () => {
const testId = './import-webpack-aliases.less';
const compiler = getCompiler(
Expand Down
8 changes: 8 additions & 0 deletions test/validate-options.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ describe('validate options', () => {
success: [true, false],
failure: ['string'],
},
webpackImporter: {
success: [true, false],
failure: ['string'],
},
unknown: {
success: [],
failure: [1, true, false, 'test', /test/, [], {}, { foo: 'bar' }],
},
};

function stringifyValue(value) {
Expand Down
49 changes: 49 additions & 0 deletions test/webpackImporter-options.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import {
compile,
getCodeFromBundle,
getCodeFromLess,
getCompiler,
getErrors,
getWarnings,
} from './helpers';

describe('webpackImporter option', () => {
it('not specify webpackImporter option', async () => {
const testId = './import-webpack.less';
const compiler = getCompiler(testId);
const stats = await compile(compiler);
const codeFromBundle = getCodeFromBundle(stats, compiler);
const codeFromLess = await getCodeFromLess(testId);

expect(codeFromBundle.css).toBe(codeFromLess.css);
expect(codeFromBundle.css).toMatchSnapshot('css');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('webpackImporter option is true', async () => {
const testId = './import-webpack.less';
const compiler = getCompiler(testId, {
webpackImporter: true,
});
const stats = await compile(compiler);
const codeFromBundle = getCodeFromBundle(stats, compiler);
const codeFromLess = await getCodeFromLess(testId);

expect(codeFromBundle.css).toBe(codeFromLess.css);
expect(codeFromBundle.css).toMatchSnapshot('css');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('webpackImporter option is false', async () => {
const testId = './import-webpack.less';
const compiler = getCompiler(testId, {
webpackImporter: false,
});
const stats = await compile(compiler);

expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});
});

0 comments on commit 12dca5b

Please sign in to comment.