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

Commit

Permalink
feat: support the query template for the name option (#366)
Browse files Browse the repository at this point in the history
evilebottnawi authored Feb 19, 2020

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 5703c58 commit cd8698b
Showing 8 changed files with 112 additions and 16 deletions.
57 changes: 55 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -102,7 +102,10 @@ module.exports = {
test: /\.(png|jpe?g|gif)$/i,
loader: 'file-loader',
options: {
name(file) {
name(resourcePath, resourceQuery) {
// `resourcePath` - `/absolute/path/to/file.js`
// `resourceQuery` - `?foo=bar`

if (process.env.NODE_ENV === 'development') {
return '[path][name].[ext]';
}
@@ -439,6 +442,13 @@ Default: `file.folder`

The folder of the resource is in.

### `[query]`

Type: `String`
Default: `file.query`

The query of the resource, i.e. `?foo=bar`.

### `[emoji]`

Type: `String`
@@ -619,14 +629,55 @@ Result:
path/to/file.png?e43b20c069c4a01867c31e98cbce33c9
```

### CDN

The following examples show how to use `file-loader` for CDN uses query params.

**file.js**

```js
import png from './directory/image.png?width=300&height=300';
```

**webpack.config.js**

```js
module.exports = {
output: {
publicPath: 'https://cdn.example.com/',
},
module: {
rules: [
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
options: {
name: '[path][name].[ext][query]',
},
},
],
},
],
},
};
```

Result:

```bash
# result
https://cdn.example.com/directory/image.png?width=300&height=300
```

### Dynamic public path depending on environment variable at run time

An application might want to configure different CDN hosts depending on an environment variable that is only available when running the application. This can be an advantage, as only one build of the application is necessary, which behaves differntly depending on environment variables of the deployment environment. Since file-loader is applied when compiling the application, and not when running it, the environment variable cannot be used in the file-loader configuration. A way around this is setting the `__webpack_public_path__` to the desired CDN host depending on the environment variable at the entrypoint of the application. The option `postTransformPublicPath` can be used to configure a custom path depending on a variable like `__webpack_public_path__`.

**main.js**

```js
const namespace = process.env.NAMESPACE;
const assetPrefixForNamespace = (namespace) => {
switch (namespace) {
case 'prod':
@@ -641,6 +692,8 @@ const assetPrefixForNamespace = (namespace) => {
return '';
}
};
const namespace = process.env.NAMESPACE;

__webpack_public_path__ = `${assetPrefixForNamespace(namespace)}/`;
```

14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@
"webpack": "^4.0.0 || ^5.0.0"
},
"dependencies": {
"loader-utils": "^1.2.3",
"loader-utils": "^1.4.0",
"schema-utils": "^2.5.0"
},
"devDependencies": {
10 changes: 8 additions & 2 deletions test/__snapshots__/name-option.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`"name" option should work for CDN support query params: errors 1`] = `Array []`;

exports[`"name" option should work for CDN support query params: result 1`] = `"https://cdn.example.com/nested/file.png?foo=bar"`;

exports[`"name" option should work for CDN support query params: warnings 1`] = `Array []`;

exports[`"name" option should work with "Function" value: errors 1`] = `Array []`;

exports[`"name" option should work with "Function" value: result 1`] = `"9c87cbf3ba33126ffd25ae7f2f6bbafb.function.png"`;
exports[`"name" option should work with "Function" value: result 1`] = `"9c87cbf3ba33126ffd25ae7f2f6bbafb.function.png?foo=bar"`;

exports[`"name" option should work with "Function" value: warnings 1`] = `Array []`;

exports[`"name" option should work with "String" value: errors 1`] = `Array []`;

exports[`"name" option should work with "String" value: result 1`] = `"9c87cbf3ba33126ffd25ae7f2f6bbafb.string.png"`;
exports[`"name" option should work with "String" value: result 1`] = `"9c87cbf3ba33126ffd25ae7f2f6bbafb.string.png?foo=bar"`;

exports[`"name" option should work with "String" value: warnings 1`] = `Array []`;

6 changes: 6 additions & 0 deletions test/fixtures/cdn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* eslint-disable */
import png from './nested/file.png?foo=bar#hash';

__export__ = png;

export default png;
Binary file added test/fixtures/nested/file.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test/fixtures/simple.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable */
import png from './file.png';
import png from './file.png?foo=bar';

__export__ = png;

37 changes: 34 additions & 3 deletions test/name-option.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import path from 'path';

import {
compile,
execute,
@@ -22,7 +24,7 @@ describe('"name" option', () => {

it('should work with "String" value', async () => {
const compiler = getCompiler('simple.js', {
name: '[hash].string.[ext]',
name: '[hash].string.[ext][query]',
});
const stats = await compile(compiler);

@@ -37,8 +39,11 @@ describe('"name" option', () => {

it('should work with "Function" value', async () => {
const compiler = getCompiler('simple.js', {
name() {
return '[hash].function.[ext]';
name(resourcePath, resourceQuery) {
expect(resourcePath).toBeDefined();
expect(resourceQuery).toBeDefined();

return '[hash].function.[ext][query]';
},
});
const stats = await compile(compiler);
@@ -51,4 +56,30 @@ describe('"name" option', () => {
);
expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot('errors');
});

it('should work for CDN support query params', async () => {
const compiler = getCompiler(
'cdn.js',
{
name: '[path][name].[ext][query]',
},
{
output: {
path: path.resolve(__dirname, './outputs'),
publicPath: 'https://cdn.example.com/',
filename: '[name].bundle.js',
chunkFilename: '[name].chunk.js',
},
}
);
const stats = await compile(compiler);

expect(
execute(readAsset('main.bundle.js', compiler, stats))
).toMatchSnapshot('result');
expect(normalizeErrors(stats.compilation.warnings)).toMatchSnapshot(
'warnings'
);
expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot('errors');
});
});

0 comments on commit cd8698b

Please sign in to comment.