Skip to content
This repository was archived by the owner on Jan 21, 2021. It is now read-only.

Commit 2605ce4

Browse files
committed
[update] implement the multiple html function
1 parent 7eb8803 commit 2605ce4

File tree

2 files changed

+140
-122
lines changed

2 files changed

+140
-122
lines changed

index.js

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ const objectAssign = require('object-assign');
2424
const PLUGIN_NAME = 'preload-webpack-plugin';
2525

2626
const weblog = require('webpack-log');
27-
const Entrypoint = require('webpack/lib/Entrypoint');
2827
const log = weblog({name: PLUGIN_NAME});
2928

3029
const flatten = arr => arr.reduce((prev, curr) => prev.concat(curr), []);
@@ -52,6 +51,29 @@ const doesChunkBelongToHTML = (chunk, roots, visitedChunks) => {
5251
return false;
5352
};
5453

54+
const doesChunkGroupBelongToHTML = (chunkGroup, rootChunkGroups, visitedChunks) => {
55+
// Prevent circular recursion.
56+
// See https://github.com/GoogleChromeLabs/preload-webpack-plugin/issues/49
57+
if (visitedChunks[chunkGroup.groupDebugId]) {
58+
return false;
59+
}
60+
visitedChunks[chunkGroup.groupDebugId] = true;
61+
62+
for (const rootChunkGroup of rootChunkGroups) {
63+
if (rootChunkGroup.groupDebugId === chunkGroup.groupDebugId) {
64+
return true;
65+
}
66+
}
67+
68+
for (const parentChunkGroup of chunkGroup.getParents()) {
69+
if (doesChunkGroupBelongToHTML(parentChunkGroup, rootChunkGroups, visitedChunks)) {
70+
return true;
71+
}
72+
}
73+
74+
return false;
75+
};
76+
5577
const defaultOptions = {
5678
rel: 'preload',
5779
include: 'asyncChunks',
@@ -122,27 +144,23 @@ class PreloadPlugin {
122144

123145
// only handle the chunks associated to this htmlWebpackPlugin instance, in case of multiple html plugin outputs
124146
// allow `allAssets` mode to skip, as assets are just files to be filtered by black/whitelist, not real chunks
125-
// if (options.include !== 'allAssets') {
126-
// extractedChunks = extractedChunks.filter(chunk => {
127-
// const rootChunksHashs = Object.values(htmlPluginData.assets.chunks).map(({hash}) => hash);
128-
// const rootChunkGroups = compilation.chunkGroups.reduce((groups, chunkGroup) => {
129-
// const isRootChunkGroup = chunkGroup.chunks.reduce((flag, chunk) => {
130-
// return flag ||
131-
// rootChunksHashs.indexOf(chunk.renderedHash) > -1;
132-
// }, false);
133-
// if (isRootChunkGroup) groups.push(chunkGroup);
134-
// return groups;
135-
// }, []);
136-
// return rootChunkGroups.reduce((flag, chunkGroup) => {
137-
// return flag ||
138-
// chunk.isInGroup(chunkGroup);
139-
// }, false);
140-
// // console.log(Object.values(htmlPluginData.assets.chunks));
141-
// // console.warn(compilation.chunkGroups);
142-
// // doesChunkBelongToHTML(
143-
// // chunk, Object.values(htmlPluginData.assets.chunks), {});
144-
// });
145-
// }
147+
if (options.include !== 'allAssets') {
148+
extractedChunks = extractedChunks.filter(chunk => {
149+
const rootChunksHashs = Object.values(htmlPluginData.assets.chunks).map(({hash}) => hash);
150+
const rootChunkGroups = compilation.chunkGroups.reduce((groups, chunkGroup) => {
151+
const isRootChunkGroup = chunkGroup.chunks.reduce((flag, chunk) => {
152+
return flag ||
153+
rootChunksHashs.indexOf(chunk.renderedHash) > -1;
154+
}, false);
155+
if (isRootChunkGroup) groups.push(chunkGroup);
156+
return groups;
157+
}, []);
158+
return Array.from(chunk.groupsIterable).reduce((flag, chunkGroup) => {
159+
return flag ||
160+
doesChunkGroupBelongToHTML(chunkGroup, rootChunkGroups, {});
161+
}, false);
162+
});
163+
}
146164

147165
flatten(extractedChunks.map(chunk => chunk.files))
148166
.filter(entry => {

test/spec.js

Lines changed: 100 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -462,106 +462,106 @@ describe('filtering unwanted files', function() {
462462
});
463463

464464
describe('multiple html', function() {
465-
// it('each one only include their own chunk', function(done) {
466-
// const compiler = webpack({
467-
// entry: {
468-
// js: path.join(__dirname, 'fixtures', 'file.js'),
469-
// moduleA: path.join(__dirname, 'fixtures', 'module-a.js')
470-
// },
471-
// output: {
472-
// path: OUTPUT_DIR,
473-
// filename: '[name].js',
474-
// chunkFilename: 'chunk.[chunkhash].js',
475-
// publicPath: '/',
476-
// },
477-
// devtool: 'cheap-source-map',
478-
// plugins: [
479-
// new HtmlWebpackPlugin({
480-
// filename: 'index.html',
481-
// chunks: ['js'],
482-
// }),
483-
// new HtmlWebpackPlugin({
484-
// filename: 'home.html',
485-
// chunks: ['moduleA'],
486-
// }),
487-
// new PreloadPlugin()
488-
// ]
489-
// }, function(err, result) {
490-
// expect(err).toBeFalsy();
491-
// expect(JSON.stringify(result.compilation.errors)).toBe('[]');
492-
// const html = result.compilation.assets['index.html'].source();
493-
// const homeHtml = result.compilation.assets['home.html'].source();
494-
// expect(html).toContain('<link rel="preload" as="script" href="/chunk.');
495-
// expect(homeHtml).not.toContain('<link rel="preload" as="script" href="/chunk.');
496-
// done();
497-
// });
498-
// compiler.outputFileSystem = new MemoryFileSystem();
499-
// });
465+
it('each one only include their own chunk', function(done) {
466+
const compiler = webpack({
467+
entry: {
468+
js: path.join(__dirname, 'fixtures', 'file.js'),
469+
moduleA: path.join(__dirname, 'fixtures', 'module-a.js')
470+
},
471+
output: {
472+
path: OUTPUT_DIR,
473+
filename: '[name].js',
474+
chunkFilename: 'chunk.[chunkhash].js',
475+
publicPath: '/',
476+
},
477+
devtool: 'cheap-source-map',
478+
plugins: [
479+
new HtmlWebpackPlugin({
480+
filename: 'index.html',
481+
chunks: ['js'],
482+
}),
483+
new HtmlWebpackPlugin({
484+
filename: 'home.html',
485+
chunks: ['moduleA'],
486+
}),
487+
new PreloadPlugin()
488+
]
489+
}, function(err, result) {
490+
expect(err).toBeFalsy();
491+
expect(JSON.stringify(result.compilation.errors)).toBe('[]');
492+
const html = result.compilation.assets['index.html'].source();
493+
const homeHtml = result.compilation.assets['home.html'].source();
494+
expect(html).toContain('<link rel="preload" as="script" href="/chunk.');
495+
expect(homeHtml).not.toContain('<link rel="preload" as="script" href="/chunk.');
496+
done();
497+
});
498+
compiler.outputFileSystem = new MemoryFileSystem();
499+
});
500500

501-
// it('exclude by html filename', function(done) {
502-
// const compiler = webpack({
503-
// entry: {
504-
// js: path.join(__dirname, 'fixtures', 'file.js')
505-
// },
506-
// output: {
507-
// path: OUTPUT_DIR,
508-
// filename: '[name].js',
509-
// chunkFilename: 'chunk.[chunkhash].js',
510-
// publicPath: '/',
511-
// },
512-
// devtool: 'cheap-source-map',
513-
// plugins: [
514-
// new HtmlWebpackPlugin({
515-
// filename: 'index.html',
516-
// chunks: ['js'],
517-
// }),
518-
// new HtmlWebpackPlugin({
519-
// filename: 'home.html',
520-
// chunks: ['js'],
521-
// }),
522-
// new PreloadPlugin({
523-
// excludeHtmlNames: ['index.html'],
524-
// })
525-
// ]
526-
// }, function(err, result) {
527-
// expect(err).toBeFalsy();
528-
// expect(JSON.stringify(result.compilation.errors)).toBe('[]');
529-
// const html = result.compilation.assets['index.html'].source();
530-
// const homeHtml = result.compilation.assets['home.html'].source();
531-
// expect(html).not.toContain('<link rel="preload" as="script" href="/chunk.');
532-
// expect(homeHtml).toContain('<link rel="preload" as="script" href="/chunk.');
533-
// done();
534-
// });
535-
// compiler.outputFileSystem = new MemoryFileSystem();
536-
// });
537-
// });
501+
it('exclude by html filename', function(done) {
502+
const compiler = webpack({
503+
entry: {
504+
js: path.join(__dirname, 'fixtures', 'file.js')
505+
},
506+
output: {
507+
path: OUTPUT_DIR,
508+
filename: '[name].js',
509+
chunkFilename: 'chunk.[chunkhash].js',
510+
publicPath: '/',
511+
},
512+
devtool: 'cheap-source-map',
513+
plugins: [
514+
new HtmlWebpackPlugin({
515+
filename: 'index.html',
516+
chunks: ['js'],
517+
}),
518+
new HtmlWebpackPlugin({
519+
filename: 'home.html',
520+
chunks: ['js'],
521+
}),
522+
new PreloadPlugin({
523+
excludeHtmlNames: ['index.html'],
524+
})
525+
]
526+
}, function(err, result) {
527+
expect(err).toBeFalsy();
528+
expect(JSON.stringify(result.compilation.errors)).toBe('[]');
529+
const html = result.compilation.assets['index.html'].source();
530+
const homeHtml = result.compilation.assets['home.html'].source();
531+
expect(html).not.toContain('<link rel="preload" as="script" href="/chunk.');
532+
expect(homeHtml).toContain('<link rel="preload" as="script" href="/chunk.');
533+
done();
534+
});
535+
compiler.outputFileSystem = new MemoryFileSystem();
536+
});
537+
});
538538

539-
// describe('filtering unwanted html', function() {
540-
// it('does not include preload asset into index.html file', function(done) {
541-
// const compiler = webpack({
542-
// entry: {
543-
// js: path.join(__dirname, 'fixtures', 'file.js')
544-
// },
545-
// output: {
546-
// path: OUTPUT_DIR,
547-
// filename: 'bundle.js',
548-
// chunkFilename: 'chunk.[chunkhash].js',
549-
// publicPath: '/',
550-
// },
551-
// devtool: 'cheap-source-map',
552-
// plugins: [
553-
// new HtmlWebpackPlugin(),
554-
// new PreloadPlugin({
555-
// excludeHtmlNames: ['index.html'],
556-
// })
557-
// ]
558-
// }, function(err, result) {
559-
// expect(err).toBeFalsy();
560-
// expect(JSON.stringify(result.compilation.errors)).toBe('[]');
561-
// const html = result.compilation.assets['index.html'].source();
562-
// expect(html).not.toContain('<link rel="preload" as="script" href="/chunk.');
563-
// done();
564-
// });
565-
// compiler.outputFileSystem = new MemoryFileSystem();
566-
// });
539+
describe('filtering unwanted html', function() {
540+
it('does not include preload asset into index.html file', function(done) {
541+
const compiler = webpack({
542+
entry: {
543+
js: path.join(__dirname, 'fixtures', 'file.js')
544+
},
545+
output: {
546+
path: OUTPUT_DIR,
547+
filename: 'bundle.js',
548+
chunkFilename: 'chunk.[chunkhash].js',
549+
publicPath: '/',
550+
},
551+
devtool: 'cheap-source-map',
552+
plugins: [
553+
new HtmlWebpackPlugin(),
554+
new PreloadPlugin({
555+
excludeHtmlNames: ['index.html'],
556+
})
557+
]
558+
}, function(err, result) {
559+
expect(err).toBeFalsy();
560+
expect(JSON.stringify(result.compilation.errors)).toBe('[]');
561+
const html = result.compilation.assets['index.html'].source();
562+
expect(html).not.toContain('<link rel="preload" as="script" href="/chunk.');
563+
done();
564+
});
565+
compiler.outputFileSystem = new MemoryFileSystem();
566+
});
567567
});

0 commit comments

Comments
 (0)