Webpack's Rule
option presents two things (in a full, not shortcut syntax): resource
and issuer
.
In a
Rule
the propertiestest
,include
,exclude
andresource
are matched with the resource and the propertyissuer
is matched with the issuer.
So, it is somewhat clear what properties are related to a resource
:
{
resource: {
test: ...,
include: ...,
exclude: ...,
},
issuer: { ...boom?? }
}
But what properties are matched with the issuer
? There is just nothing for issuer in their docs:
A
Condition
matched with the issuer. See details in Rule conditions.
And details do not explain issuer
.
Why? They have created an option, but haven't decided on its properties yet?
Webpack's Rule
option presents two things (in a full, not shortcut syntax): resource
and issuer
.
In a
Rule
the propertiestest
,include
,exclude
andresource
are matched with the resource and the propertyissuer
is matched with the issuer.
So, it is somewhat clear what properties are related to a resource
:
{
resource: {
test: ...,
include: ...,
exclude: ...,
},
issuer: { ...boom?? }
}
But what properties are matched with the issuer
? There is just nothing for issuer in their docs:
A
Condition
matched with the issuer. See details in Rule conditions.
And details do not explain issuer
.
Why? They have created an option, but haven't decided on its properties yet?
Share edited Oct 16, 2017 at 11:14 Michael Jungo 33k4 gold badges95 silver badges87 bronze badges asked Oct 16, 2017 at 3:15 GreenGreen 30.9k62 gold badges163 silver badges253 bronze badges1 Answer
Reset to default 12They have created an option, but haven't decided on its properties yet?
The value of issuer
is a Condition
. The most mon Condition
is an object with test
, include
and/or exclude
properties, which you have used for the resource
. Everything you can use for resource
, you can also use for issuer
.
In fact, Rule.resource
expects itself a Condition
, excerpt from the docs:
Rule.resource
A
Condition
matched with the resource. You can either supply aRule.resource
option or use the shortcut optionsRule.test
,Rule.exclude
, andRule.include
.
The only difference to the issuer
is that there are shortcuts (Rule.test
, Rule.exclude
and Rule.include
), because that's the majority of the use-cases. It roughly translates to:
resource: {
test: Rule.test,
exclude: Rule.exclude,
include: Rule.include,
}
And details do not explain
issuer
.
Clicking on See details in Rule
conditions leads to a description, which even contains an example. Excerpt:
Rule Conditions
There are two input values for the conditions:
The resource: An absolute path to the file requested. It's already resolved according to the resolve rules.
The issuer: An absolute path to the file of the module which requested the resource. It's the location of the import.
Example: When we
import "./style.css"
fromapp.js
, the resource is/path/to/style.css
and the issuer is/path/to/app.js
.
That is definitely an explanation, but maybe it isn't good enough, so I'll explain it in more details.
To illustrate the purpose of issuer
I will use a contrived example, which could potentially be a use-case for it. Let's assume that you have some JavaScript code, which you would like to show to the user (the actual code) and at the same time you want to run that code in another part of the application. The code in question will be a simple greeting function.
greeter.js
export default function greet(name) {
console.log(`Hello ${name}!`);
}
If we want to show the source of greeter.js
, we could read it from the file system, but because we'd like to run it in the browser, this is not an option. As we are using webpack, we can use the raw-loader
to import the greeter.js
file as a string instead of JavaScript. Assuming we have configured it, we can create a module that prints the source code.
printer.js
import greetSource from "./greeter";
export default function printSource() {
console.log(greetSource);
}
In our entry point we want to use the greeter and the printer at the same time.
index.js
import greet from "./greeter";
import printSource from "./printer";
greet("World");
printSource();
Now we have a problem, because we've configured raw-loader
for greeter.js
, therefore greet
will be a string, not a function and that will cause a runtime error. What we want is to import greeter.js
in index.js
as a regular JavaScript file, but we want to import it as a string in printer.js
. We could use an inline loader definition, but that would be rather tedious.
This is where issuer
es in. Whichever JavaScript file is imported from printer.js
should be passed through the raw-loader
, and from any other file we'd like to use babel-loader
.
We will define two webpack rules. Both rules target only JavaScript files, so we test for the .js
file ending, for every file that is imported, this it the resource
. We would like to know which file imported it (where the import statement was), this is the issuer
.
printer.js
// Resource: greeter.js, Issuer: printer.js
import greetSource from "./greeter";
index.js
// Resource: greeter.js, Issuer: index.js
import greet from "./greeter";
For the rules, it means that we want to exclude printer.js
as an issuer from the babel-loader
rule, and include only printer.js
for the raw-loader
rule.
module: {
rules: [
{
loader: "babel-loader",
resource: {
test: /\.js$/
},
issuer: {
exclude: /printer\.js$/
}
},
{
loader: "raw-loader",
resource: {
test: /\.js$/
},
issuer: {
include: /printer\.js$/
}
}
]
}
Note: It's not necessary to include the resource
option for the raw-loader
rule and if you leave it out, it would apply the raw-loader
to everything that is being imported in printer.js
, which may or may not be what you want (think of including CSS to style the output)
Bundling and running the above code will produce the following output:
Hello World!
export default function greet(name) {
console.log(`Hello ${name}!`);
}