From f72a6bad204557f99a3f1dd313d877a1ebda135d Mon Sep 17 00:00:00 2001 From: cap-Bernardito Date: Mon, 24 Aug 2020 18:23:18 +0300 Subject: [PATCH] feat: add option additionaldata --- README.md | 35 ++--- src/index.js | 15 +-- src/options.json | 15 +-- .../additionalData-option.test.js.snap | 27 ++++ .../appendData-option.test.js.snap | 23 ---- .../prependData-option.test.js.snap | 23 ---- .../validate-options.test.js.snap | 120 +++++------------- ....test.js => additionalData-option.test.js} | 33 +++-- test/appendData-option.test.js | 39 ------ ...prepend-data.less => additional-data.less} | 0 test/fixtures/append-data.less | 5 - test/validate-options.test.js | 6 +- 12 files changed, 100 insertions(+), 241 deletions(-) create mode 100644 test/__snapshots__/additionalData-option.test.js.snap delete mode 100644 test/__snapshots__/appendData-option.test.js.snap delete mode 100644 test/__snapshots__/prependData-option.test.js.snap rename test/{prependData-option.test.js => additionalData-option.test.js} (50%) delete mode 100644 test/appendData-option.test.js rename test/fixtures/{prepend-data.less => additional-data.less} (100%) delete mode 100644 test/fixtures/append-data.less diff --git a/README.md b/README.md index 760d1c62..ad78a0b0 100644 --- a/README.md +++ b/README.md @@ -45,13 +45,12 @@ And run `webpack` via your preferred method. ## Options -| Name | Type | Default | Description | -| :-------------------------------------: | :------------------: | :----------------------: | :----------------------------------------------- | -| **[`lessOptions`](#lessoptions)** | `{Object\|Function}` | `{ relativeUrls: true }` | Options for Less. | -| **[`prependData`](#prependdata)** | `{String\|Function}` | `undefined` | Prepends Less code before the actual entry file. | -| **[`appendData`](#appenddata)** | `{String\|Function}` | `undefined` | Prepends Less code after the actual entry file. | -| **[`sourceMap`](#sourcemap)** | `{Boolean}` | `compiler.devtool` | Enables/Disables generation of source maps. | -| **[`implementation`](#implementation)** | `{Object}` | `less` | Setup Less implementation to use. | +| 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. | +| **[`implementation`](#implementation)** | `{Object}` | `less` | Setup Less implementation to use. | ### `lessOptions` @@ -134,12 +133,13 @@ module.exports = { }; ``` -### `prependData` +### `additionalData` Type: `String|Function` Default: `undefined` Prepends `Less` code before the actual entry file. +In this case, the `less-loader` will not override the source but just **prepend** the entry's content. This is especially useful when some of your Less variables depend on the environment: @@ -159,7 +159,7 @@ module.exports = { { loader: 'less-loader', options: { - prependData: `@env: ${process.env.NODE_ENV};`, + additionalData: `@env: ${process.env.NODE_ENV};`, }, }, ], @@ -183,16 +183,16 @@ module.exports = { { loader: 'less-loader', options: { - prependData: (loaderContext) => { + additionalData: (content, loaderContext) => { // More information about available properties https://webpack.js.org/api/loaders/ const { resourcePath, rootContext } = loaderContext; const relativePath = path.relative(rootContext, resourcePath); if (relativePath === 'styles/foo.less') { - return '@value: 100px;'; + return '@value: 100px;' + content; } - return '@value: 200px;'; + return '@value: 200px;' + content; }, }, }, @@ -203,17 +203,6 @@ module.exports = { }; ``` -### `appendData` - -Type: `String|Function` -Default: `undefined` - -AppendData `Less` code after the actual entry file. - -This can be useful when you need to rewrite some of your Less variables.: - -> ℹ Since you're injecting code, this will break the source mappings in your entry file. Often there's a simpler solution than this, like multiple Less entry files. - #### `String` ```js diff --git a/src/index.js b/src/index.js index dfa1a2de..1e56cb98 100644 --- a/src/index.js +++ b/src/index.js @@ -24,18 +24,11 @@ function lessLoader(source) { let data = source; - if (typeof options.prependData !== 'undefined') { + if (typeof options.additionalData !== 'undefined') { data = - typeof options.prependData === 'function' - ? `${options.prependData(this)}\n${data}` - : `${options.prependData}\n${data}`; - } - - if (typeof options.appendData !== 'undefined') { - data = - typeof options.appendData === 'function' - ? `${data}\n${options.appendData(this)}` - : `${data}\n${options.appendData}`; + typeof options.additionalData === 'function' + ? `${options.additionalData(data, this)}` + : `${options.additionalData}\n${data}`; } getLessImplementation(options.implementation) diff --git a/src/options.json b/src/options.json index 81bcc9f2..74f3296d 100644 --- a/src/options.json +++ b/src/options.json @@ -13,19 +13,8 @@ } ] }, - "prependData": { - "description": "Prepends `Less` code before the actual entry file (https://github.com/webpack-contrib/less-loader#prependdata).", - "anyOf": [ - { - "type": "string" - }, - { - "instanceof": "Function" - } - ] - }, - "appendData": { - "description": "Add `Less` code after the actual entry file (https://github.com/webpack-contrib/less-loader#postponeddata).", + "additionalData": { + "description": "Prepends/Appends `Less` code to the actual entry file (https://github.com/webpack-contrib/less-loader#additionalData).", "anyOf": [ { "type": "string" diff --git a/test/__snapshots__/additionalData-option.test.js.snap b/test/__snapshots__/additionalData-option.test.js.snap new file mode 100644 index 00000000..5825629e --- /dev/null +++ b/test/__snapshots__/additionalData-option.test.js.snap @@ -0,0 +1,27 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`additionalData option should work additionalData data as function: css 1`] = ` +"/* RelativePath: additional-data.less; */ +.background { + color: coral; +} +.custom-class { + color: red; +} +" +`; + +exports[`additionalData option should work additionalData data as function: errors 1`] = `Array []`; + +exports[`additionalData option should work additionalData data as function: warnings 1`] = `Array []`; + +exports[`additionalData option should work additionalData data as string: css 1`] = ` +".background { + color: coral; +} +" +`; + +exports[`additionalData option should work additionalData data as string: errors 1`] = `Array []`; + +exports[`additionalData option should work additionalData data as string: warnings 1`] = `Array []`; diff --git a/test/__snapshots__/appendData-option.test.js.snap b/test/__snapshots__/appendData-option.test.js.snap deleted file mode 100644 index 5440d02c..00000000 --- a/test/__snapshots__/appendData-option.test.js.snap +++ /dev/null @@ -1,23 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`appendData option should work append data as function: css 1`] = ` -".background { - color: coral; -} -" -`; - -exports[`appendData option should work append data as function: errors 1`] = `Array []`; - -exports[`appendData option should work append data as function: warnings 1`] = `Array []`; - -exports[`appendData option should work append data as string: css 1`] = ` -".background { - color: coral; -} -" -`; - -exports[`appendData option should work append data as string: errors 1`] = `Array []`; - -exports[`appendData option should work append data as string: warnings 1`] = `Array []`; diff --git a/test/__snapshots__/prependData-option.test.js.snap b/test/__snapshots__/prependData-option.test.js.snap deleted file mode 100644 index e83d19d9..00000000 --- a/test/__snapshots__/prependData-option.test.js.snap +++ /dev/null @@ -1,23 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`prependData option should work prepend data as function: css 1`] = ` -".background { - color: coral; -} -" -`; - -exports[`prependData option should work prepend data as function: errors 1`] = `Array []`; - -exports[`prependData option should work prepend data as function: warnings 1`] = `Array []`; - -exports[`prependData option should work prepend data as string: css 1`] = ` -".background { - color: coral; -} -" -`; - -exports[`prependData option should work prepend data as string: errors 1`] = `Array []`; - -exports[`prependData option should work prepend data as string: warnings 1`] = `Array []`; diff --git a/test/__snapshots__/validate-options.test.js.snap b/test/__snapshots__/validate-options.test.js.snap index 7834ae0b..4ba49b3e 100644 --- a/test/__snapshots__/validate-options.test.js.snap +++ b/test/__snapshots__/validate-options.test.js.snap @@ -1,63 +1,63 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`validate options should throw an error on the "appendData" option with "/test/" value 1`] = ` +exports[`validate options should throw an error on the "additionalData" 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.appendData should be one of these: + - options.additionalData should be one of these: string | function - -> Add \`Less\` code after the actual entry file (https://github.com/webpack-contrib/less-loader#postponeddata). + -> Prepends/Appends \`Less\` code to the actual entry file (https://github.com/webpack-contrib/less-loader#additionalData). Details: - * options.appendData should be a string. - * options.appendData should be an instance of function." + * options.additionalData should be a string. + * options.additionalData should be an instance of function." `; -exports[`validate options should throw an error on the "appendData" option with "[]" value 1`] = ` +exports[`validate options should throw an error on the "additionalData" option with "[]" value 1`] = ` "Invalid options object. Less Loader has been initialized using an options object that does not match the API schema. - - options.appendData should be one of these: + - options.additionalData should be one of these: string | function - -> Add \`Less\` code after the actual entry file (https://github.com/webpack-contrib/less-loader#postponeddata). + -> Prepends/Appends \`Less\` code to the actual entry file (https://github.com/webpack-contrib/less-loader#additionalData). Details: - * options.appendData should be a string. - * options.appendData should be an instance of function." + * options.additionalData should be a string. + * options.additionalData should be an instance of function." `; -exports[`validate options should throw an error on the "appendData" option with "{}" value 1`] = ` +exports[`validate options should throw an error on the "additionalData" option with "{}" value 1`] = ` "Invalid options object. Less Loader has been initialized using an options object that does not match the API schema. - - options.appendData should be one of these: + - options.additionalData should be one of these: string | function - -> Add \`Less\` code after the actual entry file (https://github.com/webpack-contrib/less-loader#postponeddata). + -> Prepends/Appends \`Less\` code to the actual entry file (https://github.com/webpack-contrib/less-loader#additionalData). Details: - * options.appendData should be a string. - * options.appendData should be an instance of function." + * options.additionalData should be a string. + * options.additionalData should be an instance of function." `; -exports[`validate options should throw an error on the "appendData" option with "1" value 1`] = ` +exports[`validate options should throw an error on the "additionalData" 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.appendData should be one of these: + - options.additionalData should be one of these: string | function - -> Add \`Less\` code after the actual entry file (https://github.com/webpack-contrib/less-loader#postponeddata). + -> Prepends/Appends \`Less\` code to the actual entry file (https://github.com/webpack-contrib/less-loader#additionalData). Details: - * options.appendData should be a string. - * options.appendData should be an instance of function." + * options.additionalData should be a string. + * options.additionalData should be an instance of function." `; -exports[`validate options should throw an error on the "appendData" option with "false" value 1`] = ` +exports[`validate options should throw an error on the "additionalData" 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.appendData should be one of these: + - options.additionalData should be one of these: string | function - -> Add \`Less\` code after the actual entry file (https://github.com/webpack-contrib/less-loader#postponeddata). + -> Prepends/Appends \`Less\` code to the actual entry file (https://github.com/webpack-contrib/less-loader#additionalData). Details: - * options.appendData should be a string. - * options.appendData should be an instance of function." + * options.additionalData should be a string. + * options.additionalData should be an instance of function." `; -exports[`validate options should throw an error on the "appendData" option with "true" value 1`] = ` +exports[`validate options should throw an error on the "additionalData" 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.appendData should be one of these: + - options.additionalData should be one of these: string | function - -> Add \`Less\` code after the actual entry file (https://github.com/webpack-contrib/less-loader#postponeddata). + -> Prepends/Appends \`Less\` code to the actual entry file (https://github.com/webpack-contrib/less-loader#additionalData). Details: - * options.appendData should be a string. - * options.appendData should be an instance of function." + * options.additionalData should be a string. + * options.additionalData should be an instance of function." `; exports[`validate options should throw an error on the "implementation" option with "false" value 1`] = ` @@ -136,66 +136,6 @@ exports[`validate options should throw an error on the "lessOptions" option with * options.lessOptions should be an instance of function." `; -exports[`validate options should throw an error on the "prependData" 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.prependData should be one of these: - string | function - -> Prepends \`Less\` code before the actual entry file (https://github.com/webpack-contrib/less-loader#prependdata). - Details: - * options.prependData should be a string. - * options.prependData should be an instance of function." -`; - -exports[`validate options should throw an error on the "prependData" option with "[]" value 1`] = ` -"Invalid options object. Less Loader has been initialized using an options object that does not match the API schema. - - options.prependData should be one of these: - string | function - -> Prepends \`Less\` code before the actual entry file (https://github.com/webpack-contrib/less-loader#prependdata). - Details: - * options.prependData should be a string. - * options.prependData should be an instance of function." -`; - -exports[`validate options should throw an error on the "prependData" option with "{}" value 1`] = ` -"Invalid options object. Less Loader has been initialized using an options object that does not match the API schema. - - options.prependData should be one of these: - string | function - -> Prepends \`Less\` code before the actual entry file (https://github.com/webpack-contrib/less-loader#prependdata). - Details: - * options.prependData should be a string. - * options.prependData should be an instance of function." -`; - -exports[`validate options should throw an error on the "prependData" 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.prependData should be one of these: - string | function - -> Prepends \`Less\` code before the actual entry file (https://github.com/webpack-contrib/less-loader#prependdata). - Details: - * options.prependData should be a string. - * options.prependData should be an instance of function." -`; - -exports[`validate options should throw an error on the "prependData" 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.prependData should be one of these: - string | function - -> Prepends \`Less\` code before the actual entry file (https://github.com/webpack-contrib/less-loader#prependdata). - Details: - * options.prependData should be a string. - * options.prependData should be an instance of function." -`; - -exports[`validate options should throw an error on the "prependData" 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.prependData should be one of these: - string | function - -> Prepends \`Less\` code before the actual entry file (https://github.com/webpack-contrib/less-loader#prependdata). - Details: - * options.prependData should be a string. - * options.prependData should be an instance of function." -`; - exports[`validate options should throw an error on the "sourceMap" 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.sourceMap should be a boolean. diff --git a/test/prependData-option.test.js b/test/additionalData-option.test.js similarity index 50% rename from test/prependData-option.test.js rename to test/additionalData-option.test.js index bf33eb9d..f2e72c88 100644 --- a/test/prependData-option.test.js +++ b/test/additionalData-option.test.js @@ -8,13 +8,11 @@ import { jest.setTimeout(30000); -describe('prependData option', () => { - it('should work prepend data as function', async () => { - const testId = './prepend-data.less'; +describe('additionalData option', () => { + it('should work additionalData data as string', async () => { + const testId = './additional-data.less'; const compiler = getCompiler(testId, { - prependData() { - return `@background: coral;`; - }, + additionalData: `@background: coral;`, }); const stats = await compile(compiler); const codeFromBundle = getCodeFromBundle(stats, compiler); @@ -24,10 +22,27 @@ describe('prependData option', () => { expect(getErrors(stats)).toMatchSnapshot('errors'); }); - it('should work prepend data as string', async () => { - const testId = './prepend-data.less'; + it('should work additionalData data as function', async () => { + const testId = './additional-data.less'; const compiler = getCompiler(testId, { - prependData: `@background: coral;`, + additionalData(content, loaderContext) { + const { resourcePath, rootContext } = loaderContext; + // eslint-disable-next-line global-require + const relativePath = require('path').relative( + rootContext, + resourcePath + ); + + const result = ` + /* RelativePath: ${relativePath}; */ + + @background: coral; + ${content}; + .custom-class {color: red}; + `; + + return result; + }, }); const stats = await compile(compiler); const codeFromBundle = getCodeFromBundle(stats, compiler); diff --git a/test/appendData-option.test.js b/test/appendData-option.test.js deleted file mode 100644 index fa869907..00000000 --- a/test/appendData-option.test.js +++ /dev/null @@ -1,39 +0,0 @@ -import { - compile, - getCodeFromBundle, - getCompiler, - getErrors, - getWarnings, -} from './helpers'; - -jest.setTimeout(30000); - -describe('appendData option', () => { - it('should work append data as function', async () => { - const testId = './append-data.less'; - const compiler = getCompiler(testId, { - appendData() { - return `@color: coral;`; - }, - }); - const stats = await compile(compiler); - const codeFromBundle = getCodeFromBundle(stats, compiler); - - expect(codeFromBundle.css).toMatchSnapshot('css'); - expect(getWarnings(stats)).toMatchSnapshot('warnings'); - expect(getErrors(stats)).toMatchSnapshot('errors'); - }); - - it('should work append data as string', async () => { - const testId = './append-data.less'; - const compiler = getCompiler(testId, { - appendData: `@color: coral;`, - }); - const stats = await compile(compiler); - const codeFromBundle = getCodeFromBundle(stats, compiler); - - expect(codeFromBundle.css).toMatchSnapshot('css'); - expect(getWarnings(stats)).toMatchSnapshot('warnings'); - expect(getErrors(stats)).toMatchSnapshot('errors'); - }); -}); diff --git a/test/fixtures/prepend-data.less b/test/fixtures/additional-data.less similarity index 100% rename from test/fixtures/prepend-data.less rename to test/fixtures/additional-data.less diff --git a/test/fixtures/append-data.less b/test/fixtures/append-data.less deleted file mode 100644 index b9d80350..00000000 --- a/test/fixtures/append-data.less +++ /dev/null @@ -1,5 +0,0 @@ -@color: red; - -.background { - color: @color; -} diff --git a/test/validate-options.test.js b/test/validate-options.test.js index 09091fc9..883b940e 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -11,11 +11,7 @@ describe('validate options', () => { ], failure: [1, true, false, 'test', []], }, - prependData: { - success: ['@background: coral;', () => '@background: coral;'], - failure: [1, true, false, /test/, [], {}], - }, - appendData: { + additionalData: { success: ['@background: coral;', () => '@background: coral;'], failure: [1, true, false, /test/, [], {}], },