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

Commit

Permalink
refactor: loader
Browse files Browse the repository at this point in the history
BREAKING CHANGE: removed the `useRelativePath` option. It is dangerously and break url when you use multiple entry points.
  • Loading branch information
evilebottnawi authored Dec 20, 2018
1 parent d5eb823 commit 9853db1
Show file tree
Hide file tree
Showing 11 changed files with 203 additions and 181 deletions.
17 changes: 0 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,23 +283,6 @@ _Note: If `[0]` is used, it will be replaced by the entire tested string,
whereas `[1]` will contain the first capturing parenthesis of your regex and so
on..._

### `useRelativePath`

Type: `Boolean`
Default: `false`

Specifies whether or not to generate a relative URI for each target file context.

```js
// webpack.config.js
{
loader: 'file-loader',
options: {
useRelativePath: process.env.NODE_ENV === "production"
}
}
```

## Placeholders

### `[ext]`
Expand Down
31 changes: 5 additions & 26 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,38 +28,17 @@ export default function loader(content) {
}
}

if (options.useRelativePath) {
const filePath = this.resourcePath;

const issuer = options.context
? context
: this._module && this._module.issuer && this._module.issuer.context;

const relativeUrl =
issuer &&
path
.relative(issuer, filePath)
.split(path.sep)
.join('/');

const relativePath = relativeUrl && `${path.dirname(relativeUrl)}/`;
// eslint-disable-next-line no-bitwise
if (~relativePath.indexOf('../')) {
outputPath = path.posix.join(outputPath, relativePath, url);
} else {
outputPath = path.posix.join(relativePath, url);
}
}

let publicPath = `__webpack_public_path__ + ${JSON.stringify(outputPath)}`;

if (options.publicPath) {
if (typeof options.publicPath === 'function') {
publicPath = options.publicPath(url, this.resourcePath, context);
} else if (options.publicPath.endsWith('/')) {
publicPath = options.publicPath + url;
} else {
publicPath = `${options.publicPath}/${url}`;
publicPath = `${
options.publicPath.endsWith('/')
? options.publicPath
: `${options.publicPath}/`
}${url}`;
}

publicPath = JSON.stringify(publicPath);
Expand Down
58 changes: 47 additions & 11 deletions src/options.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,60 @@
{
"type": "object",
"additionalProperties": false,
"properties": {
"name": {},
"regExp": {},
"name": {
"anyOf": [
{
"type": "string"
},
{
"instanceof": "Function"
}
]
},
"outputPath": {
"anyOf": [
{
"type": "string"
},
{
"instanceof": "Function"
}
]
},
"publicPath": {
"anyOf": [
{
"type": "string"
},
{
"instanceof": "Function"
}
]
},
"context": {
"type": "string"
},
"publicPath": {},
"outputPath": {},
"useRelativePath": {
"type": "boolean"
},
"emitFile": {
"type": "boolean"
},
"regExp": {
"anyOf": [
{
"type": "string"
},
{
"instanceof": "RegExp"
}
]
}
},
"errorMessages": {
"name": "should be {String} or {Function} (https://github.com/webpack-contrib/file-loader#name)",
"outputPath": "should be {String} or {Function} (https://github.com/webpack-contrib/file-loader#outputpath)",
"publicPath": "should be {String} or {Function} (https://github.com/webpack-contrib/file-loader#publicpath)",
"context": "should be {String} (https://github.com/webpack-contrib/file-loader#context)",
"useRelativePath": "should be {Boolean} (https://github.com/webpack-contrib/file-loader#userelativepath)",
"emitFile": "should be {Boolean} (https://github.com/webpack-contrib/file-loader#emitfile)"
"emitFile": "should be {Boolean} (https://github.com/webpack-contrib/file-loader#emitfile)",
"regExp": "should be {String} or {RegExp} (https://github.com/webpack-contrib/file-loader#regexp)"
},
"additionalProperties": true
"type": "object"
}
54 changes: 52 additions & 2 deletions test/__snapshots__/errors.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,8 +1,58 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`errors validation errors 1`] = `
exports[`validation errors 1`] = `
"File Loader Invalid Options
options.useRelativePath should be boolean
options should NOT have additional properties
"
`;

exports[`validation errors 2`] = `
"File Loader Invalid Options
options.name should be string
options.name should pass \\"instanceof\\" keyword validation
options.name should match some schema in anyOf
"
`;

exports[`validation errors 3`] = `
"File Loader Invalid Options
options.outputPath should be string
options.outputPath should pass \\"instanceof\\" keyword validation
options.outputPath should match some schema in anyOf
"
`;

exports[`validation errors 4`] = `
"File Loader Invalid Options
options.publicPath should be string
options.publicPath should pass \\"instanceof\\" keyword validation
options.publicPath should match some schema in anyOf
"
`;

exports[`validation errors 5`] = `
"File Loader Invalid Options
options.context should be string
"
`;

exports[`validation errors 6`] = `
"File Loader Invalid Options
options.emitFile should be boolean
"
`;

exports[`validation errors 7`] = `
"File Loader Invalid Options
options.regExp should be string
options.regExp should pass \\"instanceof\\" keyword validation
options.regExp should match some schema in anyOf
"
`;
9 changes: 9 additions & 0 deletions test/__snapshots__/outputPath-option.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,12 @@ Object {
"source": "module.exports = __webpack_public_path__ + \\"output_path/file.png\\";",
}
`;

