Skip to content
This repository has been archived by the owner on Mar 17, 2021. It is now read-only.

Commit

Permalink
fix: fallback options behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait committed Aug 16, 2018
1 parent e4d10a2 commit 08a7a59
Show file tree
Hide file tree
Showing 17 changed files with 279 additions and 233 deletions.
10 changes: 5 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,18 @@ export default function loader(src) {
}

// Normalize the fallback.
const { loader: fallbackLoader, query: fallbackQuery } = normalizeFallback(
options.fallback,
options
);
const {
loader: fallbackLoader,
options: fallbackOptions,
} = normalizeFallback(options.fallback, options);

// Require the fallback.
const fallback = require(fallbackLoader);

// Call the fallback, passing a copy of the loader context. The copy has the query replaced. This way, the fallback
// loader receives the query which was intended for it instead of the query which was intended for url-loader.
const fallbackLoaderContext = Object.assign({}, this, {
query: fallbackQuery,
query: fallbackOptions,
});

return fallback.call(fallbackLoaderContext, src);
Expand Down
55 changes: 18 additions & 37 deletions src/utils/normalizeFallback.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,27 @@
function normalizeFallbackString(fallbackString, originalOptions) {
const index = fallbackString.indexOf('?');
if (index >= 0) {
return {
loader: fallbackString.substr(0, index),
query: fallbackString.substr(index),
};
}
import loaderUtils from 'loader-utils';

// To remain consistent with version 1.0.1, pass any other options which were provided to url-loader to the fallback loader.
const { fallback, limit, mimetype, ...otherOptions } = originalOptions;
export default function normalizeFallback(fallback, originalOptions) {
let loader = 'file-loader';
let options = {};

return {
loader: fallbackString,
query: otherOptions,
};
}
if (typeof fallback === 'string') {
loader = fallback;

function normalizeFallbackObject(fallbackObject) {
return {
loader: fallbackObject.loader,
query: fallbackObject.options,
};
}
const index = fallback.indexOf('?');

/**
* Converts the fallback option, which can be a string or an object, to an object with a loader and a query. The result
* has this form:
* {
* loader: 'file-loader',
* query: '?name=[name].[ext]'
* }
* Note that the returned query can be either a string or an object.
*/
export default function normalizeFallback(fallback, originalOptions) {
// If no fallback was provided, use file-loader.
if (!fallback) {
return normalizeFallbackString('file-loader', originalOptions);
if (index >= 0) {
loader = fallback.substr(0, index);
options = loaderUtils.parseQuery(fallback.substr(index));
}
}

if (typeof fallback === 'string') {
return normalizeFallbackString(fallback, originalOptions);
if (fallback !== null && typeof fallback === 'object') {
({ loader, options } = fallback);
}

return normalizeFallbackObject(fallback);
options = Object.assign({}, originalOptions, options);

delete options.fallback;

return { loader, options };
}
9 changes: 9 additions & 0 deletions test/__snapshots__/limit-option.test.js.snap

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions test/__snapshots__/mimetype-option.test.js.snap

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions test/cjs.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import loader from '../src';
import CJSLoader from '../src/cjs';

describe('CJS', () => {
it('should exported loader', () => {
expect(CJSLoader).toEqual(loader);
});
});
108 changes: 108 additions & 0 deletions test/fallback-option.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/* eslint-disable
prefer-destructuring,
*/
import path from 'path';

import webpack from '@webpack-contrib/test-utils';

describe('fallback option', () => {
test('{undefined}', async () => {
const config = {
rules: [
{
test: /\.png$/,
use: {
loader: path.join(__dirname, '../src'),
options: {},
},
},
],
};

const stats = await webpack('fixture.js', config);
const { source } = stats.toJson().modules[0];

expect(source).toMatchSnapshot();
});

test('{String}', async () => {
const config = {
rules: [
{
test: /\.png$/,
use: {
loader: path.join(__dirname, '../src'),
options: {
limit: Number.MIN_SAFE_INTEGER,
name: '[name].[hash].[ext]',
unknown: 'value',
fallback: path.join(__dirname, 'fixtures/x-custom-loader'),
},
},
},
],
};

const stats = await webpack('fixture.js', config);
const { source } = stats.toJson().modules[0];

expect(source).toMatchSnapshot();
});

test('{String} (with query)', async () => {
const config = {
rules: [
{
test: /\.png$/,
use: {
loader: path.join(__dirname, '../src'),
options: {
limit: Number.MIN_SAFE_INTEGER,
name: '[name].[hash].[ext]',
unknown: 'value',
fallback: `${path.join(
__dirname,
'fixtures/x-custom-loader'
)}?name=fallback-[hash].[ext]&unknown=fallback-value`,
},
},
},
],
};

const stats = await webpack('fixture.js', config);
const { source } = stats.toJson().modules[0];

expect(source).toMatchSnapshot();
});

test('{Object}', async () => {
const config = {
rules: [
{
test: /\.png$/,
use: {
loader: path.join(__dirname, '../src'),
options: {
limit: Number.MIN_SAFE_INTEGER,
name: '[name].[hash].[ext]',
unknown: 'value',
fallback: {
loader: path.join(__dirname, 'fixtures/x-custom-loader'),
options: {
name: 'fallback-[hash].[ext]',
unknown: 'fallback-other-value',
},
},
},
},
},
],
};

const stats = await webpack('fixture.js', config);
const { source } = stats.toJson().modules[0];

expect(source).toMatchSnapshot();
});
});
7 changes: 7 additions & 0 deletions test/fixtures/x-custom-loader/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const utils = require('loader-utils');

module.exports = function loader() {
const options = utils.getOptions(this);

return `module.exports=${JSON.stringify(options)}`;
};
68 changes: 68 additions & 0 deletions test/limit-option.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/* eslint-disable
prefer-destructuring,
*/
import webpack from '@webpack-contrib/test-utils';

describe('limit option', () => {
test('{undefined}', async () => {
const config = {
loader: {
test: /\.png$/,
options: {},
},
};

const stats = await webpack('fixture.js', config);
const { source } = stats.toJson().modules[0];

expect(source).toMatchSnapshot();
});

test('{Number} (big)', async () => {
const config = {
loader: {
test: /\.png$/,
options: {
limit: Number.MAX_SAFE_INTEGER,
},
},
};

const stats = await webpack('fixture.js', config);
const { source } = stats.toJson().modules[0];

expect(source).toMatchSnapshot();
});

test('{Number} (less)', async () => {
const config = {
loader: {
test: /\.png$/,
options: {
limit: Number.MIN_SAFE_INTEGER,
},
},
};

const stats = await webpack('fixture.js', config);
const { source } = stats.toJson().modules[0];

expect(source).toMatchSnapshot();
});

test('{String} (big)', async () => {
const config = {
loader: {
test: /\.png$/,
options: {
limit: '8192',
},
},
};

const stats = await webpack('fixture.js', config);
const { source } = stats.toJson().modules[0];

expect(source).toMatchSnapshot();
});
});
36 changes: 36 additions & 0 deletions test/mimetype-option.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* eslint-disable
prefer-destructuring,
*/
import webpack from '@webpack-contrib/test-utils';

describe('mimetype option', () => {
test('{undefined}', async () => {
const config = {
loader: {
test: /\.png$/,
options: {},
},
};

const stats = await webpack('fixture.js', config);
const { source } = stats.toJson().modules[0];

expect(source).toMatchSnapshot();
});

test('{String}', async () => {
const config = {
loader: {
test: /\.png$/,
options: {
mimetype: 'image/x-custom',
},
},
};

const stats = await webpack('fixture.js', config);
const { source } = stats.toJson().modules[0];

expect(source).toMatchSnapshot();
});
});
11 changes: 0 additions & 11 deletions test/options/__snapshots__/fallback.test.js.snap

This file was deleted.

5 changes: 0 additions & 5 deletions test/options/__snapshots__/limit.test.js.snap

This file was deleted.

3 changes: 0 additions & 3 deletions test/options/__snapshots__/mimetype.test.js.snap

This file was deleted.

0 comments on commit 08a7a59

Please sign in to comment.