Skip to content

Commit a97a3cc

Browse files
committed
refactor(options): filename to filenameTemplate
1 parent 1a79f40 commit a97a3cc

File tree

14 files changed

+25
-49
lines changed

14 files changed

+25
-49
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -342,14 +342,14 @@ module.exports = {
342342
};
343343
```
344344

345-
#### Filename as function instead of string
345+
#### Filename Template Function
346346

347-
By using a function instead of a string, you can use chunk data to customize the filename. This is particularly useful when dealing with multiple entry points and wanting to get more control out of the filename for a given entry point/chunk. In the example below, the we'll change the filename to output the css to a different directory.
347+
With the `filenameTemplate` option you can use chunk data to customize the filename. This is particularly useful when dealing with multiple entry points and wanting to get more control out of the filename for a given entry point/chunk. In the example below, we'll use `filenameTemplate` to output the generated css into a different directory.
348348

349349
```javascript
350350
const miniCssExtractPlugin = new MiniCssExtractPlugin({
351-
filename: (chunkData) =>
352-
`${chunkData.name.replace('/js/', '/css/')}.[chunkhash:8].css`
351+
filenameTemplate: ({chunk}) =>
352+
`${chunk.name.replace('/js/', '/css/')}.[chunkhash:8].css`
353353
})
354354
```
355355

src/index.js

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ const REGEXP_CHUNKHASH = /\[chunkhash(?::(\d+))?\]/i;
1717
const REGEXP_CONTENTHASH = /\[contenthash(?::(\d+))?\]/i;
1818
const REGEXP_NAME = /\[name\]/i;
1919
const REGEXP_PLACEHOLDERS = /\[(name|id|chunkhash)\]/g;
20-
const DEFAULT_FILENAME = '[name].css';
2120

2221
class CssDependency extends webpack.Dependency {
2322
constructor(
@@ -123,26 +122,23 @@ class MiniCssExtractPlugin {
123122
constructor(options) {
124123
this.options = Object.assign(
125124
{
126-
filename: DEFAULT_FILENAME,
125+
filename: '[name].css',
127126
},
128127
options
129128
);
130129

131130
if (!this.options.chunkFilename) {
132131
const { filename } = this.options;
132+
133133
// Anything changing depending on chunk is fine
134-
if (typeof filename === 'string') {
135-
if (REGEXP_PLACEHOLDERS.test(filename)) {
136-
this.options.chunkFilename = filename;
137-
} else {
138-
// Elsewise prefix '[id].' in front of the basename to make it changing
139-
this.options.chunkFilename = filename.replace(
140-
/(^|\/)([^/]*(?:\?|$))/,
141-
'$1[id].$2'
142-
);
143-
}
134+
if (REGEXP_PLACEHOLDERS.test(filename)) {
135+
this.options.chunkFilename = filename;
144136
} else {
145-
this.options.chunkFilename = `[id].${DEFAULT_FILENAME}`;
137+
// Elsewise prefix '[id].' in front of the basename to make it changing
138+
this.options.chunkFilename = filename.replace(
139+
/(^|\/)([^/]*(?:\?|$))/,
140+
'$1[id].$2'
141+
);
146142
}
147143
}
148144
}
@@ -189,9 +185,6 @@ class MiniCssExtractPlugin {
189185
const renderedModules = Array.from(chunk.modulesIterable).filter(
190186
(module) => module.type === MODULE_TYPE
191187
);
192-
const { filename } = this.options;
193-
const filenameTemplate =
194-
typeof filename === 'function' ? filename(chunk) : filename;
195188

196189
if (renderedModules.length > 0) {
197190
result.push({
@@ -202,7 +195,8 @@ class MiniCssExtractPlugin {
202195
renderedModules,
203196
compilation.runtimeTemplate.requestShortener
204197
),
205-
filenameTemplate,
198+
filenameTemplate:
199+
this.options.filenameTemplate || this.options.filename,
206200
pathOptions: {
207201
chunk,
208202
contentHashType: MODULE_TYPE,

test/TestCases.test.js

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ describe('TestCases', () => {
4040
directoryForCase,
4141
'webpack.config.js'
4242
));
43+
4344
for (const config of [].concat(webpackConfig)) {
4445
Object.assign(
4546
config,
@@ -56,12 +57,15 @@ describe('TestCases', () => {
5657
config
5758
);
5859
}
60+
5961
webpack(webpackConfig, (err, stats) => {
6062
if (err) {
6163
done(err);
6264
return;
6365
}
66+
6467
done();
68+
6569
// eslint-disable-next-line no-console
6670
console.log(
6771
stats.toString({
@@ -71,6 +75,7 @@ describe('TestCases', () => {
7175
modules: false,
7276
})
7377
);
78+
7479
if (stats.hasErrors()) {
7580
done(
7681
new Error(
@@ -80,40 +85,17 @@ describe('TestCases', () => {
8085
})
8186
)
8287
);
88+
8389
return;
8490
}
91+
8592
const expectedDirectory = path.resolve(directoryForCase, 'expected');
8693

87-
for (const file of walkSync(expectedDirectory)) {
88-
const actualFilePath = file.replace(
89-
expectedDirectory,
90-
path.join(outputDirectory, directory)
91-
);
92-
const expectedContent = fs.readFileSync(file, 'utf-8');
93-
const actualContent = fs.readFileSync(actualFilePath, 'utf-8');
94+
compareDirectory(outputDirectoryForCase, expectedDirectory);
9495

95-
expect(actualContent).toEqual(expectedContent);
96-
}
9796
done();
9897
});
9998
}, 10000);
10099
}
101100
}
102101
});
103-
104-
/**
105-
* Synchronously traverse directory of files
106-
* @param {String} dir
107-
* @returns {String} path to file or directory
108-
*/
109-
function* walkSync(dir) {
110-
for (const file of fs.readdirSync(dir)) {
111-
const pathToFile = path.join(dir, file);
112-
const isDirectory = fs.statSync(pathToFile).isDirectory();
113-
if (isDirectory) {
114-
yield* walkSync(pathToFile);
115-
} else {
116-
yield pathToFile;
117-
}
118-
}
119-
}

test/cases/filename/webpack.config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ module.exports = {
1717
},
1818
plugins: [
1919
new Self({
20-
filename: ({ name }) =>
21-
`${name.replace('/js/', '/css/')}.css`,
20+
filenameTemplate: ({ chunk }) =>
21+
`${chunk.name.replace('/js/', '/css/')}.css`,
2222
}),
2323
],
2424
};

0 commit comments

Comments
 (0)