exports[`when applied with \`outputPath\` option matches snapshot without value 1`] = `
Object {
"assets": Array [
"9c87cbf3ba33126ffd25ae7f2f6bbafb.png",
],
"source": "module.exports = __webpack_public_path__ + \\"9c87cbf3ba33126ffd25ae7f2f6bbafb.png\\";",
}
`;
9 changes: 9 additions & 0 deletions test/__snapshots__/publicPath-option.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,12 @@ Object {
"source": "module.exports = \\"public_path/9c87cbf3ba33126ffd25ae7f2f6bbafb.png\\";",
}
`;

exports[`when applied with \`publicPath\` option matches snapshot without value 1`] = `
Object {
"assets": Array [
"9c87cbf3ba33126ffd25ae7f2f6bbafb.png",
],
"source": "module.exports = __webpack_public_path__ + \\"9c87cbf3ba33126ffd25ae7f2f6bbafb.png\\";",
}
`;
37 changes: 0 additions & 37 deletions test/__snapshots__/useRelativePath-option.test.js.snap

This file was deleted.

63 changes: 53 additions & 10 deletions test/errors.test.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,57 @@
import loader from '../src';

describe('errors', () => {
it('validation errors', () => {
const err = () =>
loader.call({
query: { useRelativePath: 1 },
emitFile: true,
});

expect(err).toThrow();
expect(err).toThrowErrorMatchingSnapshot();
describe('validation', () => {
it('errors', () => {
const validate = (options) =>
loader.call(
Object.assign(
{},
{
resourcePath: 'image.png',
query: options,
emitFile: () => {},
}
),
'a { color: red; }'
);

expect(() =>
validate({ unknown: 'unknown' })
).toThrowErrorMatchingSnapshot();

expect(() => validate({ name: '[path][name].[ext]' })).not.toThrow();
expect(() =>
validate({
name: () => '[hash].[ext]',
})
).not.toThrow();
expect(() => validate({ name: true })).toThrowErrorMatchingSnapshot();

expect(() => validate({ outputPath: 'assets' })).not.toThrow();
expect(() =>
validate({
outputPath: () => 'assets',
})
).not.toThrow();
expect(() => validate({ outputPath: true })).toThrowErrorMatchingSnapshot();

expect(() => validate({ publicPath: 'assets' })).not.toThrow();
expect(() =>
validate({
publicPath: () => 'assets',
})
).not.toThrow();
expect(() => validate({ publicPath: true })).toThrowErrorMatchingSnapshot();

expect(() => validate({ context: 'assets' })).not.toThrow();
expect(() => validate({ context: true })).toThrowErrorMatchingSnapshot();

expect(() => validate({ emitFile: true })).not.toThrow();
expect(() => validate({ emitFile: false })).not.toThrow();
expect(() => validate({ emitFile: 'true' })).toThrowErrorMatchingSnapshot();

expect(() => validate({ regExp: /image\.png/ })).not.toThrow();
expect(() => validate({ regExp: 'image\\.png' })).not.toThrow();
expect(() => validate({ regExp: true })).toThrowErrorMatchingSnapshot();
});
});
14 changes: 14 additions & 0 deletions test/outputPath-option.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
import webpack from './helpers/compiler';

describe('when applied with `outputPath` option', () => {
it('matches snapshot without value', async () => {
const config = {
loader: {
test: /(png|jpg|svg)/,
},
};

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

expect({ assets, source }).toMatchSnapshot();
});

it('matches snapshot for `{String}` value', async () => {
const config = {
loader: {
Expand Down
14 changes: 14 additions & 0 deletions test/publicPath-option.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
import webpack from './helpers/compiler';

describe('when applied with `publicPath` option', () => {
it('matches snapshot without value', async () => {
const config = {
loader: {
test: /(png|jpg|svg)/,
},
};

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

expect({ assets, source }).toMatchSnapshot();
});

it('matches snapshot for `{String}` value', async () => {
const config = {
loader: {
Expand Down
Loading

0 comments on commit 9853db1

Please sign in to comment.